WordPress中文开发手册

WordPress主题开发 — 定制对象

Customize API是面向对象的。 Customizer对象有四种主要类型:面板,部分,设置和控件。 设置将UI元素(控件)与保存在数据库中的设置相关联。 部分是用于控制的UI容器,以改善其组织。 面板是部分的容器,允许将多个部分组合在一起。

每个Customizer对象由PHP类表示,所有对象都由Customize Manager对象WP_Customize_Manager管理。

要添加,删除或修改任何Customizer对象,并访问Customizer Manager,请使用customize_register钩子:

function themeslug_customize_register( $wp_customize ) {
  // Do stuff with $wp_customize, the WP_Customize_Manager object.
}
add_action( 'customize_register', 'themeslug_customize_register' );

Customizer Manager为每个Customizer对象类型提供add_,get_和remove_方法; 每个都有一个id。 get_方法允许直接修改添加控件时指定的参数。

add_action('customize_register','my_customize_register');
function my_customize_register( $wp_customize ) {
  $wp_customize->add_panel();
  $wp_customize->get_panel();
  $wp_customize->remove_panel();
 
  $wp_customize->add_section();
  $wp_customize->get_section();
  $wp_customize->remove_section();
 
  $wp_customize->add_setting();
  $wp_customize->get_setting();
  $wp_customize->remove_setting();
 
  $wp_customize->add_control();
  $wp_customize->get_control();
  $wp_customize->remove_control();
}

注意:主题通常不应该使用get方法来修改核心部分和面板,因为主题不应该修改核心的,与主题无关的功能。 鼓励插件在必要时使用这些功能。 主题不应该“重组”主题未添加的自定义程序部分。

设置

设置可以处理您的定制器对象的实时预览,保存和清理。 每个设置由控制对象管理。 添加新设置时可以使用几个参数:

$wp_customize->add_setting( 'setting_id', array(
  'type' => 'theme_mod', // or 'option'
  'capability' => 'edit_theme_options',
  'theme_supports' => '', // Rarely needed.
  'default' => '',
  'transport' => 'refresh', // or postMessage
  'sanitize_callback' => '',
  'sanitize_js_callback' => '', // Basically to_json.
) );

警报:重要事项:不要使用看起来像widget_ ,sidebars_widgets [],nav_menu []或nav_menu_item []的设置ID。 这些设置ID模式分别保留用于窗口小部件实例,侧边栏,导航菜单和导航菜单项。 如果您需要在设置ID中使用“widget”,请将其用作后缀而不是前缀,例如“homepage_widget”。

有两种主要的设置类型:选项和主题修改。 选项直接存储在WordPress数据库的wp_options表中,并应用于该站点,而不考虑活动主题。 如果添加了选项类型的设置,主题很少。 另一方面,主题模式是针对特定主题的。 大多数主题选项应该是theme_mods。 例如,自定义CSS插件可以将自定义主题css设置注册为theme_mod,允许每个主题具有独特的一组CSS规则,而不会在切换主题然后切换时丢失CSS。

  • customize-theme-mods-options
  • Theme_mod与选项设置类型示例。

通常最重要的是设置设置的默认值以及其清理回调,这将确保数据库中不存储不安全的数据。 典型主题用法:

$wp_customize->add_setting( 'accent_color', array(
  'default' => '#f72525',
  'sanitize_callback' => 'sanitize_hex_color',
) );

Typical plugin usage:

$wp_customize->add_setting( 'myplugin_options[color]', array(
  'type' => 'option',
  'capability' => 'manage_options',
  'default' => '#ff2525',
  'sanitize_callback' => 'sanitize_hex_color',
) );

请注意,定制程序可以使用选项类型处理存储为键控数组的选项以进行设置。 这允许将多个设置存储在不是主题模式的单个选项中。 要检索并使用您的Customizer选项的值,请使用get_theme_mod()和get_option()与设置标识:

function my_custom_css_output() {
  echo '<style type="text/css" id="custom-theme-css">' .
  get_theme_mod( 'custom_theme_css', '' ) . '</style>';
  echo '<style type="text/css" id="custom-plugin-css">' .
  get_option( 'custom_plugin_css', '' ) . '</style>';
}
add_action( 'wp_head', 'my_custom_css_output');

