wordpress过滤文档?试图理解add_filter()

时间:2010-06-06 08:45:39

标签: wordpress-theming filter wordpress

我多次阅读文档,并且很难弄清楚该功能的用途。在查看文档后,我也越来越困惑,查看源代码。

add_filter($tag, $hook, $priority, $args);

在我看来,新函数扩展了父函数。让我感到困惑的是钩子的哪些部分被覆盖了。在文档的一些示例中,我看到一些变量被替换为新$ tag中的$ args。

我几乎完全理解这一切:http://www.andrewnacin.com/2010/05/18/rethinking-template-tags-in-plugins/

但后来我无法弄清楚你如何传递参数,最终会被覆盖。

提前感谢。

4 个答案:

答案 0 :(得分:12)

add_filter()apply_filters()的伴侣功能。在针对特定过滤器(apply_filters中的$tag参数)运行add_filter()之前,您可以使用add_filter为标记注册过滤器。使用该标记名称执行apply_filters()时,它会按顺序调用所有已注册的过滤器。过滤器用于通过函数传递数据以进行操作。例如,我经常发现自己使用的是wp_list_pages过滤器。我用它来删除页面列表中的换行符。所以这是它的工作原理:

首先我定义一个带有一个参数的函数,并在使用它后返回它:

function my_list_pages_filter($pages){
  $pages = preg_replace( array("\n","\r"), '', $pages );
  return $pages;
}

然后我添加了过滤器钩子: add_filter('wp_list_pages','my_list_pages_filter');

add_filter告诉WordPress“当调用函数apply_filters时,第一个参数为'wp_list_pages',请调用my_list_pages_filter。”过滤器必须至少发送一个值(任何类型:字符串,数组,整数等),并且它们希望函数返回一个值。

它们为您提供了一种在发送之前操纵输入的方法。

do_action是一个完全不同的钩子。要将信息发送到过滤器功能,请执行以下操作(取自您的示例):

<div id="content" <?php $class='post post_content'; echo apply_filters('my_custom_classes', $class); ?>>

然后在你的functions.php文件中添加:

add_filter('my_custom_classes','my_custom_classes_function');
function my_custom_classes_function($classes){
  $output 'class="'. $classes.'"';
  return $output;
}

这是一个非常基本的过滤器使用,但它是一个开始。您可以真正了解使用相同示例的过滤器可以做些什么以及一些增强功能:

function my_custom_classes_function($classes){
  $classes = explode( ' ', $classes );
  if(is_home())
    $classes[] = 'home_content';
  if(is_single())
    $classes[] = 'single_content';
  if(is_page())
    $classes[] = 'page_content';
  if(is_tag())
    $classes[] = 'tag_content';
  $output 'class="'. implode( ' ', $classes ) .'"';
  return $output;
}

答案 1 :(得分:4)

克里斯, 你似乎对一些事情感到困惑:

  1. 过滤器和操作不相关(它们都是WP称为'钩子'的类型,但在其他方面不相关)。上面你说“使用我的过滤器......”但是do_action()适用于 过滤器。
  2. 标签(即add_filter,apply_filter,add_action,do_action的标签参数与XML / HTML意义上的标签无关( - 也许你知道)。
  3. 调用Action时,使用do_action()除了强制标记名称之外,您可能还想传递参数。上面你称之为do_action('content_class'),首先,除非你第一次注册标签名为“content_class”的Action,否则它将无效,其次,你的动作函数content_class_filter(更好地命名为content_class_action as)与filter无关),有一个可选参数$ classes,因为你没有在标记名后面提供do_action的参数,所以它总是''。另请注意,您可能需要编写$ output = ..
  4. 过滤器不会“覆盖”任何内容(特别是在OO语言意义上)。添加具有相同标记的多个过滤器将导致在调用标记的apply_filters时调用所有过滤器。您可以使用priority参数控制排序。行动也是如此。

答案 2 :(得分:2)

这是非常好的文章,但我必须做一些愚蠢的错误,不过......

我试图通过“add_filter”技术删除“屏幕选项”下的WP3 +导航菜单中的一些项目:

可湿性粉剂管理员/包含/ NAV-menus.php:

function wp_nav_menu_manage_columns() {
    return array(
        '_title' => __('Show advanced menu properties'),
        'cb' => '<input type="checkbox" />',
        'link-target' => __('Link Target'),
        'css-classes' => __('CSS Classes'),
        'xfn' => __('Link Relationship (XFN)'),
        'description' => __('Description'),
    );
}

mytheme的/ function.php:

原来的功能似乎不是某些CLASS的一部分:

add_filter('wp_nav_menu_manage_columns', 'new_wp_nav_menu_manage_columns');
function new_wp_nav_menu_manage_columns() {
    return array(
        '_title' => __('Show advanced menu properties'),
        'cb' => '<input type="checkbox" />',
        'link-target' => __('Link Target'),
    );
}

但结果我可以看到包含所有项目的原始“屏幕选项”。 如果我删除行: 'css-classes'=&gt; _ ('CSS Classes'), 'xfn'=&gt; _ ('链接关系(XFN)'), 'description'=&gt; __('描述'), 直接在WP核心中,一切看起来都不错,所以我不确定是否有可能以这种方式覆盖所有WP功能。

非常感谢您的建议。 最诚挚的问候,Milo

答案 3 :(得分:0)

我已将钩子放在模板文件中:

<div id="content" <?php content_class() ?>>

钩子只是在函数文件中执行:

function content_class() {
 do_action('content_class');
}

使用我的过滤器我正在尝试将类传递给此函数。

function content_class_filter($classes='') {
   $output 'classes="'. $classes.'"';
   return $output;
}

然后最后我真的很困惑如何编写过滤器......