以编程方式将小部件添加到侧边栏

时间:2011-08-22 作者:Marlun

我想通过编程将小部件添加到我的两个侧栏中。我找不到任何正式的方法?

我开始查数据库。我发现是“sidebars\\u widgets”选项将小部件放在了侧栏上。查看选项时,小部件名称的末尾添加了一个数字,如:widget\\u name-6。这个数字来自哪里?

有没有办法解决这个问题?

4 个回复
最合适的回答,由SO网友:fuxia 整理而成

当我开始回答这个问题时,它应该只是一个小纸条。嗯,我失败了。很抱歉和我在一起,有一个美好的东西隐藏在内心深处…

WordPress小部件的存储方式小部件列表存储在名为\'sidebars_widgets\'. A.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 向下滚动,直到看到如下内容:

screen shot of serialized widget options

是,序列化数据。不,你不能在这里读这些。别担心,你不必担心。

演示小部件为了更好地说明内部工作原理,我编写了一个非常简单的演示小部件:

/**
 * 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\'  => \'\'
            )
        );
    }
到目前为止,一切都很简单。我们的主题现在是widget ready,演示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, a负号- 还有柜台。这个content 小部件的$demo_widget_content. 这是柜台key 小部件参数存储在一个数组中。

为了避免碰撞,我们将计数器增加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稍后会自动找到这些
我们没有保存演示小部件参数,因为我们现在在第二个侧边栏中添加了第二个实例…

// 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 );
…并保存t5_demo_widget 一下子。无需更新同一选项两次。

好了,今天有足够的小部件了,让我们保存sidebars_widgets 也是:

update_option( \'sidebars_widgets\', $active_widgets );
现在WordPress将知道有一些已注册的小部件以及每个小部件的参数存储在哪里。A.var_export() 在侧边栏上,小部件将如下所示:

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,
)
Thecomplete code 再次强调:

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 );
}
如果你去wp-admin/widgets.php 现在,您将看到三个预设小部件:

screen shot of active widgets

就这样。使用…

dynamic_sidebar( \'top-widget\' );
dynamic_sidebar( \'bottom-widget\' );
…打印小部件。

有一个小问题:您必须为初始注册加载前端两次<如果有人能帮忙,我将非常感激

SO网友:BdN3504

感谢分享您的解决方案。我使用了这个问题中描述的内容来创建一段代码,可以很容易地用来初始化侧栏。它非常灵活,您可以创建任意多个小部件,而无需修改代码。只需使用过滤器挂钩并在数组中传入参数。以下是注释代码:

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\\u 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\',
    ),
 );

}
理想情况下,您可以在设置函数中调用initialize\\u边栏,该函数在插件或主题激活时调用,如下所示:主题激活:

add_action( \'after_switch_theme\', \'my_activation_function\' );
function my_activation_function() {
  initialize_sidebars();
}
插件激活:

register_activation_hook( __FILE__, \'my_activation_function\' );
function my_activation_function() {
  initialize_sidebars();
}
要总结此功能组合的使用情况,请执行以下操作:

创建一个函数来初始化连接到“alter\\u initialization\\u sidebars”过滤器的侧栏。

为刚刚添加的每个侧栏创建一个函数,该函数连接到“alter\\u initialization\\u widgets\\u$sidebarname”过滤器。将$sidebarname替换为步骤1中创建的每个侧栏的名称。

您也可以简单地将此未注释的代码复制到函数文件中,然后立即开始创建过滤器函数:Code on pastie (without initialization filter functions)

SO网友:Manolo

首先,感谢@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 进入widgets菜单并查看想要的侧边栏。第一个<div id="widgets-holder-wrap">\'s<div> 孩子有sidebar-id

注2:您可以获得widget_name 转到widgets菜单并检查想要的widget。你会看到<div id="widget-6_widget_name-__i__" class="widget ui-draggable">.

我希望能有所帮助。

SO网友:its_me

以下是您的操作方式:

(警告,如果您没有将原始小部件放回widgets 阵列。)

    $widgets = array(
    \'middle-sidebar\' => array(
        \'widget_name\'
    ),
    \'right-sidebar\' => array(
        \'widget2_name-1\'
    )
);
update_option(\'sidebars_widgets\', $widgets);
如果您以后想向小部件添加如下选项,可以使用-数字:

    update_option(\'widget_widget_name\', array(
    1 => array(
        \'title\' => \'The tile\',
        \'number\' => 4
    ),
    \'_multiwidget\' => 1
));

结束

相关推荐

Sidebar Generator? :)

我厌倦了编辑功能。每次我想添加/删除侧栏时,都会使用php。我知道有Sidebar Generator plugin, 但我想自己开发一些东西,不用插件就可以开箱即用。无论如何,我已经知道如何列出所有侧边栏,如何注册和删除它们,但我不知道如何从选项页自动执行此操作(当然我已经有了一个)。我已经分析了插件的代码,但我的PHP很烂,所以我不懂一半甚至更多。也许这里有人开发了自己的边栏生成器,可以帮助我掌握一些基本知识,比如如何使用$\\u POST等注册新的边栏。?我在考虑fopen(“functions.p