请注意,get_theme_mod()和get_option()的第二个参数是默认值,它应该与添加设置时设置的默认值相匹配。

控制

控件是用于创建UI的主要Customizer对象。 具体来说,每个控件必须与设置相关联,并且该设置将将用户输入的数据从控件保存到数据库(除了将其显示在实时预览中并将其消毒之外)。 控件可以由定制程序管理器添加,并以极少的努力提供一组强大的UI选项:

$wp_customize->add_control( 'setting_id', array(
  'type' => 'date',
  'priority' => 10, // Within the section.
  'section' => 'colors', // Required, core or custom.
  'label' => __( 'Date' ),
  'description' => __( 'This is a date control with a red border.' ),
  'input_attrs' => array(
    'class' => 'my-custom-class-for-js',
    'style' => 'border: 1px solid #900',
    'placeholder' => __( 'mm/dd/yyyy' ),
  ),
  'active_callback' => 'is_front_page',
) );

添加控件时最重要的参数是它的类型 - 这决定了Customizer将显示哪种类型的UI。 Core提供了几种内置控件类型:

<input>任何允许类型的元素(见下文)

  • checkbox
  • textarea
  • radio (将值的数组=>标签传递给选择参数)
  • select (将值的数组=>标签传递给choices参数)
  • dropdown-pages (使用allow_addition参数允许用户从控件添加新页面)

对于html input元素支持的任何输入类型,只需在添加控件时将type属性值传递给type参数即可。 这允许支持控件类型,如文本,隐藏,数字,范围,URL,电话,电子邮件,搜索,时间,日期,日期时间和周,等待浏览器支持。

必须将控件添加到部分,然后才能显示(部分必须包含要显示的控件)。 这是通过在添加控件时指定section参数来完成的。 以下是添加基本textarea控件的示例:

$wp_customize->add_control( 'custom_theme_css', array(
  'label' => __( 'Custom Theme CSS' ),
  'type' => 'textarea',
  'section' => 'custom_css',
) );

这是一个基本的范围(滑块)控件的例子。 请注意,大多数浏览器将不会显示此控件的数值,因为范围输入类型是为确切值不重要的设置而设计的。 如果数值很重要,请考虑使用数字类型。 input_attrs参数将映射属性=>值的键控数组到输入元素上的属性,并且可以用于从占位符文本到数据的用途 - 自定义脚本中的JavaScript引用的数据。 对于数字和范围控制,它允许我们设置最小值,最大值和步长值。

$wp_customize->add_control( 'setting_id', array(
  'type' => 'range',
  'section' => 'title_tagline',
  'label' => __( 'Range' ),
  'description' => __( 'This is the range control description.' ),
  'input_attrs' => array(
    'min' => 0,
    'max' => 10,
    'step' => 2,
  ),
) );

核心自定义控件

如果没有一个基本的控制类型适合您的需要,您可以轻松地创建和添加自定义控件。 自定义控件在本文后面将会更全面地解释,但它们基本上是基于WP_Customize_Control对象的子类,允许任何可能需要的html标记和功能。 Core提供了几个内置的自定义控件,允许开发人员轻松实现丰富的JavaScript驱动功能。 可以添加颜色选择器控件,如下所示:

$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'color_control', array(
  'label' => __( 'Accent Color', 'theme_textdomain' ),
  'section' => 'media',
) ) );

MediaPress 4.1和4.2还增加了对任何类型的多媒体内容的支持。 媒体控制实现本地WordPress媒体管理器,允许用户从其库中选择文件或上传新的文件。 通过在添加控件时指定mime_type参数,可以指示媒体库显示为特定类型,如图像或音频:

$wp_customize->add_control( new WP_Customize_Media_Control( $wp_customize, 'image_control', array(
  'label' => __( 'Featured Home Page Image', 'theme_textdomain' ),
  'section' => 'media',
  'mime_type' => 'image',
) ) );
$wp_customize->add_control( new WP_Customize_Media_Control( $wp_customize, 'audio_control', array(
  'label' => _( 'Featured Home Page Recording', 'theme_textdomain' ),
  'section' => 'media',
  'mime_type' => 'audio',
) ) );

