WordPress中文开发手册

WordPress主题开发 — Widgets

小部件将内容和功能添加到小部件区域(也称为侧边栏)。 小部件区域为用户定制其网站提供了一种方式。 窗口小部件区域可以显示在多个页面上或仅在一个页面上。 您的主题可能只有一个小部件区域或其中许多。

可以使用小部件区域的一些示例如下:

  • 使用小部件布置首页。 这允许网站所有者决定在其主页的每个部分应该出现什么。
  • 创建一个页脚,用户可以使用自己的内容进行自定义。
  • 向博客添加可自定义的侧边栏。
  • 小部件是输出一些HTML的PHP对象。 相同类型的小部件可以在同一页面上多次使用(例如,文本小部件)。 小部件可以将数据保存在数据库中(在选项表中)。

当您创建一种新的小部件时,它将显示在用户的“管理屏幕”的“外观”>“小部件”中。 用户可以将窗口小部件添加到窗口小部件区域,并从WordPress管理员自定义窗口小部件设置。

内置和独立的小部件

默认WordPress安装包含一组小部件。 除了这些标准的小部件,主题或插件可以包含额外的小部件。 内置在主题或插件中的小部件的优点是提供额外的功能并增加小部件的数量。

缺点是,如果主题已更改或插件被停用,插件或主题小部件的功能将会丢失。 但是,如果重新激活主题或插件,则小部件的数据和首选项将保存到选项表,并恢复。

如果您的主题包含小部件,则只有在该主题处于活动状态时才能使用。 如果用户决定改变他们的主题,他们将无法访问该小部件。 但是,如果插件包含插件,则用户可以更改其主题,而不会失去对窗口小部件功能的访问。

小部件解剖

视觉上,一个小部件包括两个方面:

  • 标题区
  • 小部件选项

例如,这里是管理员和前端内置文本小部件的布局:

  • 示例可编辑小部件
  • 管理区域中的小部件表单。

一个小部件,因为它可以访问一个网站访问者。网站访问者看到的小部件。此小部件的HTML输出如下所示:

<div id="text-7" class="widget widget_text"> <!-- Widget Container -->
    <div class="widget-wrap">
        <h4 class="widgettitle">This is a text widget</h4> <!-- Title -->
        <div class="textwidget"> <!-- Content of Widget -->
                   I can put HTML in here.
           <a href="http://google.com">Search me!</a>
        </div>
    </div>
</div>

每个小部件都有自己的方式输出与正在显示的数据相关的HTML。 小部件的包装器标签由其正在显示的小部件区域定义。

PHP需要创建一个内置的文本小部件,如下所示:

class My_Widget extends WP_Widget {
 
    function __construct() {
 
        parent::__construct(
            'my-text',  // Base ID
            'My Text'   // Name
        );
 
        add_action( 'widgets_init', function() {
            register_widget( 'My_Widget' );
        });
 
    }
 
    public $args = array(
        'before_title'  => '<h4 class="widgettitle">',
        'after_title'   => '</h4>',
        'before_widget' => '<div class="widget-wrap">',
        'after_widget'  => '</div></div>'
    );
 
    public function widget( $args, $instance ) {
 
        echo $args['before_widget'];
 
        if ( ! empty( $instance['title'] ) ) {
            echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
        }
 
        echo '<div class="textwidget">';
 
        echo esc_html__( $instance['text'], 'text_domain' );
 
        echo '</div>';
 
        echo $args['after_widget'];
 
    }
 
    public function form( $instance ) {
 
        $title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( '', 'text_domain' );
        $text = ! empty( $instance['text'] ) ? $instance['text'] : esc_html__( '', 'text_domain' );
        ?>
        <p>
            <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'text_domain' ); ?></label>
            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
        </p>
        <p>
            <textarea class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'text' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'text' ) ); ?>" type="text" cols="30" rows="10"><?php echo esc_attr( $text ); ?></textarea>
        </p>
        <?php
 
    }
 
    public function update( $new_instance, $old_instance ) {
 
        $instance = array();
 
        $instance['title'] = ( !empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
        $instance['text'] = ( !empty( $new_instance['text'] ) ) ? $new_instance['text'] : '';
 
        return $instance;
    }
 
}
$my_widget = new My_Widget();

上面的代码将在后面的文章中详细解释。

开发小部件

要创建和显示窗口小部件,您需要执行以下操作:

  • 通过扩展标准的WP_Widget类及其一些功能来创建小部件的类。
  • 注册您的小部件,以便它可以在Widgets屏幕中使用。
  • 确保您的主题至少有一个小部件区域添加小部件。

你的小部件类

WP_Widget类位于wp-includes / widgets.php中

class My_Widget extends WP_Widget {
 
    public function __construct() {
        // actual widget processes
    }
 
    public function widget( $args, $instance ) {
        // outputs the content of the widget
    }
 
    public function form( $instance ) {
        // outputs the options form in the admin
    }
 
    public function update( $new_instance, $old_instance ) {
        // processes widget options to be saved
    }
 
}

每个这些功能的文档可以在窗口小部件类代码中找到:

  • __construct:在管理员中设置具有说明,名称和显示宽度的小部件。
  • widget:处理小部件选项并在页面上显示HTML。 $ args参数提供了HTML可以用来显示窗口小部件标题类和窗口小部件内容类。
  • form:显示用于设置窗口小部件选项的窗体。 如果您的窗口小部件没有任何选项,则可以跳过此功能(尽管即使空白也是最佳做法)。
  • update:将小部件选项保存到数据库。 如果您的窗口小部件没有任何选项,则可以跳过此功能(尽管即使空白也是最佳做法)。

