剖析 WordPress `register_sidebar()` 函数源码:侧边栏信息在 `$wp_registered_sidebars` 中的存储。

各位观众老爷们,早上好!咱们今天来聊聊WordPress的“墙角根儿”——register_sidebar() 函数。

准备好一杯咖啡,咱们一起扒一扒这个看似简单的函数,看看它是怎么把侧边栏的信息藏在WordPress核心的“小金库” $wp_registered_sidebars 里的。

开场白:别小看侧边栏,它可是网站的“面子”

在WordPress的世界里,侧边栏就像房子的装修,能让网站看起来更漂亮,更有条理。而要管理这些侧边栏,就得靠register_sidebar()这个“装修师傅”。 它负责告诉WordPress:“嘿,这里有个侧边栏,你得记住它,以后好让用户往里面放东西。”

正文:register_sidebar() 函数的“身世之谜”

register_sidebar() 函数的定义藏在 wp-includes/widgets.php 文件里。 咱们先来看看它的庐山真面目:

function register_sidebar( $args = array() ) {
    global $wp_registered_sidebars;

    $id = sanitize_title( $args['id'] ?? '' );

    if ( empty( $id ) ) {
        $name = $args['name'] ?? '';
        $id   = sanitize_title( $name );
        if ( empty( $id ) ) {
            _doing_it_wrong(
                __FUNCTION__,
                __( 'No "id" or "name" was defined in the arguments array. Using "sidebar-#' . count( $wp_registered_sidebars ) . '" as the ID.' ),
                '4.2.0'
            );
            $id = 'sidebar-' . count( $wp_registered_sidebars );
        }
    }

    if ( is_numeric( substr( $id, 0, 1 ) ) ) {
        _doing_it_wrong(
            __FUNCTION__,
            __( 'Sidebar IDs must start with a letter, not a number.' ),
            '4.2.0'
        );
        $id = 'sidebar-' . $id;
    }

    $defaults = array(
        'name'          => __( 'Sidebar' ),
        'id'            => $id,
        'description'   => '',
        'class'         => '',
        'before_widget' => '<li id="%1$s" class="widget %2$s">',
        'after_widget'  => '</li>',
        'before_title'  => '<h2 class="widgettitle">',
        'after_title'   => '</h2>',
    );

    $args = wp_parse_args( $args, $defaults );

    $id = sanitize_title( $args['id'] );

    if ( isset( $wp_registered_sidebars[ $id ] ) ) {
        /* translators: %s: Sidebar ID. */
        trigger_error( sprintf( __( 'Sidebar with id “%s” already registered. Skipping.' ), esc_attr( $id ) ), E_USER_NOTICE );
        return;
    }

    $wp_registered_sidebars[ $id ] = $args;

    return $args;
}

代码剖析:一步一步揭开它的“内心世界”

  1. global $wp_registered_sidebars;: 这句话是关键,它引入了一个全局变量 $wp_registered_sidebars。 这个变量就像一个大仓库,用来存放所有注册过的侧边栏的信息。 想象一下,WordPress核心就像个仓库管理员,而 $wp_registered_sidebars 就是它的仓库登记本。

  2. ID 的重要性$id = sanitize_title( $args['id'] ?? '' ); 这行代码负责获取侧边栏的 ID。 ID是侧边栏的身份证,必须是唯一的。 如果你没提供 ID,或者提供的 ID 不合法(比如以数字开头),WordPress会帮你生成一个。 确保ID是唯一的非常重要,否则你会看到错误信息。

  3. 参数解析:wp_parse_args() 的妙用: WordPress用 wp_parse_args() 函数来合并你提供的参数和默认参数。 这就像在餐厅点菜,你可以选择自己喜欢的口味,但厨师会根据基本配方来烹饪。 默认参数定义了侧边栏的基本属性,例如默认的标题标签和包裹widget的HTML。

    $defaults = array(
        'name'          => __( 'Sidebar' ),
        'id'            => $id,
        'description'   => '',
        'class'         => '',
        'before_widget' => '<li id="%1$s" class="widget %2$s">',
        'after_widget'  => '</li>',
        'before_title'  => '<h2 class="widgettitle">',
        'after_title'   => '</h2>',
    );
    
    $args = wp_parse_args( $args, $defaults );

    这个 $defaults 数组定义了如果没有在 $args 数组中指定,侧边栏参数的默认值。

    • name: 侧边栏的名称,默认为 "Sidebar"。
    • id: 侧边栏的唯一 ID。
    • description: 侧边栏的描述。
    • class: 侧边栏的 CSS 类。
    • before_widget: 在每个 widget 之前添加的 HTML 代码。%1$s 会被 widget 的 ID 替换,%2$s 会被 widget 的 CSS 类替换。
    • after_widget: 在每个 widget 之后添加的 HTML 代码。
    • before_title: 在 widget 标题之前添加的 HTML 代码。
    • after_title: 在 widget 标题之后添加的 HTML 代码。
  4. “查重”机制:确保ID的唯一性if ( isset( $wp_registered_sidebars[ $id ] ) ) { ... } 这段代码就像一个“查重”系统。 在把侧边栏信息存入 $wp_registered_sidebars 之前,它会检查是否已经有相同ID的侧边栏存在。 如果存在,就会发出警告,防止ID冲突。

  5. 入库:存入 $wp_registered_sidebars$wp_registered_sidebars[ $id ] = $args; 这行代码是核心。 它把包含侧边栏所有信息的 $args 数组,以侧边栏的 ID 为键,存入 $wp_registered_sidebars 这个全局变量中。 至此,侧边栏的信息就被安全地保存在WordPress的“小金库”里了。

