动态WordPress小部件创建

时间:2012-09-09 11:52:15

标签: php eval wordpress

我正在寻找一种更好的方法来为我的插件动态创建小部件。我读过this article,我相信我已经掌握了如何创建自定义小部件的基本用法。

现在我的问题是我如何根据预定义的选项动态创建多个小部件。我能想到的一种方法是使用eval()来声明每个扩展类,但随着类变大,它会变得太复杂。我不认为我可以处理作为函数参数传递的PHP代码;逃避角色是太多的工作了。还有人说使用eval()是不安全的,如果可能应该避免使用。

以下代码已准备好作为插件运行。只需添加标题注释并激活它,您就会看到添加了两个小部件。

add_action( 'widgets_init', 'load_mywidgets');
function load_mywidgets() {

    // prepare widgets
    $arrWidgets = array(
        array('id' => 'Bar', 'description' => 'This is a description for Bar', 'title' => 'This is Bar'),
        array('id' => 'Foo', 'description' => 'This is a description for Foo', 'title' => 'This is Foo')
    );

    // define widget class(es) 
    foreach ($arrWidgets as $arrWidget) {
        eval('
            class ' . $arrWidget["id"] . ' extends WP_Widget {

                function ' . $arrWidget["id"] . '() {
                    $widget_ops = array("classname" => "' . $arrWidget["id"] . '"
                                        , "description" => "' . $arrWidget["description"] . '" );
                    $this->WP_Widget("' . $arrWidget["id"] . '", "' . $arrWidget["title"] . '", $widget_ops);           
                }

                function form($instance) {
                    $instance = wp_parse_args( (array) $instance, array( "title" => "" ) );
                    $title = $instance["title"];
                    echo "<p><label for=\"" . $this->get_field_id("title") . "\">Title: <input class=\"widefat\" id=\"";
                    echo $this->get_field_id("title") . "\" name=\"" . $this->get_field_name("title") . "\" type=\"text\" value=\"" . attribute_escape($title) . "\" /></label></p>";
                }

                function update($new_instance, $old_instance) {
                    $instance = $old_instance;
                    $instance["title"] = $new_instance["title"];
                    return $instance;
                }

                function widget($args, $instance) {
                    extract($args, EXTR_SKIP);

                    echo $before_widget;
                    $title = empty($instance["title"]) ? " " : apply_filters("widget_title", $instance["title"]);

                    if (!empty($title))
                        echo $before_title . $title . $after_title;

                    // WIDGET CODE GOES HERE
                    echo "<h1>This is my new widget!</h1>";

                    echo $after_widget;
                }           
            }
        ');
        register_widget($arrWidget["id"]);
    }
}

有更简单的方法吗?我认为在实例化类更多时将选项传递给构造函数的参数是有道理的。但是当我查看核心时,构造函数已经定义并想知道如何覆盖它。似乎WP_Widget不是为实例化而设计的。

感谢您提供的信息。

[编辑] 在此处发现了类似的问题:widget create dynamiclly in wordpress plugin 但建议的解决方案也使用eval(),基本上它与我上面提到的方式相同。在我继续阅读核心时,看来register_widget()只接受参数的类名称,调用WP_Widget_Factory::register()。所以eval()可能是唯一的方法。但这并不直观。我还在寻找一种更简单的方法。

0 个答案:

没有答案