我开始在数据库中查找。我发现这是“ sidebars_widgets”选项,将小部件放在侧边栏上。查看选项时,小部件名称的末尾添加了一个数字,例如:widget_name-6。这个数字从哪里来?
关于如何解决此问题的任何想法?
#1 楼
当我开始这个答案时,应该只是一个小字条。好吧,我失败了。抱歉!和我呆在一起,里面藏着一个好东西……如何存储WordPress小部件
小部件列表存储在名为
'sidebars_widgets'
的选项中。一个var_export()
可能会给出以下内容:array (
'wp_inactive_widgets' =>
array (
),
'top-widget' =>
array (
),
'bottom-widget' =>
array (
),
'array_version' => 3,
)
忽略
'wp_inactive_widgets'
和'array_version'
。我们不必关心这些。其他键是注册侧边栏的标识符。在这种情况下,侧栏可能已使用以下代码注册:
// Register two sidebars.
$sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
foreach ( $sidebars as $sidebar )
{
register_sidebar(
array (
'name' => $sidebar,
'id' => $sidebar,
'before_widget' => '',
'after_widget' => ''
)
);
}
默认情况下,侧栏在注册后为空。当然。
为每个注册的窗口小部件类创建一个单独的选项,其中包含所有必需的选项。该选项以字符串
widget_
开头。要获得所有活动RSS窗口小部件的选项,我们必须查看…get_option( 'widget_rss' );
array (
2 =>
array (
'title' => 'WordPress Stack Exchange',
'url' => 'http://wordpress.stackexchange.com/feeds',
'link' => 'http://wordpress.stackexchange.com/questions',
'items' => 5,
'show_summary' => 1,
'show_author' => 0,
'show_date' => 0,
),
)
注意数字2。多个实例的参数都存储在此选项按数字排序。
要查看WordPress已知哪些小部件类,请转到
wp-admin/options.php
并向下滚动,直到看到类似以下内容:,是序列化数据。不,您在这里看不到它们。不用担心,您不必这样做。
一个演示小部件
为了更好地说明内部工作原理,我编写了一个非常简单的演示小部件:
/**
* Super simple widget.
*/
class T5_Demo_Widget extends WP_Widget
{
public function __construct()
{ // id_base , visible name
parent::__construct( 't5_demo_widget', 'T5 Demo Widget' );
}
public function widget( $args, $instance )
{
echo $args['before_widget'], wpautop( $instance['text'] ), $args['after_widget'];
}
public function form( $instance )
{
$text = isset ( $instance['text'] )
? esc_textarea( $instance['text'] ) : '';
printf(
'<textarea class="widefat" rows="7" cols="20" id="%1$s" name="%2$s">%3$s</textarea>',
$this->get_field_id( 'text' ),
$this->get_field_name( 'text' ),
$text
);
}
}
注意构造函数:
't5_demo_widget'
是$id_base
,此小部件的标识符。如屏幕截图所示,其参数存储在选项widget_t5_demo_widget
中。您所有的自定义小部件都将被这样处理。您不必猜测名称。而且,由于您已经编写了小部件(可能),因此您知道了类的$instance
参数中的所有参数。主题基础知识
首先,您必须注册一些侧边栏和自定义小部件。对此的正确操作很容易记住:
'widgets_init'
。将所有内容放入容器–类或函数。为了简单起见,我将使用一个名为t5_default_widget_demo()
的函数。以下所有代码都放入
functions.php
中。类T5_Demo_Widget
应该已经加载。我只是将其放入相同的文件中... add_action( 'widgets_init', 't5_default_widget_demo' );
function t5_default_widget_demo()
{
// Register our own widget.
register_widget( 'T5_Demo_Widget' );
// Register two sidebars.
$sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
foreach ( $sidebars as $sidebar )
{
register_sidebar(
array (
'name' => $sidebar,
'id' => $sidebar,
'before_widget' => '',
'after_widget' => ''
)
);
}
到目前为止,非常简单。现在我们的主题已经准备就绪,小部件已众所周知。现在很有趣。
$active_widgets = get_option( 'sidebars_widgets' );
if ( ! empty ( $active_widgets[ $sidebars['a'] ] )
or ! empty ( $active_widgets[ $sidebars['b'] ] )
)
{ // Okay, no fun anymore. There is already some content.
return;
}
您真的不想破坏用户设置。如果侧边栏中已经有一些内容,则您的代码不应在其上运行。这就是我们在这种情况下停止的原因。
好吧,假设边栏为空……我们需要一个计数器:
$counter = 1;
小部件已编号。这些数字是WordPress的第二个标识符。
让我们更改数组:
$active_widgets = get_option( 'sidebars_widgets' );
我们也需要一个计数器(稍后再介绍):
$counter = 1;
这就是我们使用计数器,侧边栏名称和小部件参数的方式(嗯,我们只有一个参数:
text
)。// Add a 'demo' widget to the top sidebar …
$active_widgets[ $sidebars['a'] ][0] = 't5_demo_widget-' . $counter;
// … and write some text into it:
$demo_widget_content[ $counter ] = array ( 'text' => "This works!\n\nAmazing!" );
$counter++;
请注意如何创建小部件标识符:
id_base
,一个减去-
和计数器。小部件的内容存储在另一个变量$demo_widget_content
中。这是将键和小部件参数存储在数组中的计数器。为避免发生冲突,我们在完成操作后将计数器加1。
很容易。现在是一个RSS小部件。更多字段,更多乐趣!
$active_widgets[ $sidebars['a'] ][] = 'rss-' . $counter;
// The latest 15 questions from WordPress Stack Exchange.
$rss_content[ $counter ] = array (
'title' => 'WordPress Stack Exchange',
'url' => 'http://wordpress.stackexchange.com/feeds',
'link' => 'http://wordpress.stackexchange.com/questions',
'items' => 15,
'show_summary' => 0,
'show_author' => 1,
'show_date' => 1,
);
update_option( 'widget_rss', $rss_content );
$counter++;
这是新内容:
update_option()
,它将RSS小部件参数存储在单独的选项中。 WordPress稍后会自动找到它们。一急。无需两次更新相同的选项。今天有足够的小部件,让我们也保存
t5_demo_widget
:// Okay, now to our second sidebar. We make it short.
$active_widgets[ $sidebars['b'] ][] = 't5_demo_widget-' . $counter;
#$demo_widget_content = get_option( 'widget_t5_demo_widget', array() );
$demo_widget_content[ $counter ] = array ( 'text' => 'The second instance of our amazing demo widget.' );
update_option( 'widget_t5_demo_widget', $demo_widget_content );
现在WordPress将知道有一些已注册的小部件以及其中的参数为每个小部件存储。 sidebar_widgets上的
sidebars_widgets
如下所示:update_option( 'sidebars_widgets', $active_widgets );
再次完整的代码:
array (
'wp_inactive_widgets' =>
array (
),
'top-widget' =>
array (
0 => 't5_demo_widget-1',
1 => 'rss-2',
),
'bottom-widget' =>
array (
0 => 't5_demo_widget-3',
),
'array_version' => 3,
)
如果现在转到
var_export()
,您将看到三个预设的小部件:就是这样。使用…
add_action( 'widgets_init', 't5_default_widget_demo' );
function t5_default_widget_demo()
{
// Register our own widget.
register_widget( 'T5_Demo_Widget' );
// Register two sidebars.
$sidebars = array ( 'a' => 'top-widget', 'b' => 'bottom-widget' );
foreach ( $sidebars as $sidebar )
{
register_sidebar(
array (
'name' => $sidebar,
'id' => $sidebar,
'before_widget' => '',
'after_widget' => ''
)
);
}
// Okay, now the funny part.
// We don't want to undo user changes, so we look for changes first.
$active_widgets = get_option( 'sidebars_widgets' );
if ( ! empty ( $active_widgets[ $sidebars['a'] ] )
or ! empty ( $active_widgets[ $sidebars['b'] ] )
)
{ // Okay, no fun anymore. There is already some content.
return;
}
// The sidebars are empty, let's put something into them.
// How about a RSS widget and two instances of our demo widget?
// Note that widgets are numbered. We need a counter:
$counter = 1;
// Add a 'demo' widget to the top sidebar …
$active_widgets[ $sidebars['a'] ][0] = 't5_demo_widget-' . $counter;
// … and write some text into it:
$demo_widget_content[ $counter ] = array ( 'text' => "This works!\n\nAmazing!" );
#update_option( 'widget_t5_demo_widget', $demo_widget_content );
$counter++;
// That was easy. Now a RSS widget. More fields, more fun!
$active_widgets[ $sidebars['a'] ][] = 'rss-' . $counter;
// The latest 15 questions from WordPress Stack Exchange.
$rss_content[ $counter ] = array (
'title' => 'WordPress Stack Exchange',
'url' => 'http://wordpress.stackexchange.com/feeds',
'link' => 'http://wordpress.stackexchange.com/questions',
'items' => 15,
'show_summary' => 0,
'show_author' => 1,
'show_date' => 1,
);
update_option( 'widget_rss', $rss_content );
$counter++;
// Okay, now to our second sidebar. We make it short.
$active_widgets[ $sidebars['b'] ][] = 't5_demo_widget-' . $counter;
#$demo_widget_content = get_option( 'widget_t5_demo_widget', array() );
$demo_widget_content[ $counter ] = array ( 'text' => 'The second instance of our amazing demo widget.' );
update_option( 'widget_t5_demo_widget', $demo_widget_content );
// Now save the $active_widgets array.
update_option( 'sidebars_widgets', $active_widgets );
}
…打印小部件。
有一个小故障:必须为初始注册加载两次前端。如果有人可以在这里帮忙,我将非常感激。
评论
这真的很有趣..但是此代码是否不会在每次加载页面时添加一个“新”小部件?另外,另一个有趣的问题是,一个人如何能够控制这些小部件,包括从插件中而不是主题中加载它们的内容(较早加载?)
–krembo99
13年8月3日在8:36
@ krembo99如果边栏不为空,则不添加小部件。该代码在插件中的工作方式完全相同。
– fuxia♦
13年8月3日,11:46
widget_t5_demo_widget在这里指的是什么:update_option('widget_t5_demo_widget',$ demo_widget_content);?
–雪崩
15年10月16日在15:29
@SnowCrash这只是一个选项名称,没有其他引用。
– fuxia♦
15年10月16日在15:37
我发现此答案很有用,有助于您理解如何存储/使用数据。然后,我喜欢实际代码示例的另一个答案:wordpress.stackexchange.com/a/138248/27896
–泰勒·科利尔(Tyler Collier)
9月28日21:13
#2 楼
感谢您分享您的解决方案。我已使用此问题中描述的内容创建了一段代码,可以非常轻松地初始化侧边栏。它非常灵活,您可以创建任意数量的窗口小部件,而无需完全修改代码。只需利用滤镜挂钩并在数组中传递参数即可。这是注释的代码:function initialize_sidebars(){
$sidebars = array();
// Supply the sidebars you want to initialize in a filter
$sidebars = apply_filters( 'alter_initialization_sidebars', $sidebars );
$active_widgets = get_option('sidebars_widgets');
$args = array(
'sidebars' => $sidebars,
'active_widgets' => $active_widgets,
'update_widget_content' => array(),
);
foreach ( $sidebars as $current_sidebar_short_name => $current_sidebar_id ) {
$args['current_sidebar_short_name'] = $current_sidebar_short_name;
// we are passing our arguments as a reference, so we can modify their contents
do_action( 'your_plugin_sidebar_init', array( &$args ) );
}
// we only need to update sidebars, if the sidebars are not initialized yet
// and we also have data to initialize the sidebars with
if ( ! empty( $args['update_widget_content'] ) ) {
foreach ( $args['update_widget_content'] as $widget => $widget_occurence ) {
// the update_widget_content array stores all widget instances of each widget
update_option( 'widget_' . $widget, $args['update_widget_content'][ $widget ] );
}
// after we have updated all the widgets, we update the active_widgets array
update_option( 'sidebars_widgets', $args['active_widgets'] );
}
}
这是一个辅助功能,用于检查侧边栏中是否已包含内容:
function check_sidebar_content( $active_widgets, $sidebars, $sidebar_name ) {
$sidebar_contents = $active_widgets[ $sidebars[ $sidebar_name ] ];
if ( ! empty( $sidebar_contents ) ) {
return $sidebar_contents;
}
return false;
}
现在我们需要创建一个挂钩到'sidebar_init'操作的函数。
add_action( 'your_plugin_sidebar_init', 'add_widgets_to_sidebar' );
function add_widgets_to_sidebar( $args ) {
extract( $args[0] );
// We check if the current sidebar already has content and if it does we exit
$sidebar_element = check_sidebar_content( $active_widgets, $sidebars, $current_sidebar_short_name );
if ( $sidebar_element !== false ) {
return;
}
do_action( 'your_plugin_widget_init', array( &$args ) );
}
现在是小部件初始化:
add_action( 'your_plugin_widget_init', 'your_plugin_initialize_widgets' );
function your_plugin_initialize_widgets( $args ) {
extract( $args[0][0] );
$widgets = array();
// Here the widgets previously defined in filter functions are initialized,
// but only those corresponding to the current sidebar
$widgets = apply_filters( 'alter_initialization_widgets_' . $current_sidebar_short_name, $widgets );
if ( ! empty( $widgets ) ) {
do_action( 'create_widgets_for_sidebar', array( &$args ), $widgets );
}
}
最后一个动作是在每个侧边栏中创建小部件:
add_action( 'create_widgets_for_sidebar', 'your_plugin_create_widgets', 10, 2 );
function your_plugin_create_widgets( $args, $widgets ) {
extract( $args[0][0][0] );
foreach ( $widgets as $widget => $widget_content ) {
// The counter is increased on a widget basis. For instance, if you had three widgets,
// two of them being the archives widget and one of the being a custom widget, then the
// correct counter appended to each one of them would be archive-1, archive-2 and custom-1.
// So the widget counter is not a global counter but one which counts the instances (the
// widget_occurrence as I have called it) of each widget.
$counter = count_widget_occurence( $widget, $args[0][0][0]['update_widget_content'] );
// We add each instance to the active widgets...
$args[0][0][0]['active_widgets'][ $sidebars[ $current_sidebar_short_name ] ][] = $widget . '-' . $counter;
// ...and also save the content in another associative array.
$args[0][0][0]['update_widget_content'][ $widget ][ $counter ] = $widget_content;
}
}
此功能用于跟踪已经定义了特定窗口小部件的多少个实例:
function count_widget_occurence( $widget, $update_widget_content ) {
$widget_occurrence = 0;
// We look at the update_widget_content array which stores each
// instance of the current widget with the current counter in an
// associative array. The key of this array is the name of the
// current widget.
// Having three archives widgets for instance would look like this:
// 'update_widget_content'['archives'] => [1][2][3]
if ( array_key_exists( $widget, $update_widget_content ) ) {
$widget_counters = array_keys( $update_widget_content[ $widget ] );
$widget_occurrence = end( $widget_counters );
}
$widget_occurrence++;
return $widget_occurrence;
}
我们需要做的最后一件事是实际分配值。利用以下过滤器功能:
add_filter( 'alter_initialization_sidebars', 'current_initialization_sidebars' ) ;
// Use this filter hook to specify which sidebars you want to initialize
function current_initialization_sidebars( $sidebars ) {
// The sidebars are assigned in this manner.
// The array key is very important because it is used as a suffix in the initialization function
// for each sidebar. The value is what is used in the html attributes.
$sidebars['info'] = 'info-sidebar';
return $sidebars;
}
和:
add_filter( 'alter_initialization_widgets_info', 'current_info_widgets' );
// Add a filter hook for each sidebar you have. The hook name is derived from
// the array keys passed in the alter_initialization_sidebars filter.
// Each filter has a name of 'alter_initialization_widgets_' and the array
// key appended to it.
function current_info_widgets( $widgets ) {
// This filter function is used to add widgets to the info sidebar. Add each widget
// you want to assign to this sidebar to an array.
return $widgets = array(
// Use the name of the widget as specified in the call to the WP_Widget constructor
// as the array key.
// The archives widget is a widget which is shipped with wordpress by default.
// The arguments used by this widget, as all other default widgets, can be found
// in wp-includes/default-widgets.php.
'archives' => array(
// Pass in the array options as an array
'title' => 'Old Content',
'dropdown' => 'on',
// The 'on' value is arbitrarily chosen, the widget actually only checks for
// a non-empty value on both of these options
'count' => 'on',
),
);
}
理想情况下,您将在设置功能,可在插件或主题激活时被调用,如下所示:
主题激活: br />
总结该函数集合的用法:
创建一个函数,该函数初始化侧边栏,该侧边栏链接到“ alter_initialization_sidebars”过滤器。
为您刚刚添加的每个侧边栏创建一个函数,该函数已挂接到“ alter_initialization_widgets_ $ sidebarname”过滤器。将$ sidebarname替换为您在步骤1中创建的每个侧边栏的名称。
您还可以简单地将此未注释的代码复制到函数文件中,并立即开始创建过滤器函数:Pastie上的代码(无需初始化)过滤器功能)
#3 楼
首先,感谢@toscho的详细解答。对于那些正在寻找简单解决方案和默认小部件选项的人来说,这是一个简单的示例:
$active_sidebars = get_option( 'sidebars_widgets' ); //get all sidebars and widgets
$widget_options = get_option( 'widget_name-1' );
$widget_options[1] = array( 'option1' => 'value', 'option2' => 'value2' );
if(isset($active_sidebars['sidebar-id']) && empty($active_sidebars['sidebar-id'])) { //check if sidebar exists and it is empty
$active_sidebars['sidebar-id'] = array('widget_name-1'); //add a widget to sidebar
update_option('widget_name-1', $widget_options); //update widget default options
update_option('sidebars_widgets', $active_sidebars); //update sidebars
}
注1:您可以进入
sidebar-id
进入小部件菜单并检查所需的侧边栏。第一个<div id="widgets-holder-wrap">
的<div>
子级具有sidebar-id
。注2:您可以将
widget_name
转到小部件菜单并检查所需的小部件。您会看到类似<div id="widget-6_widget_name-__i__" class="widget ui-draggable">
的内容。希望对您有所帮助。
#4 楼
操作方法如下:(警告,如果不将原始小部件放回到
widgets
数组中,则可以删除所有以前的小部件。) $widgets = array(
'middle-sidebar' => array(
'widget_name'
),
'right-sidebar' => array(
'widget2_name-1'
)
);
update_option('sidebars_widgets', $widgets);
如果以后想要向小部件添加选项,则可以使用-number:
update_option('widget_widget_name', array(
1 => array(
'title' => 'The tile',
'number' => 4
),
'_multiwidget' => 1
));
评论
不要关注此事,我无法评分。使用此代码后,我的所有小部件都消失了。
–EresDev
2014年7月11日在23:34
您需要首先获取现有的小部件数组,否则将像上面的注释一样将它们全部删除。 $ widgets = get_option('sidebars_widgets');
–耳鼻喉
16年11月11日在10:03
评论
您应该在此处添加答案以回答自己的问题:)有关侧边栏小部件的简要介绍,请查看此文章:justintadlock.com/archives/2010/11/08/sidebars-in-wordpress。
监视添加小部件时进行的ajax调用的action参数,然后查找与该动作ajax挂钩相关的代码,并查看其在核心中的完成方式。简单! ;)
请重新发布您的解决方案作为答案,并接受它作为您问题的“答案”。
Browse-tutorials.com/tutorial/how-create-widget-wordpress