注册小部件

register_widget()函数用于注册一个小部件。

使用widgets_init钩子调用此函数:

add_action( 'widgets_init', function() { register_widget( 'My_Widget' ); } );

当您使用register_sidebar()注册窗口小部件时,将指定包含窗口小部件的HTML以及标题和窗口小部件内容的类。

示例文本小部件

从本文开头的示例中构建文本小部件。您将首先设置一个扩展WP_Widget类的窗口小部件类。

在类构造函数中,您将调用父构造函数并将其传递给您的窗口小部件的基本ID和名称。同样在类构造函数中,您将挂接到widgets_init操作以注册您的窗口小部件。

接下来,您将声明创建窗口小部件时使用的参数。你必须定义四个参数,before_title,after_title,before_widget和after_widget。这些参数将定义包装小部件标题和小部件本身的代码。

定义参数后,您将定义小部件功能。此函数有两个参数,前面的$ args数组和窗口小部件的$实例,它将处理表单中的选项,并在您网站的前端显示窗口小部件的HTML。在上面的例子中,窗口小部件功能简单地输出窗口小部件标题,同时通过widget_title过滤器。然后,它放置一个简单的小部件包装器和小部件的文本字段的内容。如示例中所述,您可以从存储在$ instance中的小部件访问选项。

接下来你将定义表单函数。此函数使用一个参数$ instance,并输出用户在Widgets管理屏幕中用于创建窗口小部件的窗体。在上面的例子中,函数首先定义$ title和$ text变量,并将它们设置为先前输入的值(如果存在这些值)。然后,它输出一个简单的表单,带有标题的文本字段和文本内容的textarea。

最后你将定义更新功能。此函数具有两个参数$ new_instance和$ old_instance,并且负责在提交时使用新选项更新您的小部件。在这里,您只需将$ instance定义为空数组。然后,您将标题和文本键设置为$ new_instance值(如果存在)。然后你返回$ instance。

最后,当定义所有上述内容时,您将实例化新的小部件类并测试您的工作。

示例小部件

/**
 * Adds Foo_Widget widget.
 */
class Foo_Widget extends WP_Widget {
 
    /**
     * Register widget with WordPress.
     */
    public function __construct() {
        parent::__construct(
            'foo_widget', // Base ID
            'Foo_Widget', // Name
            array( 'description' => __( 'A Foo Widget', 'text_domain' ), ) // Args
        );
    }
 
    /**
     * Front-end display of widget.
     *
     * @see WP_Widget::widget()
     *
     * @param array $args     Widget arguments.
     * @param array $instance Saved values from database.
     */
    public function widget( $args, $instance ) {
        extract( $args );
        $title = apply_filters( 'widget_title', $instance['title'] );
 
        echo $before_widget;
        if ( ! empty( $title ) ) {
            echo $before_title . $title . $after_title;
        }
        echo __( 'Hello, World!', 'text_domain' );
        echo $after_widget;
    }
 
    /**
     * Back-end widget form.
     *
     * @see WP_Widget::form()
     *
     * @param array $instance Previously saved values from database.
     */
    public function form( $instance ) {
        if ( isset( $instance[ 'title' ] ) ) {
            $title = $instance[ 'title' ];
        }
        else {
            $title = __( 'New title', 'text_domain' );
        }
        ?>
        <p>
        <label for="<?php echo $this->get_field_name( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
        <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
        </p>
        <?php
    }
 
    /**
     * Sanitize widget form values as they are saved.
     *
     * @see WP_Widget::update()
     *
     * @param array $new_instance Values just sent to be saved.
     * @param array $old_instance Previously saved values from database.
     *
     * @return array Updated safe values to be saved.
     */
    public function update( $new_instance, $old_instance ) {
        $instance = array();
        $instance['title'] = ( !empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
 
        return $instance;
    }
 
} // class Foo_Widget

然后可以在widgets_init钩子中注册此示例窗口小部件:

// Register Foo_Widget widget
add_action( 'widgets_init', function() { register_widget( 'Foo_Widget' ); } );

##使用命名空间的示例

如果您使用PHP 5.3命名空间,则应直接调用构造函数,如下例所示:

namespace a\b\c;
 
class My_Widget_Class extends \WP_Widget {
    function __construct() {
            parent::__construct( 'baseID', 'name' );
        }
        // ... rest of the functions
}

并使用以下命令调用注册窗口

add_action( 'widgets_init', function() { register_widget( 'a\b\c\My_Widget_Class' ); } );

有关详细信息,请参阅堆栈交换中的此答案。

特殊考虑

如果要在其他模板文件中使用小部件,而不是侧边栏,则可以the_widget()以编程方式显示。 该函数接受窗口小部件类名。 您将小部件类名称传递给这样的函数:

<h1><?php the_title(); ?></h1>
 
<div class="content">
    <?php the_content(); ?>
</div>
 
<div class="widget-section">
    <?php the_widget( 'My_Widget_Class' ); ?>
</div>

如果您需要在页面上的特定区域中使用窗口小部件,则可能需要使用此方法,例如在网站首页的某个部分中显示表单旁边的事件列表,或者显示电子邮件捕获表单 一个超级菜单旁边的导航。

Tags