WordPress主题开发,从入门到精通。
相关文档:https://www.wpzhiku.com/document/wordpress-plugin-basics/
wp_query查询内容:https://developer.wordpress.org/reference/classes/wp_query
wp_comments-query评论查询:https://developer.wordpress.org/reference/classes/wp_comment_query
应用程序接口:https://make.wordpress.org/core/handbook/best-practices/core-apis/
官方开发文档:https://developer.wordpress.org/themes/basics/theme-functions/
主题相关
1.如何为不同分类的页面显示不同的模板。
文章页面默认调用的是single.php,可以在single.php里判断不同的分类,include不同的模板文件。
2.get_template_part
get_template_part( slug,name = null,
要将此功能与主题目录中的子文件夹一起使用,只需在 slug 之前添加文件夹名称即可。例如,如果您的主题目录中有一个名为“partials”的文件夹,而该子文件夹中有一个名为“content-page.php”的模板部分,则可以这样使用get_template_part():
<?php get_template_part( 'partials/content', 'page' ); ?>
Hook列表
1.after_setup_theme
在主题初始化后(funtions.php已经执行完毕),每次页面加载期间都会调用此钩子。它通常用于执行主题的基本设置、注册和初始化操作。
2.init
大部分 WP 在这个阶段被加载,并且用户被认证。WP 继续加载随后的“init”钩子(例如小部件),许多插件出于各种原因在其上实例化自己(例如,它们需要用户、分类等)。
3.wp_loaded
彻底加载完毕, WP、所有插件和主题完全加载并实例化,就会触发此钩子。https://developer.wordpress.org/reference/hooks/wp_loaded/
4.admin_init
当管理员页面或脚本正在初始化时触发,当用户访问管理区域时,在任何其他挂钩之前触发。不仅在面向用户的管理屏幕上运行。它也在 admin-ajax.php 和 admin-post.php 上运行。
加载顺序:after_setup_theme --> init --> wp_loaded --> admin_init
5.wp_enqueue_scripts、admin_enqueue_scripts、login_enqueue_scripts
当脚本和样式入队时触发。用于将主页面的脚本和样式排入队列。
6.edit_form_after_title
在WordPress撰写文章页面添加一段提示标语的功能。
7.wp_head、wp_body_open(放在Body之后)、wp_footer
利用钩子函数的输出,在指定标签的位置输出相应的内容;wp_head(),方法内就是一个do_action("wp-head")
8.after_switch_theme
主题切换后,第一次加载wp时触发的钩子;check_theme_switched()检查是否已经触发这个钩子
9.save_post、publish_post、edit_post
在文章保存后立即触发,remove_all_actions(),移除所有钩子,did_action(),钩子的运行次数
10.admin_menu
在后台加载管理菜单之前触发。
主题可用函数
带s的方法一般是钩子函数的包装器,可以直接传入函数作为钩子;
1.add_theme_support
WordPress 默认隐藏了很多功能,我们可以通过 add_theme_support() 函数启用它们,add_theme_support可以在主题的functions.php中调用,如需在hook中调用的必须在after_theme_setup中调用;
- add_theme_support( 'post-thumbnails' ,[array( 'post' )]); 启用指定类型文章的缩略图功能,不指定第二个参数时默认为全部文章启用缩略图功能;
- post-formats:文章形式。
- html5:HTML5支持。
- custom-logo:自定义网站Logo图标。
- custom-header-uploads:顶部图像上传。
- custom-header:自定义网站顶部内容。
- custom-background:自定义网站背景内容。
- title-tag:自动生成页面标题信息,需调用。
- customize-selective-refresh-widgets:小部件选择性更新。
- starter-content:内容初始化。
- responsive-embeds:自适应嵌入内容。
- align-wide:配置块编辑器宽对齐。
- dark-editor-style:配置暗风格块编辑器。
- disable-custom-colors:禁用快编辑器自定义颜色。
- disable-custom-font-sizes:禁用快编辑器自定义字体大小。
- editor-color-pallete:配置块编辑器调色板。
- editor-font-sizes:配置块编辑器字体大小。
- editor-styles:配置块编辑器样式。
- wp-block-styles:启用默认块编辑器样式。
2.目录、路径的相关函数
get_template_directory,获取活动主题所在的目录路径; get_template_directory_uri()获取活动主题的完整URL; get_stylesheet_uri(),获取活动主题的style.css的完整URL路径; get_theme_file_path(file)、getthemefileuri(file) 一样 ,这个函数将返回主题中文件的路径(如果存在)。
3.wp_get_theme()
获取当前启用的主题相关说明信息(style.css文件内的主题说明),wp_get_themes(),获取系统内所有的主题信息;
4.样式、脚本加载
只在wp_enqueue_scripts(主页面)、admin_enqueue_scripts(后台)、login_enqueue_scripts(登录页面)钩子内可用;
<?php
/*注册样式*/
wp_enqueue_style( string $handle(样式名), string $src = ''(样式文件的目录路径), string[] $deps = array()(依赖的文件), string|bool|null $ver = false(动态版本号), string $media = 'all' (支持的媒体类型));按照注册的队列加载css文件。
/*注册脚本*/
wp_enqueue_script( string $handle, string $src = '', string[] $deps = array(), string|bool|null $ver = false, bool $in_footer = false )
/*内联样式*/
wp_add_inline_style()
/*内联脚本*/
wp_add_inline_script()
参考:https://developer.wordpress.org/reference/functions/wp_add_inline_script/
5.删除已注册的样式表、脚本
- wp_deregister_style(style)
- wp_dequeue_script(script)
6.文章相关函数
这些函数需要在循环中工作,因为它们需要全局 post 对象,WordPress 循环会自动设置这个 post 对象。
- in_the_loop(),是否处于文章循环;
- get_the_ID,获取文章ID;
- the_title,输出文章标题
- the_title_attribute(['before'=>"前",'after'=>"后",'post'=>1]); 指定相关属性输出标题
- get_the_title,获取文章标题
- the_guid,文章的GUID
- get_the_guid,获取文章的GUID
- the_content,文章内容
- get_the_content,获取文章内容
- the_excerpt,文章摘要
- get_the_excerpt,获取文章摘要
- has_excerpt,是否有文章摘要
- post_password_required,是否需要密码
- next_post(),下一篇文章
- previous_post(),前一篇文章
7.缩略图
- has_post_thumbnail,是否拥有缩略图
- get_post_thumbnail_id,获取缩略图ID
- the_post_thumbnail,输出缩略图(img元素)
- update_post_thumbnail_cache
- get_the_post_thumbnail,缩略图(img元素)
- get_the_post_thumbnail_url,缩略图URL
- the_post_thumbnail_url,输出缩略图URL
- get_the_post_thumbnail_caption,缩略图文件标题
- the_post_thumbnail_caption,缩略图文件标题
8.站点信息
页面判断函数需要在指定声明周期之后才会有值,例如function加载的时候是没有的,wp_enqueue_scripts钩子内是有值的。
- bloginfo([key])、getbloginfo([key]);
- is_user_logged_in(),是否已经登录
- is_home(),是否处于首页;
- is_admin(),是否处于后台;
- is_single(),传递空、文章ID、文章标题,判断是否在这个文章页面;
- is_sticky(),传递空、文章ID、文章标题,判断是否是置顶的文章
- is_page(),传递空、文章ID、文章标题,判断是否在这个页面;
- paged=wp_query->get( 'page' ); 获取分页所处的页数;
- is_page_template(‘about.php’),是否处于某个页面模板;
- is_category(),传递空、分类ID、分类标题,判断是否在某个分类页面;
- is_archive()、is_search()、is_404()
以上所有get都可以单独指定wp_post对象;
9.列表
- 传递一个配置数组获取页面列表:wp_list_pages()
- 传递一个配置数组获取目录列表:wp_list_categories()
- 传递一个配置数组获取评论列表:wp_list_categories()
10.posts表相关操作方法
- wp_update_post(),更新文章
- wp_insert_post(),插入文章
- wp_is_post_revision(),
- wp_trash_post(),删除文章到回收站
- wp_delete_post(),用久删除文章
- wp_publish_post(),发布文章,改为发布状态
相对应的还有wp_insert_attachment、wp_insert_category等钩子;
11.网络
- wp_send_json_success
- wp_send_json_error
- wp_send_json
- 响应json数据,然后die
11.附件
- wp_get_attachment_thumb_file
- wp_get_attachment_thumb_url
- wp_get_attachment_link
- wp_get_attachment_url
- wp_get_attachment_image_src
post表保存的是基本信息,访问附件的URL保存在post_meta表
12.wp_options表
option可直接存放一个数组;当我们单独访问许多选项数据时,可能导致许多单独的数据库事务,通常,数据库事务是昂贵的操作(就时间和服务器资源而言)而把许多选项作为数组存储和获取时,只会产生一个数据库事务,这是一种比较理想的操作。
- update_option 更新WP设置选项
- delete_option,从 WordPress 选项数据表中安全删除“选项/值”对的方法。
- add_option 添加设置选项
- get_option 获取选项设置值
- add_site_option、get_site_option...
13.wp_posts文章类型
Post、Page、Attachment、Revision、Navigation Menu Items
14.转义
- esc_html() – 在显示 HTML 时,使用此函数。
- esc_url() – 在输出 URL 时,使用此函数,包括在src和href属性中的 URL。
- esc_js() – 对内联 JavaScript 使用此函数。
- esc_attr() – 把数据设置为 HTML 元素属性时使用此能力。
- 相对于使用 echo 输出数据,我们应该更多的使用 WordPress 的本地化能力,如 _e() 或 __()
15.简码
- add_shortcode()
- remove_shortcode()
- shortcode_exists()
- 简码解析器只对简码的内容进行一次传递。
- 可以在处理函数的最终返回值上调用 do_shortcode() ,使 $content 中包含的简码也可以被解析。简码可以接受一些参数,我们称之为简码的属性
16.元数据
指的是post_meta表里的数据,一般用于保存post表内容有关的元数据。
- get_post_meta(postID,count_key, true); //查询元字段数据
- delete_post_meta(postID,count_key);//删除原字段数据
- add_post_meta(postID,count_key, '0');//新增元字段数据
- update_post_meta(postID,count_key, '0');//更新元数据
17.query_posts函数
query函数用于查询文章,将会修改wordpress主查询的指向:
wp_reset_query用于重置主循环的指针。
<?php
query_posts("showposts=10");
while (have_posts()) {
the_post();//移动文字指定到此处
get_the_permalink();
get_the_title();
get_the_title();
}
wp_reset_query(); //重置文章指指针
?>
18.get_posts函数
指定参数查询文章,返回一个wp_Query对象数组,代表所有符合条件的文章:
支持的参数:https://developer.wordpress.org/reference/classes/wp_query/parse_query/
<?php
/* 检索10条最新的指定类型的文章 */
$args = array(
'numberposts' => 10,
'post_type' => 'book'
);
$latest_books = get_posts( $args );
19.get_query_var函数
get_query_var用于查询公共变量,例如
<?php
//获取当前页码,默认值返回1
$page = get_query_var( 'page', 1 );
20.update_user_meta
update_user_meta用于更新用户信息
update_user_meta( int $user_id, string $meta_key, mixed $meta_value, mixed $prev_value = '' );
- userid,代表需要更新数据的用户ID
- meta_key,代表需要更新的key
- meta_value,更新之后的值
- prev_value,更新前的值,用户区分具有相对用户ID和key的数据,不指定时将更新所有数据
21.站点URL
- plugins_url() — 插件目录的 URL (例如:https://nicen.cn/wp-content/plugins)
- includes_url() — includes 目录的 URL (例如:https://nicen.cn/wp-includes)
- content_url() — content 目录的 URL (例如:https://nicen.cn/wp-content)
- admin_url() — admin 目录的 URL (例如:https://nicen.cn/wp-admin/)
- site_url() — 当前网站的 URL (例如:https://nicen.cn)
- home_url() — 当前网站首页的 URL (例如:https://nicen.cn)
22.获取标签、目录链接
get_tag_link 调用的是get_category_link,get_category_link又调用get_term_link(参数为对象或term_id)
23.获取用户的头像
<?php
get_avatar_url( $adminUserInfo->ID )
24.判断是不是移动设备
<?php
wp_is_mobile();
25.获取查询对象
<?php
//访问分类或者标签时返回分类和标签的wp_term对象
$term = get_queried_object();
WP_Rewrite对象
WP_Rewrite是 WordPress 的类,用于管理重定向规则。官方不建议直接修改该对象的属性,而是通过它的方法进行操作。
API文档:https://codex.wordpress.org/Rewrite_API
自定义编辑器
TinyMCE:https://www.tiny.cloud/docs-4x/api/tinymce/root_tinymce/
1.TinyMCE4.x版本相关方法
- create(s:String, p:Object, root:Object),创建一个类、子类或静态单例,https://www.tiny.cloud/docs-4x/api/tinymce/root_tinymce/#create s (String) - 类名、继承和前缀。 p (Object) - 添加到类的方法集合。 root (Object) - 可选的根对象默认为全局窗口对象。
- tinymce.PluginManager,获取tintmce.Plugin类,用于管理插件;https://www.tiny.cloud/docs-4x/api/tinymce/tinymce.plugin/
2.添加插件的两种方式;
- 先create一个类,再通过PluginManager.add添加插件。
- 直接PluginManager.add一个对象,添加插件。
3.tinymce.Editor,编辑器核心API
官方文档:https://www.tiny.cloud/docs-4x/api/tinymce/tinymce.editor
- selection,代表编辑器内被选中的内容的对象;https://www.tiny.cloud/docs-4x/api/tinymce.dom/tinymce.dom.selection/
- getContent(),获取被选中对象的内容;
- setContent(),设置被选中对象的内容
- windowManager,可打开一个新的窗口或者对话框;https://www.tiny.cloud/docs-4x/api/tinymce/tinymce.windowmanager/
4.wp注册tinymce插件、样式、按钮
<?php
add_action( 'admin_init', 'my_tinymce_button' );
/*后台初始化*/
function my_tinymce_button() {
if ( current_user_can( 'edit_posts' ) && current_user_can( 'edit_pages' ) ) {
/* 编辑器新增上方按钮的勾子*/
add_filter( 'mce_buttons', 'my_register_tinymce_button' );
/* 编辑器新增插件的勾子*/
add_filter( 'mce_external_plugins', 'my_add_tinymce_button' );
}
}
function my_register_tinymce_button( $buttons ) {
/*每一个按钮代表一个插件的JS类(插件)*/
/*JS类里指定功能和图标*/
$buttons[] = 'success';
$buttons[] = 'alert';
$buttons[] = 'error';
$buttons[] = 'h1';
$buttons[] = 'h2';
$buttons[] = 'h3';
$buttons[] = 'code';
$buttons[] = 'lightbox';
$buttons[] = 'mark';
return $buttons;
}
function my_add_tinymce_button( $plugin_array ) {
$plugin_array['my_button_script'] = plugins_url( '/mybuttons.js', __FILE__ );/*指定要加载的插件*/
return $plugin_array;
}
/* 编辑器新增样式的勾子*/
add_filter( 'mce_css', 'pure_highlightjs_mce_css' ); /* 样式新增的勾子*/
function pure_highlightjs_mce_css( $mce_css ) {
if ( ! is_array( $mce_css ) ) {
$mce_css = explode( ',', $mce_css );
}
$mce_css[] = PURE_HIGHLIGHTJS_PLUGIN_URL . 'tinymce/tinymce.css';
return implode( ',', $mce_css );
}
5.新增短标签
/* 标题标签 */
function nrtitle($atts, $content = null, $code = "")
{
static $times=1;
$return = '<h2 id="list'.$times.'">';
$return .= $content;
$return .= '</h2>';
$times++;
return $return;
}
add_shortcode('title', 'nrtitle');
技巧
1.文章是否有缩略图
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail();
}
2.注册加载样式文件,并根据修改时间自动修正版本号
//样式加载
wp_enqueue_style('main-styles', get_template_directory_uri() . '/css/style.css', array(), filemtime(get_template_directory() . '/css/style.css'), false);
//脚本加载
wp_enqueue_script('prism', $url . '/common/prism/prism.js', array(), filemtime($root . '/common/prism/prism.js'), false);
3.获取wordpress注册的所有action和filter钩子
<?php
global $wp_filter;
print_r($wp_filter);
4.去除头部无用代码
function initialize(){
/*
* 去除头部多余无用的东西
* */
remove_action('wp_enqueue_scripts', 'wp_enqueue_global_styles'); //内联样式
remove_action('wp_footer', 'wp_enqueue_global_styles', 1);//dobate图标
remove_action('wp_head', 'wp_generator'); //移除WordPress版本
remove_action('wp_head', 'rsd_link'); //移除离线编辑器开放接口
remove_action('wp_head', 'wlwmanifest_link'); //移除离线编辑器开放接口
remove_action('wp_head', 'index_rel_link'); //去除本页唯一链接信息
remove_action('wp_head', 'parent_post_rel_link', 10, 0); //清除前后文信息
remove_action('wp_head', 'start_post_rel_link', 10, 0); //清除前后文信息
remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0); //清除前后文信息
remove_action('wp_head', 'feed_links', 2); //移除feed
remove_action('wp_head', 'feed_links_extra', 3); //移除feed
remove_action('wp_head', 'rest_output_link_wp_head', 10); //移除wp-json链
remove_action('wp_head', 'print_emoji_detection_script', 7); //头部的JS代码
//remove_action( 'wp_head', 'wp_print_styles', 8 ); //emoji载入css
remove_action('wp_head', 'rel_canonical'); //rel=canonical
remove_action('wp_head', 'wp_shortlink_wp_head', 10, 0); //rel=shortlink
/*移除emjoy*/
remove_action('wp_head', 'print_emoji_detection_script', 7);
remove_action('admin_print_scripts', 'print_emoji_detection_script');
remove_action('wp_print_styles', 'print_emoji_styles');
remove_action('admin_print_styles', 'print_emoji_styles');
remove_filter('the_content_feed', 'wp_staticize_emoji');
remove_filter('comment_text_rss', 'wp_staticize_emoji');
remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
/*移除文章内的embed内容*/
remove_action('wp_head', 'wp_oembed_add_discovery_links');
remove_action('wp_head', 'wp_oembed_add_host_js');
add_filter('wp_resource_hints', //移除WordPress头部加载DNS预获取(dns-prefetch)
function ($hints, $relation_type) {
if ('dns-prefetch' === $relation_type) {
return array_diff(wp_dependencies_unique_hosts()