我在寻找一个更好的方式来动态地为我的插件创建的小部件。 我读过这篇文章 ,我相信我已经掌握了如何创建一个自定义插件的基本用法。
现在的问题是我怎么能动态地创建基于预定义的选项多个部件。 我能想到的一个方法是使用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的目的不是要被实例化。
感谢您的信息。
[编辑]发现了类似的问题在这里: 在WordPress插件插件创建dynamiclly但建议的解决方案还使用eval()
,基本上是相同的方式我上面提出的。 正如我继续阅读的核心,它似乎register_widget()
只接受一个类名参数,调用WP_Widget_Factory::register()
所以eval()
可以做到这一点的唯一方法。 但是,这并不直观。 我仍然在寻找这样做的一个简单的方法。