请注意,与WP_Customize_Media_Control关联的设置保存相关的附件ID,而所有其他媒体相关控件(WP_Customize_Upload_Control的子项)将媒体文件URL保存到该设置。 有关Make WordPress Core的更多信息。

此外,WordPress 4.3引入了WP_Customize_Cropped_Image_Control,它为选择后的图像提供了一个界面。 这对于需要特定宽高比的情况很有用。

部分

部分是Customizer控件的UI容器。 虽然您可以将自定义控件添加到核心部分,但如果您有多个选项,则可能需要添加一个或多个自定义部分。 使用WP_Customize_Manager对象的add_section方法添加新的部分:

$wp_customize->add_section( 'custom_css', array(
  'title' => __( 'Custom CSS' ),
  'description' => __( 'Add custom CSS here' ),
  'panel' => '', // Not typically needed.
  'priority' => 160,
  'capability' => 'edit_theme_options',
  'theme_supports' => '', // Rarely needed.
) );

您只需要包含要覆盖默认值的字段。 例如,默认优先级(外观顺序)通常是可接受的,如果您的选项不言自明,大多数部分不应该需要描述性文本。 如果您想要更改自定义部分的位置,则核心部分的优先级如下所示:

TitleIDPriority (Order)
Site Title & Taglinetitle_tagline20
Colorscolors40
Header Imageheader_image60
Background Imagebackground_image80
Menus (Panel)nav_menus100
Widgets (Panel)widgets110
Static Front Pagestatic_front_page120
default160
Additional CSScustom_css200

在大多数情况下,可以添加仅指定一个或两个参数的节。 以下是添加与主题页脚相关的选项部分的示例:

// Add a footer/copyright information section.
$wp_customize->add_section( 'footer' , array(
  'title' => __( 'Footer', 'themename' ),
  'priority' => 105, // Before Widgets.
) );

面板

Customizer Panels API是在WordPress 4.0中引入的,允许开发人员创建一个超出控件和部分的层次结构。控制面板不仅仅是简单地分组控件,而是设计为定制工具提供不同的上下文,例如自定义窗口小部件,菜单,或者将来可能编辑帖子。部分和面板对象之间存在重要的技术区别。

在大多数情况下,主题不应该注册自己的面板。部分不需要嵌套在面板下,每个部分通常应包含多个控件。控件也应该添加到核心提供的部分,例如为颜色部分添加颜色选项。还要确保您的选择尽可能精简和高效;看到WordPress的哲学。面板设计为整个功能(如小部件,菜单或帖子)的上下文,而不是用于通用部分的包装。如果您绝对必须使用面板,您会发现API与章节几乎完全相同:

$wp_customize->add_panel( 'menus', array(
  'title' => __( 'Menus' ),
  'description' => $description, // Include html tags such as <p>.
  'priority' => 160, // Mixed with top-level-section hierarchy.
) );
$wp_customize->add_section( $section_id , array(
  'title' => $menu->name,
  'panel' => 'menus',
) );

面板必须包含至少一个必须包含至少一个控件的节,以显示。 如上例所示,Sections可以添加到面板中,类似于将控件添加到Sections。 但是,与控件不同,如果Panel参数在注册Section时为空,则它将显示在主要的顶级定制程序上下文中,因为大多数部分不应包含在面板中。

自定义控件,部分和面板

通过对与每个Customizer对象相关联的PHP对象进行子类化,可以轻松创建自定义控件,部分和面板:WP_Customize_Control,WP_Customize_Section和WP_Customize_Panel(这也可以用于WP_Customize_Setting,但自定义设置通常使用自定义设置类型更好地实现,如 在下一节概述)。 以下是基本自定义控件的示例:

class WP_New_Menu_Customize_Control extends WP_Customize_Control {
  public $type = 'new_menu';
  /**
  * Render the control's content.
  */
  public function render_content() {
  ?>
    <button class="button button-primary" id="create-new-menu-submit" tabindex="0"><?php _e( 'Create Menu' ); ?></button>
  <?php
  }
}

