相关文档: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/
文章页面默认调用的是single.php,可以在single.php里判断不同的分类,include不同的模板文件。
get_template_part( slug, name = null,
要将此功能与主题目录中的子文件夹一起使用,只需在 slug 之前添加文件夹名称即可。例如,如果您的主题目录中有一个名为“partials”的文件夹,而该子文件夹中有一个名为“content-page.php”的模板部分,则可以这样使用get_template_part():
<?php get_template_part( 'partials/content', 'page' ); ?>
在主题初始化后(funtions.php已经执行完毕),每次页面加载期间都会调用此钩子。它通常用于执行主题的基本设置、注册和初始化操作。
大部分 WP 在这个阶段被加载,并且用户被认证。WP 继续加载随后的“init”钩子(例如小部件),许多插件出于各种原因在其上实例化自己(例如,它们需要用户、分类等)。
彻底加载完毕, WP、所有插件和主题完全加载并实例化,就会触发此钩子。https://developer.wordpress.org/reference/hooks/wp_loaded/
当管理员页面或脚本正在初始化时触发,当用户访问管理区域时,在任何其他挂钩之前触发。不仅在面向用户的管理屏幕上运行。它也在 admin-ajax.php 和 admin-post.php 上运行。
加载顺序:after_setup_theme --> init --> wp_loaded --> admin_init
当脚本和样式入队时触发。用于将主页面的脚本和样式排入队列。
在WordPress撰写文章页面添加一段提示标语的功能。
利用钩子函数的输出,在指定标签的位置输出相应的内容;wp_head(),方法内就是一个do_action("wp-head")
主题切换后,第一次加载wp时触发的钩子;check_theme_switched()检查是否已经触发这个钩子
在文章保存后立即触发,remove_all_actions(),移除所有钩子,did_action(),钩子的运行次数
在后台加载管理菜单之前触发。
带s的方法一般是钩子函数的包装器,可以直接传入函数作为钩子;
WordPress 默认隐藏了很多功能,我们可以通过 add_theme_support() 函数启用它们,add_theme_support可以在主题的functions.php中调用,如需在hook中调用的必须在after_theme_setup中调用;
get_template_directory,获取活动主题所在的目录路径; get_template_directory_uri()获取活动主题的完整URL; get_stylesheet_uri(),获取活动主题的style.css的完整URL路径; get_theme_file_path(file)、get_theme_file_uri(file) 一样 ,这个函数将返回主题中文件的路径(如果存在)。
获取当前启用的主题相关说明信息(style.css文件内的主题说明),wp_get_themes(),获取系统内所有的主题信息;
只在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/
这些函数需要在循环中工作,因为它们需要全局 post 对象,WordPress 循环会自动设置这个 post 对象。
页面判断函数需要在指定声明周期之后才会有值,例如function加载的时候是没有的,wp_enqueue_scripts钩子内是有值的。
以上所有get都可以单独指定wp_post对象;
相对应的还有wp_insert_attachment、wp_insert_category等钩子;
post表保存的是基本信息,访问附件的URL保存在post_meta表
option可直接存放一个数组;当我们单独访问许多选项数据时,可能导致许多单独的数据库事务,通常,数据库事务是昂贵的操作(就时间和服务器资源而言)而把许多选项作为数组存储和获取时,只会产生一个数据库事务,这是一种比较理想的操作。
13.wp_posts文章类型
Post、Page、Attachment、Revision、Navigation Menu Items
指的是post_meta表里的数据,一般用于保存post表内容有关的元数据。
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(); //重置文章指指针
?>
指定参数查询文章,返回一个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 );
get_query_var用于查询公共变量,例如
<?php
//获取当前页码,默认值返回1
$page = get_query_var( 'page', 1 );
update_user_meta用于更新用户信息
update_user_meta( int $user_id, string $meta_key, mixed $meta_value, mixed $prev_value = '' );
get_tag_link 调用的是get_category_link,get_category_link又调用get_term_link(参数为对象或term_id)
<?php
get_avatar_url( $adminUserInfo->ID )
<?php
wp_is_mobile();
<?php
//访问分类或者标签时返回分类和标签的wp_term对象
$term = get_queried_object();
WP_Rewrite是 WordPress 的类,用于管理重定向规则。官方不建议直接修改该对象的属性,而是通过它的方法进行操作。
API文档:https://codex.wordpress.org/Rewrite_API
TinyMCE:https://www.tiny.cloud/docs-4x/api/tinymce/root_tinymce/
官方文档:https://www.tiny.cloud/docs-4x/api/tinymce/tinymce.editor
<?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 );
}
/* 标题标签 */
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');
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail();
}
//样式加载
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);
<?php
global $wp_filter;
print_r($wp_filter);
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(), $hints);
}
return $hints;
}, 10, 2); //头部加载DNS预获取(dns-prefetch)
}
add_action('after_setup_theme', 'initialize'); //去除博客无用代码
//禁止Gutenberg编辑器
add_filter('use_block_editor_for_post', '__return_false');
remove_action( 'wp_enqueue_scripts', 'wp_common_block_scripts_and_styles' );
//禁止新版小工具
add_filter( 'gutenberg_use_widgets_block_editor', '__return_false' );
add_filter( 'use_widgets_block_editor', '__return_false');
editor.addButton('PureHighlightjsInsert', {
title : PureHighlightjsTrans.title,
icon: 'wp_code',
onclick: function() {
editor.windowManager.open({
title : PureHighlightjsTrans.title,
minWidth : 700,
body : [
{
type : 'listbox',
name : 'lang',
label : PureHighlightjsTrans.language,
values : languageValues
},
{
type : 'textbox',
name : 'code',
label : PureHighlightjsTrans.code,
multiline : true,
minHeight : 200
}
],
onsubmit : function(e){
var code = e.data.code.replace(/\r\n/gmi, '\n'),
tag = 'code';
code = tinymce.html.Entities.encodeAllRaw(code);
var sp = (e.data.addspaces ? ' ' : '');
editor.insertContent(sp + '<pre class="pure-highlightjs"><code class="' + e.data.lang + '">' + code + '\n</code></pre>' + sp + '<p></p>');
}
});
}
});
tinymce.create('tinymce.plugins.info', {
init : function(ed, url) {
ed.addButton('info', {
title : '蓝色背景栏',
image : url+'/images/info.png',
onclick : function() {
ed.selection.setContent('[info]' + ed.selection.getContent() + '[/info]');
}
});
},
createControl : function(n, cm) {
return null;
},
});
tinymce.PluginManager.add('info', tinymce.plugins.info);
if ( version_compare( $GLOBALS['wp_version'], '5.3', '<' ) ) {}
function remove_footer( $text ) {
$text = '';
return $text;
}
/*
* 删除WordPress后台底部版权信息、版本号
* */
add_filter('update_footer', 'remove_footer', 11);
add_filter('admin_footer_text', 'remove_footer', 11);
/*
* 替换Gravatar头像镜像站地址
* */
function replace_https_avatar( $avatar ) {
$Image = get_option( 'document_Gravatar' );
//~ 替换为 https 的域名
$avatar = str_replace( array(
'secure.gravatar.com/avatar',
"www.gravatar.com/avatar",
"0.gravatar.com/avatar",
"1.gravatar.com/avatar",
"2.gravatar.com/avatar"
), $Image, $avatar );
//~ 替换为 https 协议
$avatar = str_replace( "http://", "https://", $avatar );
return $avatar;
}
/*
* 替换Gravatar镜像站地址
* */
add_filter('get_avatar', 'replace_https_avatar');
add_filter('get_avatar_url', 'replace_https_avatar');
/*
* 修改文字摘要字数
* */
function article_excerpt_lengths( $length ) {
return 300;
}
/*修改文章摘要的数量*/
add_filter( 'excerpt_length', 'article_excerpt_lengths', 999 );
/*
* 添加后台可选的页面模板
* */
function add_page_template( $page_templates ) {
$page_templates['template/page/posts.php']='文章聚合';
return $page_templates;
}
add_filter( 'theme_page_templates', 'add_page_template' );
add_filter( 'theme_post_templates', 'add_page_template' );
/*
* 修改页面的固定链接
* */
add_action( 'init', 'custom_page_rules' );
function custom_page_rules() {
global $wp_rewrite;
$wp_rewrite->page_structure = $wp_rewrite->root . '%pagename%.html';
}
官方文档:https://developer.wordpress.org/reference/functions/get_the_posts_pagination/
<?php
$pagination = get_the_posts_pagination( array(
'prev_next' => false,
'current' => max( 1, get_query_var( 'paged' ) ), //当前页码
'type' => 'list'
) );
/*去除多余的元素*/
$pagination=preg_replace( '/^[\s\S]*?(\<ul[\s\S]*\>[\s\S]*\<\/ul\>)[\s\S]*?$/', "$1", $pagination );
<?php if(get_comment_pages_count()>1){ ?>
<div class="pagination">
<?php paginate_comments_links( ['prev_next' => false]); ?>
</div>
<?php } ?>
<?php
//是否登录
$isLogin = is_user_logged_in();
//用户信息
$Info = wp_get_current_user();
<?php
/*
* 主题功能
* */
add_theme_support( 'post-thumbnails'); //开启主题缩略图
add_theme_support( 'menus'); //开启主题菜单功能
add_theme_support( 'widgets'); //开启自定义侧边栏
add_theme_support( 'widgets-block-editor'); //开启自定义侧边栏
remove_filter('the_content', 'wptexturize'); //关闭文章转义
<?php
if ( have_posts() ) :
while ( have_posts() ) : the_post();
// 显示文章内容
endwhile;
endif;
?>
<?php
$defaults = array(
'menu' => '',
'container' => 'div',
'container_class' => '',
'container_id' => '',
'container_aria_label' => '',
'menu_class' => 'menu',
'menu_id' => '',
'echo' => true,
'fallback_cb' => 'wp_page_menu',
'before' => '',
'after' => '',
'link_before' => '',
'link_after' => '',
'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
'item_spacing' => 'preserve',
'depth' => 0,
'walker' => '',
'theme_location' => '',
);
<?php
// add top level menu
add_menu_page(page_title, menu_title, capability, handle, [function], [icon_url]);
// add sub-menu pages
add_submenu_page(parent, page_title, menu_title, capability, file/handle, [function]);
// add Options sub-menu
add_options_page(page_title, menu_title, capability, handle, [function]);
// add Management sub-menu
add_management_page(page_title, menu_title, capability, handle, [function]);
// add Pages sub-menu
add_pages_page( page_title, menu_title, capability, handle, [function]);
// add Posts sub-menu
add_posts_page( page_title, menu_title, capability, handle, [function]);
// add Appearances sub-menu
add_theme_page( page_title, menu_title, capability, handle, [function]);
上面这些函数都有一个必须的参数capability。这意味着登录到后台的用户需要有相应的职能才能够看到这里添加的菜单选项。 如果你的主题或者插件有一个选项页,合理的 控制对该页的访问时非常重要的。例如,如果有一个主题选项页,你需要使用edit_themes这个职能(capability),如果是一个插件选项页,就需要使用edit_plugins职能。另一种方法是为插件和主题选项也使用manage_options这个职能.
register_setting注册的能够通过表单自动更新、add_option只是普通的选项;
用于输出表单带有表单提交时用于验证的input隐藏元素;
用于按照wordpress内置的格式输出表单的分节
用于按照指定的回调输出表单元素
评论相关函数必须运行在comments.php内,其它文件内调用无返回结果;
相关文章:http://www.sins7.cn/wordpress-wpdb-usage/
$wpdb是一个全局变量,包含多个关于数据库查询函数:
<?php
$wpdb -> get_results('query');
$wpdb->query('query');
$wpdb->get_var('query',column_offset,row_offset);
$wpdb->get_row('query', output_type, row_offset);
$wpdb->get_col('query',column_offset);
$wpdb->get_results('query', output_type);
$wpdb->insert( $table, $data, $format );
$wpdb->update( $table, $data, $where, $format = null, $where_format = null );
$wpdb->prepare( 'query' [, value_parameter, value_parameter ... ] );
$wpdb->show_errors();
$wpdb->hide_errors();
$wpdb->print_error();
$wpdb->get_col_info('type', offset);
$wpdb->flush();
相较于选项,瞬态的区别是可以设置数据到期时间。
内置的时间单位常量:
MINUTE_IN_SECONDS = 60 (seconds)
HOUR_IN_SECONDS = 60 * MINUTE_IN_SECONDS
DAY_IN_SECONDS = 24 * HOUR_IN_SECONDS
WEEK_IN_SECONDS = 7 * DAY_IN_SECONDS
MONTH_IN_SECONDS = 30 * DAY_IN_SECONDS
YEAR_IN_SECONDS = 365 * DAY_IN_SECONDS
小部件本质就是一段可直接调用的代码块(分为边栏和挂件)。官方文档:https://codex.wordpress.org/zh-cn:%E5%B0%8F%E5%B7%A5%E5%85%B7%E6%8E%A5%E5%8F%A3、https://automattic.com/code/widgets/api/
register_widget用于注册一个Wordpress默认的挂件;
提示
经过测试,register_widget注册的部件类中最终也是调用wp_register_sidebar_widget( WP_Widget类的567行调用了这个函数),注册的小部件。
the_widget调用后,将输出指定的挂件
register_sidebars用于注册一个侧边栏,可以指定一个索引进行注册
dynamic_sidebar用于输出注册好的侧边栏,通过索引指定输出某一个侧边栏
wp_register_sidebar_widget用于注册一个边栏挂件。
判断指定的边栏是否有被激活的小工具;
官方文档:https://wordpress.org/support/article/roles-and-capabilities/
WordPress 使用角色的概念来让博客的所有者对用户进行权限控制。博客所有者可以控制用户写文章、创建页面、管理插件、管理主题,以及管理其他用户的权限。博客所有者可以通过该工具分配用户权限。
判断当前登录的用户是否具有指定的权限;检查当前用户是否有足够的职能去执行某些行为(action)
<?php
//加后一个参数时,判断用户对指定文章是否具有某种权限
current_user_can( 'edit_post', [$post_id ]);
<?php
if ( author_can( $post, $capability ) ) {
// do something if the author of the post $post has $capability
}
<?php
add_role( $role_name, $display_name, $capabilities );
//例子
add_role( 'document_uploader', 'Document Uploader', array( 'organize_document' ) );
添加了一个新的角色叫做“document_uploader”,显示名称“Document Uploader"及一个职能的集合(在这个例子中,职能名称organize_document)。 可以使用current_user_can()检查当前用户是否被允许执行相应操作。
<?php
remove_role([role_name] )://移除指定的角色
<?php
// get the "author" role object
$role = get_role( 'author' );
// add "organize_gallery" to this role object
$role->add_cap( 'organize_document');
获取指定状态类型文章的总数量;
$count_posts = wp_count_posts();
if ( $count_posts ) {
$draft_posts = $count_posts->draft;
}
wp_count_terms用于获取标签或分类的总数;
wp_count_terms('category'); //分类总数
wp_count_terms('post_tag'); //标签总数
$comment = count(get_comments());//评论总数
获取所有支持的定时任务时间间隔,看了一下源码,调用的是查看cron_schedules filter返回的数组;增加一个自定义的时间间隔:
<?php
add_filter( 'cron_schedules',function($schedules){
$schedules['nicen'] = array(
'interval' => 3600,
'display' => '定时任务' //对于这个时间间隔的描述
);
return $schedules;
});
wp_schedule_event用于添加一个定时任务;
wp_schedule_event("初次触发时间","间隔触发时间","触发的action hook");
wp_clear_scheduled_hook用于清理定时任务;
wp_unschedule_event用于删除一个间隔时间;
提示
添加计划任务之后,这个任务就独立了,每次只会去触发action,所有在插件被关闭后,没有这个action了,任务还会继续,所有在插件关闭时需要同步取消任务,同理表单的开关也需要同步任务的开启和关闭。
参考文档:https://developer.wordpress.org/plugins/http-api/
<?php
$request = wp_safe_remote_get( 'http://www.example.com/file.json' );
if ( is_wp_error( $request ) ) {
return false;
}
$body = wp_remote_retrieve_body( $request );
$json = json_decode( $body );
wp_remote_get用于进行Get请求,示例代码如下:
<?php
wp_remote_get($url,$args);
$url – 从中检索数据的资源。这必须是标准的 HTTP 格式
$args – 可选 – 您可以在此处传递一组参数来更改行为和标头,例如 cookie、跟随重定向等。
返回一个响应对象
wp_remote_post用于发起POST请求示例代码如下:
<?php
$args = array(
'body' => $body,
'timeout' => '5',
'headers'=>[],
'cookies'=>[],
'sslverify' => false,
'redirection' => '5',
'httpversion' => '1.0',
'blocking' => true,
'headers' => array(),
'cookies' => array(),
);
$response = wp_remote_post( 'http://your-contact-form.com', $args );
wp_remote_request用于进行自定义请求;
提示
WP_Http_Curl对于HTTP请求的封装
首先通过wp_enqueue_media加载前端所需的调用媒体中心的代码
wp.media({
title: '选择或上传图片', // 窗口标题
button: {
text: '选择', // 选择按钮文字
},
editable: true,
allowLocalEdits: true,
displaySettings: true,
displayUserSettings: true
multiple: false // 是否允许多选
});
// 获取被选数据
media.state().get('selection').toJSON()
同样的还可以通过加载wp_enqueue_editor调用编辑器 。
wp_enqueue_media用于加载wp.media所需的JS文件
相关文档:https://developer.wordpress.org/reference/functions/wp_enqueue_media/
wp.media用于前端创建一个wp媒体中心窗体。可传入参数如下:
wordpress自动保存也会触发这个钩子,可能导致异常输出;save_post钩子内进行wp_update_post会导致重复触发钩子
$template=get_page_template_slug( get_queried_object_id() );
if (strpos($template,"template/page/posts.php") !== false) { }
<?php
//获取访问的标签或分类对象
get_queried_object()->term_id;
//获取分类、标签的链接
get_term_link($tag->term_id);
<?php
get_the_author_meta( 'display_name', $post->post_author )