魔扣论坛

魔扣源码论坛业务
查看: 1347|回复: 5

[经验交流] WordPress 过滤器 Filters

[复制链接]
  • TA的每日心情
    难过
    19 小时前
  • 签到天数: 2929 天

    [LV.Master]开坛老将

    7万

    主题

    227

    回帖

    27万

    积分

    管理员

    Rank: 30Rank: 30Rank: 30Rank: 30Rank: 30Rank: 30Rank: 30Rank: 30

    魔扣币
    745005
    贡献
    157749
    威望
    32799

    最佳新人活跃会员热心会员推广达人宣传达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2015-12-14 21:06:24 | 显示全部楼层 |阅读模式
    魔扣币兑换比例:【 50以下 : ¥1 = 10 魔扣币 】丨【 50 - 100 :¥1 = 20 魔扣币】丨【 100以上:¥1 = 30 魔扣币 】

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x

    过滤器钩子和动作钩子有很大的区别。它让你可以控制代码的输出。动作钩子是让你插入代码,而过滤器钩子让你重写 WordPress 传递给钩子的代码。你的函数会对输出进行”过滤”。

    要掌握过滤器钩子的概念,必须首先明白 WordPress 的 apply_filters() 函数是如何工作的。

    1. <?php
    2. apply_filters( $tag, $value );
    3. ?>
    复制代码

    $tag – 过滤器钩子的名字。
    $value – 传递给任何添加到这个钩子的过滤器的参数。这个函数可以添加任意个额外的 $value 参数传递给过滤器。
    注意:在写一个过滤器的时候 $value 必须返回给 WordPress。

    下面是 WordPress 核心的一个过滤器钩子的例子:

    1. <?php
    2. apply_filters( 'template_include', $template );
    3. ?>
    复制代码

    这个例子中,template_include 是一个过滤器钩子的名字,$template 是一个可以通过注册到这个过滤器钩子的过滤器改变的文件名。

    什么是过滤器?

    一个过滤器是一个注册到过滤器钩子的函数。这个函数最少接受一个参数并在执行完代码后返回那个参数。没有过滤器的过滤器钩子没有任何作用。插件开发者可以通过过滤器钩子改变不同的变量 – 从字符串到多位数组。

    当一个过滤器钩子被 apply_filters() 函数调用时,所有注册到这个钩子的过滤器都会被执行。要添加一个过滤器,使用 add_filter() 函数。

    1. <?php
    2. add_filter( $tag, $function, $priority, $accepted_args );
    3. ?>
    复制代码

    和动作钩子添加动作类似。$accepted_args 是过滤器函数 $function 接受的参数个数,默认是1。你的函数必须至少接受一个参数并返回。

    可以给一个过滤器钩子添加多个过滤器。同样其他 WordPress 插件也可以给这个钩子添加过滤器。过滤器钩子并不限制给一个钩子。注意:因为每个过滤器都必须返回一个值供其他过滤器使用。如果你的函数没有返回值,那就可能会破坏整个 WordPress 或者其他的插件。

    下面看看 wp_title 过滤器钩子,它是负责页面的 <title> 元素的过滤器钩子。

    1. <?php
    2. apply_filters( 'wp_title', $title, $sep, $seplocation );
    3. ?>
    复制代码

    wp_title – 钩子名。
    $title – 一个字符串,要过滤并返回给 WordPress 的值。
    $sep – 说明 <title> 元素之间的分隔符是什么。
    $seplocation – 分隔符的位置。下一个例子中要用到。
    现在写一个函数来过滤 $title 的输出 – 在页面的 title 后面附加站点的名字:

    1. <?php
    2. add_filter( 'wp_title', 'boj_add_site_name_to_title', 10, 2 );

    3. function boj_add_site_name_to_title( $title, $seq ) {
    4. /* 得到网站名称 */
    5. $name  = get_bloginfo( 'name' );
    6. /* 附加到 $title 变量。 */
    7. $title .= $sqp.' '.$name;
    8. /* 返回 $title */
    9. return $title;
    10. }
    11. ?>
    复制代码

    boj_add_site_name_to_title() 函数修改 $title 参数并返回给 WordPress。$sep 参数在函数中使用,但没有返回。

    过滤器钩子函数

    除了前面提到的 apply_filters() 和 add_filter() 函数,WordPress 还提供其他的操作过滤器钩子的函数。

    apply_filters_ref_array

    类似于动作钩子里面的 do_action_ref_array() 函数。

    1. <?php
    2. apply_filters_ref_array( $tag, $args );
    3. ?>
    复制代码

    假设你要执行一个一般的 WordPress 没有的复杂的数据库查询来加载首页的 posts。WordPress 提供了一个叫做 posts_results 的过滤器钩子使得你可以改变它。下面是 WordPress 核心中的代码:

    1. <?php
    2. $this -> posts = apply_filters_ref_array(
    3. 'posts_results', array( $this -> posts, & $this )
    4. );
    5. ?>
    复制代码

    这个过滤器钩子向所有注册到它的过滤器传递一个 post 对象的数组。下面的例子,你完全重写这个 post 对象的数组并用自定义的内容代替。默认情况下,WordPress 查询 post 类型的 posts。下面改成查询 page 类型的 psots 并显示在首页。

    这段代码使用了 wpdb 类,在 part-6 “插件安全” 中将详细介绍。

    1. <?php
    2. add_filter( 'posts_result', 'boj_custom_home_page_posts' );

    3. function boj_cumstom_home_page_posts( $result ) {
    4. global $wpdb, $wp_query;
    5. /* 检查是否在首页 */
    6. if ( is_home() ) {
    7. /* 每页的 post 个数 */
    8. $per_page = get_option( 'posts_per_page' );
    9. /* 得到当前页 */
    10. $paged = get_query_var( 'paged' );
    11. /* 设置 $page 变量 */
    12. $page = ( ( 0 == $paged || 1 == $paged ) ? 1 : absint( $paged ) );
    13. /* 设置偏移的 posts 的个数 */
    14. $offset = ( $page - 1 ) * $per_page. ',';
    15. /* 通过 $offset 和 要显示的 posts 数量来设置 limit */
    16. $limits = 'LIMIT'. $offset . $per_page;
    17. /* 从数据库查询结果 */
    18. $result = $wpdb -> get_results("
    19. SELECT SQL_CALC_FOUND_ROWS $wpdb -> posts. *
    20. FROM $wpdb -> posts
    21. WHERE 1 = 1
    22. AND post_type = 'page'
    23. AND post_status = 'publish'
    24. ORDER BY post_title ASC $limits "
    25. );
    26. }
    27. return $result;
    28. }
    29. ?>
    复制代码

    remove_filter

    1. <?php
    2. remove_filter( $tag, $function_to_remove, $priority, $accepted_args );
    3. ?>
    复制代码

    这和前面的 remove_action 类似。

    下面看看 WordPress 定义在 wp-includes/default-filters.php 页面中的默认的过滤器。其中一个有意思的过滤器叫做 wpautop(),它将双换行转换成 HTML 的 <p> &lt/p>。这也就是我们在 HTML 发布内容时,直接回车便可在最终前端显示的时候换行的原因。它在核心代码中的几个钩子中都执行。下面是其中一个实例:

    1. <?php
    2. add_filter( 'the_content', 'wpautop' );
    3. ?>
    复制代码

    这将 wpautop() 过滤器应用到 post 的内容中,把每个换行都转换成段落( <p> )。但是也许有的客户不希望他的内容自动变成段落。那么你就可以使用 remove_filter() 函数从 the_content 钩子中删除这个过滤器。

    1. <?php
    2. remove_filter( 'the_content', 'wpautop' );
    3. ?>
    复制代码

    因为在 add_filter 的时候没有定义优先级,所以这里也不需要。

    remove_all_filters

    和前面的remove_all_actions类似。

    1. <?php
    2. remove_all_filters( $tag, $priority );
    3. ?>
    复制代码

    has_filter

    和前面的 has_action 类似。

    current_filter

    同样类似于 did_action。不过它不仅仅对过滤器钩子有效,同样对动作钩子也有效,所以它返回的是当前的 action 或者 filter 钩子。这个函数在你对多个钩子使用单个函数,但是需要依赖不同的钩子执行不同的内容的时候非常的有用。例如,客户希望在 post 标题 和内容中限制一些内容,但是这两个限制的minganci的集合是不同的。使用 current_filter() 函数来根据钩子设置不同的minganci表就可以实现用一个函数同时过滤 the_content 和 the_title。使用下面的代码,你可以把minganci替换成**。

    1. <?php
    2. add_filter( 'the_content', 'boj_replace_unwanted_words' );
    3. add_filter( 'the_title', 'boj_replace_unwanted_words' );

    4. function boj_replace_unwanted_words( $text ) {
    5. /* 如果过滤器钩子是 the_content */
    6. if( 'the_content' == current_filter() )
    7. $words = array( 'min', 'gan', 'ci' );
    8. /* 如果钩子是 the_title */
    9. elseif( 'the_title' == current_filter() )
    10. $words = array( 'zhen', 'de', 'hen', 'min', 'gan' );
    11. /* 替换minganci */
    12. $text = str_replace( $words, '**', $text );
    13. return $text;
    14. }
    15. ?>
    复制代码


    会员购买:>> 点击购买 << | 魔扣币购买:>> 点击购买 <<
    承接业务:服务器代维丨网站托管丨SEO
    联系客服:微信:morko-net | QQ:1367681973

    该用户从未签到

    2

    主题

    250

    回帖

    503

    积分

    高级魔扣

    Rank: 4

    魔扣币
    251
    贡献
    251
    威望
    0
    发表于 2017-1-4 19:58:21 | 显示全部楼层
    孤独时仰望蓝天,魔扣源码论坛,你是最近的那朵白云;寂寞时凝视夜空,你是最亮的那颗星星;闲暇时漫步林中,你是擦肩的那片绿叶;疲惫时安然入睡,你是最美的那段梦境!

    该用户从未签到

    0

    主题

    267

    回帖

    534

    积分

    高级魔扣

    Rank: 4

    魔扣币
    267
    贡献
    267
    威望
    0
    发表于 2017-7-29 06:23:43 | 显示全部楼层

    该用户从未签到

    0

    主题

    239

    回帖

    478

    积分

    中级魔扣

    Rank: 3Rank: 3

    魔扣币
    239
    贡献
    239
    威望
    0
    发表于 2018-1-4 05:13:52 来自手机 | 显示全部楼层
    支持,赞一个

    该用户从未签到

    1

    主题

    246

    回帖

    493

    积分

    中级魔扣

    Rank: 3Rank: 3

    魔扣币
    246
    贡献
    246
    威望
    0
    发表于 2018-8-6 20:19:59 来自手机 | 显示全部楼层
    支持,赞一个

    该用户从未签到

    1

    主题

    284

    回帖

    569

    积分

    高级魔扣

    Rank: 4

    魔扣币
    284
    贡献
    284
    威望
    0
    发表于 2019-3-7 12:23:47 | 显示全部楼层
    快乐是秋天的泉,碧波荡漾;快乐是秋天的雨,潇洒倘徉;快乐是秋天的果,满园飘香;快乐是秋天的风,轻舞飞扬,我送你的秋风秋雨秋泉秋果,魔扣源码论坛伴你快乐的度过金秋每一天!
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    • 联系我们
    • 新浪微博 :
    • 在线客服 :魔扣科技 
    • 源码QQ群 :魔扣源码论坛官方总群
    • 联系邮箱 :charlin#morko.net
    • 微信扫一扫
    快速回复 返回顶部 返回列表