$wp_registered_sidebars:WordPress的“侧边栏登记本”

$wp_registered_sidebars 是一个全局数组,它的结构大致如下:

$wp_registered_sidebars = array(
    'sidebar-1' => array(
        'name'          => '主侧边栏',
        'id'            => 'sidebar-1',
        'description'   => '显示在文章和页面右侧的侧边栏',
        'class'         => 'primary-sidebar',
        'before_widget' => '<li id="%1$s" class="widget %2$s">',
        'after_widget'  => '</li>',
        'before_title'  => '<h2 class="widgettitle">',
        'after_title'   => '</h2>',
    ),
    'footer-sidebar' => array(
        'name'          => '页脚侧边栏',
        'id'            => 'footer-sidebar',
        'description'   => '显示在网站页脚的侧边栏',
        'class'         => 'footer-sidebar',
        'before_widget' => '<div id="%1$s" class="widget %2$s">',
        'after_widget'  => '</div>',
        'before_title'  => '<h3 class="widgettitle">',
        'after_title'   => '</h3>',
    ),
    // ... 更多侧边栏
);

这个数组的键是侧边栏的 ID,值是一个数组,包含了侧边栏的所有信息,包括名称、描述、CSS类、widget的前后HTML等等。

如何使用 register_sidebar()?来点实际的!

通常,你会在主题的 functions.php 文件中,或者在插件中调用 register_sidebar() 函数。 最佳实践是在 after_setup_theme 钩子中注册你的侧边栏。

function my_theme_register_sidebars() {
    register_sidebar( array(
        'name'          => __( '主侧边栏', 'my-theme' ),
        'id'            => 'sidebar-1',
        'description'   => __( '显示在文章和页面右侧的侧边栏', 'my-theme' ),
        'before_widget' => '<li id="%1$s" class="widget %2$s">',
        'after_widget'  => '</li>',
        'before_title'  => '<h2 class="widgettitle">',
        'after_title'   => '</h2>',
    ) );

    register_sidebar( array(
        'name'          => __( '页脚侧边栏', 'my-theme' ),
        'id'            => 'footer-sidebar',
        'description'   => __( '显示在网站页脚的侧边栏', 'my-theme' ),
        'before_widget' => '<div id="%1$s" class="widget %2$s">',
        'after_widget'  => '</div>',
        'before_title'  => '<h3 class="widgettitle">',
        'after_title'   => '</h3>',
    ) );
}
add_action( 'after_setup_theme', 'my_theme_register_sidebars' );

这段代码注册了两个侧边栏:一个名为“主侧边栏”,ID为“sidebar-1”;另一个名为“页脚侧边栏”,ID为“footer-sidebar”。

如何在主题中显示侧边栏?dynamic_sidebar() 大显身手!

注册侧边栏之后,你需要使用 dynamic_sidebar() 函数在主题中显示它。

<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
    <aside id="secondary" class="widget-area">
        <?php dynamic_sidebar( 'sidebar-1' ); ?>
    </aside><!-- #secondary -->
<?php endif; ?>

这段代码首先检查“sidebar-1”是否激活(也就是是否至少有一个widget被添加到该侧边栏)。 如果激活,就显示该侧边栏。 dynamic_sidebar() 函数会根据你在 register_sidebar() 中定义的 before_widgetafter_widgetbefore_titleafter_title 参数,自动生成HTML代码。

