WordPress 过滤钩子 (Filters)
过滤钩子允许在数据发送到数据库或浏览器之前修改数据。
📚 过滤钩子 vs 动作钩子
mermaid
graph LR
A[过滤钩子] -->|修改| B[数据]
C[动作钩子] -->|执行| D[功能]
A -->|接收| E[输入数据]
E -->|处理| F[修改数据]
F -->|返回| G[输出数据]1
2
3
4
5
6
7
2
3
4
5
6
7
🎯 常用过滤钩子
内容过滤
| 钩子 | 说明 |
|---|---|
the_content | 文章内容 |
the_content_feed | RSS 内容 |
the_excerpt | 文章摘要 |
the_title | 文章标题 |
the_permalink | 文章链接 |
头部过滤
| 钩子 | 说明 |
|---|---|
wp_title | 页面标题 |
document_title_parts | 文档标题部分 |
pre_get_document_title | 预获取文档标题 |
元数据过滤
| 钩子 | 说明 |
|---|---|
meta_type | 元数据类型 |
get_{type}_{meta} | 获取特定类型元数据 |
add_{type}_{meta} | 添加元数据 |
update_{type}_{meta} | 更新元数据 |
delete_{type}_{meta} | 删除元数据 |
查询过滤
| 钩子 | 说明 |
|---|---|
pre_get_posts | 修改主查询 |
posts_where | 修改 WHERE 子句 |
posts_join | 修改 JOIN 子句 |
posts_groupby | 修改 GROUP BY 子句 |
posts_orderby | 修改 ORDER BY 子句 |
posts_limits | 修改 LIMIT 子句 |
💡 常用过滤钩子示例
修改文章内容
php
<?php
// 在内容前后添加内容
add_filter('the_content', 'my_add_content_wrapper');
function my_add_content_wrapper($content) {
if (is_single()) {
$before = '<div class="article-wrapper">';
$after = '</div>';
return $before . $content . $after;
}
return $content;
}
// 在内容末尾添加分享按钮
add_filter('the_content', 'my_add_share_buttons');
function my_add_share_buttons($content) {
if (is_single() && in_the_loop() && is_main_query()) {
$share_buttons = '<div class="share-buttons">';
$share_buttons .= '<h4>分享这篇文章</h4>';
$share_buttons .= '<a href="' . get_permalink() . '">分享到...</a>';
$share_buttons .= '</div>';
return $content . $share_buttons;
}
return $content;
}
// 替换内容中的文本
add_filter('the_content', 'my_replace_text');
function my_replace_text($content) {
$search = 'WordPress';
$replace = '<strong>WordPress</strong>';
return str_replace($search, $replace, $content);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
修改文章标题
php
<?php
// 修改标题
add_filter('the_title', 'my_modify_title', 10, 2);
function my_modify_title($title, $post_id) {
if (is_admin()) {
return $title;
}
// 为特定分类添加前缀
if (has_category('news', $post_id)) {
$title = '📰 ' . $title;
}
// 为置顶文章添加标识
if (is_sticky($post_id)) {
$title = '⭐ ' . $title;
}
return $title;
}
// 修改 RSS 文章标题
add_filter('the_title_rss', 'my_rss_title');
function my_rss_title($title) {
return '[Blog] ' . $title;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
修改查询
php
<?php
// 修改主查询
add_action('pre_get_posts', 'my_modify_main_query');
function my_modify_main_query($query) {
// 仅修改主查询
if (!is_admin() && $query->is_main_query()) {
// 首页排除特定分类
if (is_home()) {
$query->set('cat', '-5,-10'); // 排除分类 ID 5 和 10
}
// 搜索结果按日期排序
if (is_search()) {
$query->set('orderby', 'date');
$query->set('order', 'DESC');
}
// 归档页每页显示更多文章
if (is_archive()) {
$query->set('posts_per_page', 20);
}
}
}
// 自定义文章类型归档页
add_action('pre_get_posts', 'my_cpt_archive');
function my_cpt_archive($query) {
if (!is_admin() && $query->is_post_type_archive('portfolio')) {
$query->set('posts_per_page', 12);
$query->set('orderby', 'menu_order');
$query->set('order', 'ASC');
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
修改摘要
php
<?php
// 修改摘要长度
add_filter('excerpt_length', 'my_excerpt_length');
function my_excerpt_length($length) {
if (is_category('featured')) {
return 50; // 特色分类显示50字
}
return 25; // 默认25字
}
// 修改摘要省略号
add_filter('excerpt_more', 'my_excerpt_more');
function my_excerpt_more($more) {
return '... <a href="' . get_permalink() . '">阅读更多</a>';
}
// 自定义摘要
add_filter('get_the_excerpt', 'my_custom_excerpt');
function my_custom_excerpt($excerpt) {
if (has_excerpt()) {
return '<p class="custom-excerpt">' . $post->post_excerpt . '</p>';
}
return $excerpt;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
修改导航菜单
php
<?php
// 添加菜单项
add_filter('wp_nav_menu_items', 'my_add_menu_items', 10, 2);
function my_add_menu_items($items, $args) {
// 仅在主菜单位置
if ($args->theme_location === 'primary') {
// 添加搜索框
$search = '<li class="menu-item menu-item-search">';
$search .= '<form role="search" method="get" action="' . home_url('/') . '">';
$search .= '<input type="search" name="s" placeholder="搜索...">';
$search .= '</form>';
$search .= '</li>';
$items .= $search;
}
return $items;
}
// 修改菜单 CSS 类
add_filter('nav_menu_css_class', 'my_menu_classes', 10, 4);
function my_menu_classes($classes, $item, $args, $depth) {
// 添加当前页面类
if (in_array('current-menu-item', $classes)) {
$classes[] = 'active';
}
// 为特定菜单添加类
if ($item->title === '关于我们') {
$classes[] = 'about-link';
}
return $classes;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
修改评论
php
<?php
// 评论表单字段
add_filter('comment_form_default_fields', 'my_comment_fields');
function my_comment_fields($fields) {
// 修改网站字段
$fields['url'] = '<p class="comment-form-url">
<label for="url">网站</label>
<input type="url" id="url" name="url" placeholder="https://">
</p>';
return $fields;
}
// 评论内容过滤
add_filter('comment_text', 'my_comment_text');
function my_comment_text($comment_text) {
// 替换敏感词
$bad_words = array('bad', 'words');
$comment_text = str_ireplace($bad_words, '***', $comment_text);
return $comment_text;
}
// 评论作者名称
add_filter('get_comment_author', 'my_comment_author');
function my_comment_author($author) {
if (user_can($comment->user_id, 'administrator')) {
return $author . ' 👑';
}
return $author;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
修改用户信息
php
<?php
// 修改用户显示名称
add_filter('the_author', 'my_author_display_name');
function my_author_display_name($name) {
global $post;
$author_nickname = get_the_author_meta('nickname', $post->post_author);
return $author_nickname ? $author_nickname : $name;
}
// 修改用户邮箱
add_filter('pre_user_email', 'my_pre_user_email');
function my_pre_user_email($email) {
// 拒绝临时邮箱
$disposable_domains = array('tempmail.com', 'throwaway.com');
$domain = substr(strrchr($email, '@'), 1);
if (in_array($domain, $disposable_domains)) {
$email = '';
}
return $email;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
修改小工具
php
<?php
// 动态侧边栏类
add_filter('dynamic_sidebar_params', 'my_sidebar_params');
function my_sidebar_params($params) {
global $wp_registered_widgets;
$widget_id = $params[0]['widget_id'];
$widget_obj = $wp_registered_widgets[$widget_id];
// 为特定小工具添加包装类
if ($widget_id === 'recent-posts-2') {
$params[0]['before_widget'] = str_replace(
'class="',
'class="recent-posts-widget ',
$params[0]['before_widget']
);
}
return $params;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
🎯 过滤钩子优先级
php
<?php
// 默认优先级 10
add_filter('the_content', 'my_function_1');
add_filter('the_content', 'my_function_2');
// 较高优先级(较早执行)
add_filter('the_content', 'my_function_3', 1);
add_filter('the_content', 'my_function_4', 5);
// 较低优先级(较晚执行)
add_filter('the_content', 'my_function_5', 20);
add_filter('the_content', 'my_function_6', 100);
// 带参数
add_filter('the_title', 'my_title_filter', 10, 2);
function my_title_filter($title, $post_id) {
return $title;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
🗑️ 移除过滤钩子
php
<?php
// 移除默认过滤器
remove_filter('the_content', 'wptexturize');
remove_filter('the_content', 'wpautop');
// 移除带特定优先级的过滤器
remove_filter('the_content', 'some_function', 10);
// 移除所有特定钩子的过滤器
remove_all_filters('the_content');1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