通过对基本控件类进行子类化,您可以使用自定义功能覆盖任何功能,也可以根据需要使用核心功能。 要覆盖的最常用的功能是render_content(),因为它允许您从头开始使用HTML创建自定义UI。 应该谨慎使用自定义控件,因为它们可能会引入与周围的核心UI不一致的UI,并导致用户混淆。 自定义定制器对象可以类似于添加默认控件,部分和面板的方式添加:

$wp_customize->add_control(
  new WP_Customize_Color_Control(
    $wp_customize, // WP_Customize_Manager
    'accent_color', // Setting id
    array( // Args, including any custom ones.
      'label' => __( 'Accent Color' ),
      'section' => 'colors',
    )
  )
);

添加控件时传递的参数映射到控件类中的类变量,因此您可以添加和使用自定义对象的特定部分在不同实例之间不同的自定义对象。

在创建自定义控件,部分或面板时,强烈建议引用核心代码,以便完全了解可以覆盖的可用功能。 Core还包括每种类型的自定义对象的示例。 这可以在wp-includes / class-wp-customize-control.php,wp-includes / class-wp-customize-section.php和wp-includes / class-wp-customize-panel.php中找到。 每个Customizer对象类型还有一个JavaScript API,可以使用自定义对象进行扩展; 有关更多详细信息,请参阅Customizer JavaScript API部分。

定制界面UI标准

自定义定制程序控件,部分和面板应尽可能匹配核心UI实践。 这包括依赖于wp-admin的标准,例如使用.button和.button-primary类。 还有一些特定于定制器的标准(从WordPress 4.7开始):

  • 白色背景颜色仅用于指示导航和可操作的项目(如输入)
  • 一般的#eee背景颜色提供与白色元素的视觉对比
  • 1px #ddd将背景边框和彼此之间的导航元素分开
  • 在需要视觉分离的元素之间提供15px的间距
  • 导航元素一侧使用4px边框显示悬停或焦点,颜色为#0073aa
  • 定制器文本使用颜色:#555d66,#0073aa用于导航元素上的悬停和焦点状态

自定义设置类型

默认情况下,定制程序支持将设置保存为选项或主题修改。 但是,可以轻松地覆盖此行为,以手动保存和预览WordPress数据库的wp_options表外的设置,或应用其他自定义处理。 要开始使用,请在添加设置时指定除选项或theme_mod之外的类型(您几乎可以使用任何字符串):

$wp_customize-&gt;add_setting( $nav_menu_setting_id, array(
  'type' =&gt; 'nav_menu',
  'default' =&gt; $item_ids,
) );

当相关控件中的值更改时,该设置将不再保存或预览。 现在,您可以使用customize_update_ $ setting-> type和customize_preview_ $ setting->类型操作来实现自定义保存和预览功能。 以下是从菜单定制程序项目中保存菜单项的顺序属性的示例(设置的值是菜单ID的有序数组):

function menu_customizer_update_nav_menu( $value, $setting ) {
  $menu_id = str_replace( 'nav_menu_', '', $setting-&gt;id );
  // ...
  $i = 0;
  foreach( $value as $item_id ) { // $value is ordered array of item ids.
    menu_customizer_update_menu_item_order( $menu_id, $item_id, $i );
  $i++;
  }
}
add_action( 'customize_update_nav_menu', 'menu_customizer_update_nav_menu', 10, 2 );

而且这里是同一个插件实现导航菜单项的预览(请注意,此示例需要PHP 5.3或更高版本):

function menu_customizer_preview_nav_menu( $setting ) {
  $menu_id = str_replace( 'nav_menu_', '', $setting->id );
  add_filter( 'wp_get_nav_menu_items', function( $items, $menu, $args ) use ( $menu_id, $setting ) {
    $preview_menu_id = $menu->term_id;
    if ( $menu_id == $preview_menu_id ) {
      $new_ids = $setting->post_value();
      foreach ( $new_ids as $item_id ) {
        $item = wp_setup_nav_menu_item( $item );
        $item->menu_order = $i;
        $new_items[] = $item;
        $i++;
      }
      return $new_items;
    } else {
      return $items;
    }
  }, 10, 3 );
}
add_action( 'customize_preview_nav_menu', 'menu_customizer_preview_nav_menu', 10, 2 );