可以从(扩展WP_Widget对象的)Widget方法中将脚本入队吗?

时间:2012-05-17 作者:setterGetter

我正在创建一个小部件插件,用户可以在单个小部件区域/单个页面上的多个小部件区域上多次使用小部件的多次迭代。由于它的功能,将有不同的小部件级别的变量,我需要将这些变量从PHP单独传递到JavaScript以对其采取行动(通过jQuery)。我使用了$widget_id 以包装在HTML方面工作良好的小部件。

然而,我在将信息传递给JavaScript时遇到了问题——至少在尝试使用wp_localize_script 将信息传递到JavaScript文件。我尝试通过添加操作挂钩来将JavaScript排入小部件方法的队列来实现这一点。不幸的是,我甚至无法让JavaScript从那里排队,更不用说能够传递信息了!

以下是我所拥有的:

class my_widget extends WP_Widget {
   private $widget_id;
   private $variable; 
   private $plugin_location;

  function my_widget() {
    parent::WP_Widget(false, $name = \'My Widget Plugin\');
    $this->plugin_location = plugin_dir_url(__FILE__);
  }

  function widget($args, $instance) {   
    $this->widget_id="widget-".time().rand(1,100).rand(1,100); //make a unique id for widget, i know there are probably better ways to do this... but this works for now...
    extract( $args );
    $this->variable = $instance[\'variable\'];
    add_action(\'wp_enqueue_scripts\', array( &$this, \'plugin_scripts\' ));
    echo \'<div id="\' . $this->widget_id . \'">\';
    ...
    create & output widget
    ..
    echo \'</div>\';
   }

   ... irrelevant widget administration functions ...
  public function plugin_scripts(){
    //here we set up & pass relevant information specific to EACH INDIVIDUAL widget (can have multiple in a single widget-area) for jQuery to execute functions & methods on to the JavaScript file
    $widget_info_to_pass = array(
      "widget_id"  =>  $this->widget_id,
      "variables"  =>  $this->variables
    );

    wp_register_script( \'my-site-script\'.$this->widget_id, $this->plugin_location . "js/my.js", array(\'jquery\'),\'1.2.0\');
    wp_enqueue_script( \'my-site-script\'.$this->widget_id );
    wp_localize_script(\'my-site-script\'.$this->widget_id, \'php_params\', $widget_id_to_pass);
  }      

}

  add_action(\'widgets_init\', create_function(\'\', \'return register_widget("my_widget");\'));
这不会使脚本排队,我很确定,因为小部件直到之后才会启动wp_enqueue_scripts 钩子来了又走了。

需要注意的重要事项:it appears that to use wp_localize_script you have to call the function before wp_head.

注意到这一点,我尝试了大多数钩子,甚至无法让脚本排队,更不用说之前排队了wp_head. 如果我甚至可以让widget方法将脚本排队,我可以手动添加嵌入式JavaScript来定义每个widget实例的信息(可能是关联数组?)-但我根本无法让它将任何脚本排队。

是否可以将脚本从扩展WP_Widget 反对还是我在这里打一场无法获胜的战斗?我还缺少其他的方法吗?

-------------------更新---------------------

我根据您的建议进行了如下更新:

class my_widget extends WP_Widget {
   private $widget_id;
   private $variable; 
   private $plugin_location;

  function my_widget() {
    parent::WP_Widget(false, $name = \'My Widget Plugin\');
    $this->plugin_location = plugin_dir_url(__FILE__);
  }

  function widget($args, $instance) {   
    $this->widget_id="widget-".time().rand(1,100).rand(1,100); //make a unique id for widget, i know there are probably better ways to do this... but this works for now...
    extract( $args );
    $this->variable = $instance[\'variable\'];
   //here we set up & pass relevant information specific to EACH INDIVIDUAL widget (can have multiple in a single widget-area) for jQuery to execute functions & methods on to the javascript file
    $widget_info_to_pass = array(
      "widget_id"  =>  $this->widget_id,
      "variable"  =>  $this->variable
    );
    wp_register_script( \'my-site-script\'.$this->widget_id, $this->plugin_location . "js/my.js", array(\'jquery\'),\'1.2.0\');
    wp_enqueue_script( \'my-site-script\'.$this->widget_id );
    wp_localize_script(\'my-site-script\'.$this->widget_id, \'php_params\', $widget_id_to_pass);
    echo \'<div id="\' . $this->widget_id . \'">\';
    ...
    create & output widget
    ..
    echo \'</div>\';
   }

   ... irrelevant widget administration methods ...

}

  add_action(\'widgets_init\', create_function(\'\', \'return register_widget("my_widget");\'));
为了确保我得到了正确的信息,我做了我的。js包含以下内容:

widget_id = php_params.widget_id;
variable = php_params.variable;
console.log(widget_id + "---" + variable);
不幸的是,它只向控制台输出最终widget_id 和变量三次。

为什么会这样?知道如何让它输出正确的迭代吗?

2 个回复
最合适的回答,由SO网友:Stephen Harris 整理而成

It\'s not true that you have to use wp_localize_script before the wp_head.

从3.3开始,您可以使用wp_enqueue_script 在文档的正文中(即在小部件或短代码回调中),脚本加载到页脚中。

下面是一个骨架类,我使用它将小部件的每个实例的变量添加到数组中,然后使用wp_localize_script 将整个数组添加到文档中。这将加载脚本和页脚中的变量。

首先,在init

class my_widget extends WP_Widget {

  static $variables=array();

  function my_widget() {
      //initialiser function
  }

  function widget($args, $instance) {   
     //Display widget

     //Then make sure our options will be added in the footer
     add_action(\'wp_footer\', array(__CLASS__, \'add_options_to_script\'));

     //Enqueue the script (registered on init)
     wp_enqueue_script( \'my_script\');

     //Add the data to the (static) class variable `$variables`, using the widget ID.
     $id = $args[\'widget_id\'];
     self::$variables[$id] = \'my variable for this instance\'
   }

   //... irrelevant widget administration functions ...

  function add_options_to_script(){
       //If there is data to add, add it
       if(!empty(self::$widget_cal))
            wp_localize_script( \'my_script\', \'my_var\', self::$variables);   
  }      

}

  add_action(\'widgets_init\', create_function(\'\', \'return register_widget("my_widget");\'));

SO网友:Milo

wp_enqueue_scripts 已经发生了。将脚本直接排入小部件函数中,并将其输出到页脚中。

结束