实战演练:打造一个自定义侧边栏

假设我们要创建一个自定义的侧边栏,用于显示广告。 我们可以这样写:

function my_theme_register_ad_sidebar() {
    register_sidebar( array(
        'name'          => __( '广告侧边栏', 'my-theme' ),
        'id'            => 'ad-sidebar',
        'description'   => __( '用于显示广告的侧边栏', 'my-theme' ),
        'before_widget' => '<div id="%1$s" class="widget ad-widget %2$s">',
        'after_widget'  => '</div>',
        'before_title'  => '<h4 class="widgettitle">',
        'after_title'   => '</h4>',
    ) );
}
add_action( 'after_setup_theme', 'my_theme_register_ad_sidebar' );

然后,在主题中显示这个侧边栏:

<?php if ( is_active_sidebar( 'ad-sidebar' ) ) : ?>
    <div id="ad-sidebar" class="ad-sidebar">
        <?php dynamic_sidebar( 'ad-sidebar' ); ?>
    </div>
<?php endif; ?>

现在,你就可以在WordPress后台的“小工具”页面,把广告widget添加到“广告侧边栏”了。

深入挖掘:$args 参数详解

register_sidebar() 函数接受一个 $args 数组,这个数组包含了侧边栏的所有配置信息。 让我们来详细了解一下这些参数:

参数 类型 描述
name string 侧边栏的名称,显示在WordPress后台的“小工具”页面。
id string 侧边栏的唯一ID。 必须是小写字母、数字和短横线的组合,并且必须以字母开头。
description string 侧边栏的描述,显示在WordPress后台的“小工具”页面。
class string 侧边栏的CSS类。
before_widget string 在每个widget之前添加的HTML代码。 %1$s 会被widget的ID替换,%2$s 会被widget的CSS类替换。
after_widget string 在每个widget之后添加的HTML代码。
before_title string 在widget标题之前添加的HTML代码。
after_title string 在widget标题之后添加的HTML代码。

注意事项:一些“坑”需要避开

  • ID 必须唯一: 确保每个侧边栏的 ID 都是唯一的,否则会导致冲突。
  • after_setup_theme 钩子中注册: 最佳实践是在 after_setup_theme 钩子中注册你的侧边栏。
  • 使用 is_active_sidebar() 检查: 在显示侧边栏之前,务必使用 is_active_sidebar() 函数检查该侧边栏是否激活。
  • 国际化: 使用 __() 函数进行国际化,让你的主题或插件支持多语言。

进阶技巧:动态生成侧边栏

有时候,你可能需要根据用户的选择,动态生成侧边栏。 例如,你可以根据文章的分类,为每个分类创建一个侧边栏。

function my_theme_register_category_sidebars() {
    $categories = get_categories();
    foreach ( $categories as $category ) {
        $sidebar_id = 'category-' . $category->term_id;
        register_sidebar( array(
            'name'          => sprintf( __( '%s 分类侧边栏', 'my-theme' ), $category->name ),
            'id'            => $sidebar_id,
            'description'   => sprintf( __( '显示在 %s 分类页面的侧边栏', 'my-theme' ), $category->name ),
            'before_widget' => '<li id="%1$s" class="widget %2$s">',
            'after_widget'  => '</li>',
            'before_title'  => '<h2 class="widgettitle">',
            'after_title'   => '</h2>',
        ) );
    }
}
add_action( 'after_setup_theme', 'my_theme_register_category_sidebars' );

这段代码会遍历所有分类,为每个分类创建一个侧边栏。 侧边栏的 ID 是 category- 加上分类的 ID。

在分类页面显示侧边栏:

<?php
$category = get_queried_object();
$sidebar_id = 'category-' . $category->term_id;
if ( is_active_sidebar( $sidebar_id ) ) : ?>
    <aside id="secondary" class="widget-area">
        <?php dynamic_sidebar( $sidebar_id ); ?>
    </aside><!-- #secondary -->
<?php endif; ?>

总结:register_sidebar() 的精髓

register_sidebar() 函数是WordPress主题开发中一个非常重要的函数。 它负责注册侧边栏,并将侧边栏的信息存储在 $wp_registered_sidebars 全局变量中。 通过理解 register_sidebar() 函数的工作原理,你可以更好地控制你的主题,并创建更灵活的侧边栏布局。

结尾:下次见!

希望今天的讲座对你有所帮助。 记住,掌握 register_sidebar() 函数,就像掌握了WordPress主题开发的“装修秘籍”。 下次再见,祝大家编程愉快!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注