【问题标题】:Wordpress apply filter / add filter from child themeWordpress 应用过滤器/从子主题添加过滤器
【发布时间】:2025-12-01 22:30:01
【问题描述】:

我查看了有关如何完成此操作的文档和示例,但看不出下面的代码有什么问题。我的子主题中的函数没有被调用。这可能很明显,但我就是看不到,欢迎任何指点...

父主题的functions.php

add_action('init', 'st_header_scripts');
    function st_header_scripts() {
        $javascripts  = wp_enqueue_script('jquery');
        $javascripts .= wp_enqueue_script('custom',get_bloginfo('template_url') ."/javascripts/app.js",array('jquery'),'1.2.3',true);
        $javascripts .= wp_enqueue_script('superfish',get_bloginfo('template_url') ."/javascripts/superfish.js",array('jquery'),'1.2.3',true);
        $javascripts .= wp_enqueue_script('formalize',get_bloginfo('template_url') ."/javascripts/jquery.formalize.min.js",array('jquery'),'1.2.3',true);

        echo apply_filters ('child_add_javascripts',$javascripts);
    }

在子主题中...

function child_add_javascripts($javascripts) {
        $javascripts  = "test";
        echo "test"; die;
        return $javascripts;
    }

    add_filter('st_header_scripts','child_add_javascripts');

【问题讨论】:

    标签: php wordpress wordpress-theming


    【解决方案1】:

    这里有一些问题。 wp_enqueue_script 不是返回函数,因此您没有理由将其设置为变量。它的作用是在 header.php 中调用 wp_head() 后生成所有必需的脚本标签

    其次,问题源于您使用 add_filter 和 apply_filter。但我认为我们应该讨论一下操作和过滤器之间的实际区别(您可能知道,但其他人可能不知道):

    动作根据接收到的数据执行操作
    过滤器对接收到的数据进行处理并返回

    do_action()apply_filter() 是您的触发器函数,它们将触发器名称作为其第一个参数,以及您希望传递给回调的参数,因为它是第 2-n 个参数。

    add_action()add_filter() 是您的侦听器,它们在其第一个参数中查找定义的名称,然后执行在其第二个参数中定义的回调函数。

    鉴于您的情况,您最好使用操作挂钩的第三个参数优先处理您的操作挂钩。

    父主题:

    add_action('wp_enqueue_scripts', 'st_header_scripts');
    function st_header_scripts() {
        wp_enqueue_script('jquery');
        wp_enqueue_script('custom',get_bloginfo('template_url') ."/javascripts/app.js",array('jquery'),'1.2.3',true);
        wp_enqueue_script('superfish',get_bloginfo('template_url') ."/javascripts/superfish.js",array('jquery'),'1.2.3',true);
        wp_enqueue_script('formalize',get_bloginfo('template_url') ."/javascripts/jquery.formalize.min.js",array('jquery'),'1.2.3',true);
    }
    

    儿童主题:

    add_action('wp_enqueue_scripts','child_add_javascripts',20); //This will execute the child_add_javascripts callback after the st_header_scripts callback
    function child_add_javascripts(){
        wp_enqueue_script('child_javascript',get_bloginfo('stylesheet_directory') ."/javascripts/child_js.js",array('jquery'),'1.2.3',true); //This looks in the CHLID theme's directory while template_url looks in the parent theme's directory
    }
    

    我花了一点时间才牢牢掌握所有不同的核心操作和过滤器,但是一旦您习惯了它并利用它来满足您所有主题的需求,它们就会成为一个非常强大的工具。

    如果这有帮助,请告诉我

    【讨论】:

      【解决方案2】:

      那么,您希望在父主题中拥有一个挂钩您的 JS 文件的功能,而在子主题中只添加 JS 文件?

      你的代码有点乱。我解释一下

      1. 脚本应该挂接到wp_enqueue_scripts,而不是init
      2. wp_enqueue_script 不返回任何值(甚至不返回 NULL :-D),因此将其分配给变量是无用的
      3. 注意过滤器的命名,函数add_filterapply_filters一起“工作”,所以它们的第一个参数应该相同

      这里是代码,我假设你想要的,在父主题中,创建了一个函数,它执行入队,通过子主题,你只设置一个要挂钩和入队的 javascript 文件数组。

      function st_header_scripts() {
      
          /**
           * 'jquery' has FALSE value, since it is registered in wordpress and you do not need an url
           */
          $js_files = array(
              'jquery' => false,
              'custom' => get_bloginfo('template_url') ."/javascripts/app.js",
              'superfish' => get_bloginfo('template_url') ."/javascripts/superfish.js",
              'formalize' =>get_bloginfo('template_url') ."/javascripts/jquery.formalize.min.js"
          );
      
          /**
           * Here you create a variable with a possibility to be filtered
           * The first argument is your custom name of your filter
           * The second argument is a variable which might be modified with filter and assigned to the $javascripts variable
           */
          $javascripts = apply_filters('header_javascripts', $js_files);
      
          /**
           * Here you just enqueue your scripts
           */
          if(false != $javascripts)
              foreach($javascripts as $name => $uri)
                  if(!$uri)
                      wp_enqueue_script($name);
                  else
                      wp_enqueue_script($name, $uri, array('jquery'), '1.2.3', true );
      }
      add_action('wp_enqueue_scripts', 'st_header_scripts');
      
      /**
       * A callback for a filter `header_javascripts`
       * @param array $original_js array of JS files from parent theme
       * You can either add JS into array or create and return new array
       */
      function children_theme_js($original_js) {
      
          //adding to original array
          $original_js[] = 'jquery-ui-core';
      
          //not enqueueing JS from parent theme
          //$original_js = array();
          //$original_js['script'] = 'I-am-the-url';
      
          //you need to return an array into the filter
          return $original_js;
      }
      add_filter('header_javascripts','children_theme_js');
      

      【讨论】: