搜索全站
主题 14 分钟阅读

add_theme_support 完整用法:主题该声明哪些能力

从 title-tag、post-thumbnails 到 html5、wp-block-styles、align-wide,逐个说明 add_theme_support 常用参数的作用、引入版本与验证方法,附一套可直接用的 after_setup_theme 配置。

U
UFO_PF 2018-04-07 · 阅读 14 分钟
ad 主题
阅读提示
本文约 5,464 字,预计阅读 14 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:为什么别人的主题有特色图,我的没有

上传文章时右侧「特色图片」模块怎么都找不到,翻遍后台设置也没有开关。搜索一圈才知道是主题没声明支持:add_theme_support( 'post-thumbnails' )。类似的情况还有:<title> 标签被 SEO 插件重复输出两遍、搜索框的 HTML5 占位属性不生效、古腾堡编辑器里的”宽幅对齐”按钮是灰的。

这些”功能开关”都由同一个函数控制。它不产生任何可见输出,只往全局变量 $_wp_theme_features 里登记一条记录,然后由核心各处通过 current_theme_supports() 查询。理解这一点,就知道它不是”锦上添花的声明”,而是主题对核心的”能力契约”。

原理分析:一个登记函数,三种使用形态

add_theme_support( string $feature, mixed ...$args )

内部实现极其简单:

// wp-includes/theme.php(简化)
function add_theme_support( $feature, ...$args ) {
    global $_wp_theme_features;
    if ( ! $args ) {
        $_wp_theme_features[ $feature ] = true;     // 形态一:布尔开关
    } else {
        $_wp_theme_features[ $feature ] = $args;    // 形态二:带参数
    }
}

三种形态对应不同类型的能力:

形态 示例 核心如何使用
布尔开关 add_theme_support( 'title-tag' ) 决定是否接管 <title> 输出
数组参数 add_theme_support( 'html5', array( 'comment-form', 'gallery' ) ) 逐个判断是否输出 HTML5 标记
复杂配置 add_theme_support( 'post-thumbnails', array( 'post', 'page' ) ) 限定作用范围

查询侧统一走 current_theme_supports( $feature, ...$args ),比如 current_theme_supports( 'html5', 'gallery' ) 会检查 gallery 是否在数组里。移除用 remove_theme_support( $feature ),一般只在子主题里用来”反悔”父主题的声明。

注意调用时机:必须在 after_setup_theme 钩子里调用(或直接在 functions.php 顶层,此时 after_setup_theme 尚未触发)。挂在 init 上太晚,很多功能已经初始化完毕。

保姆级实操

第 1 步:基础必备项

add_action( 'after_setup_theme', function () {
    // 由主题接管 <title>,避免与 SEO 插件重复输出(WP 4.1+)
    add_theme_support( 'title-tag' );

    // 开启特色图片,数组参数限定作用的文章类型(WP 2.9+)
    add_theme_support( 'post-thumbnails' );

    // 自动输出 RSS feed 链接到 <head>(WP 3.0+)
    add_theme_support( 'automatic-feed-links' );
} );

title-tag 开启后,<head> 里不要再手写 <title>,也不要在 header.php 里调 wp_title()(已废弃)。SEO 插件(Yoast、Rank Math)检测到 title-tag 后会接管输出,不会重复。

第 2 步:HTML5 标记支持

add_theme_support( 'html5', array(
    'search-form',    // 搜索表单用 <input type="search"> 与 HTML5 占位符
    'comment-form',   // 评论表单
    'comment-list',   // 评论列表用 <ol class="comment-list">
    'gallery',        // 图库用 <figure>/<figcaption>
    'caption',        // 图片说明用 <figure>/<figcaption>
    'style',          // 去掉 <style> 标签上的 type="text/css"
    'script',         // 去掉 <script> 标签上的 type="text/javascript"
) );

'style' 与 'script' 是 WP 5.3 加入的,用于移除 HTML5 已默认的类型属性,对通过校验工具有帮助。少声明一项,对应的输出就会退回 XHTML 风格标记。

第 3 步:块编辑器(古腾堡)相关

add_theme_support( 'wp-block-styles' );        // 加载核心块默认样式(WP 5.0+)
add_theme_support( 'align-wide' );             // 启用"宽幅/全宽"对齐按钮(WP 5.0+)
add_theme_support( 'responsive-embeds' );      // 嵌入内容自适应(WP 4.9+)
add_theme_support( 'editor-styles' );          // 编辑器加载 editor-style.css(WP 3.0+)
add_theme_support( 'custom-logo', array(       // 站点 Logo(WP 4.5+)
    'height'      => 60,
    'width'       => 200,
    'flex-height' => true,
    'flex-width'  => true,
) );
add_theme_support( 'customize-selective-refresh-widgets' ); // 小组件局部刷新(WP 4.5+)
add_theme_support( 'post-formats', array( 'aside', 'gallery', 'video' ) ); // 文章形式(WP 3.1+)

editor-styles 要在 after_setup_theme 里再补一句资源加载,否则不生效:

add_action( 'after_setup_theme', function () {
    add_editor_style( 'assets/css/editor-style.css' );
} );

第 4 步:自定义 Logo 的前台输出

// header.php 里
if ( has_custom_logo() ) {
    the_custom_logo();
} else {
    printf(
        '<a href="%1$s" class="site-title">%2$s</a><p class="site-desc">%3$s</p>',
        esc_url( home_url( '/' ) ),
        esc_html( get_bloginfo( 'name' ) ),
        esc_html( get_bloginfo( 'description' ) )
    );
}

the_custom_logo() 会输出带 custom-logo 类的 <a><img></a>,并自动带 srcset,主题只需给它写宽度样式。

第 5 步:加自定义能力,并让插件能查询

主题也可以自己登记一项能力,供插件侧判断:

// 主题声明:支持深色模式
add_theme_support( 'mmf-dark-mode' );

// 插件里查询
if ( current_theme_supports( 'mmf-dark-mode' ) ) {
    add_action( 'wp_footer', 'myplugin_inject_dark_toggle' );
}

这是主题与插件解耦协作的标准方式,比”检测主题名是不是 Astra”可靠得多。

第 6 步:验证声明是否生效

wp eval 'var_dump( current_theme_supports( "post-thumbnails" ) );'
wp eval 'print_r( get_theme_support( "html5" ) );'

后台也能肉眼验证:文章编辑页右侧出现「特色图片」模块 → post-thumbnails 生效;「外观 → 自定义」里出现「站点身份 → Logo」→ custom-logo 生效;编辑器段落工具栏出现”宽幅对齐” → align-wide 生效。调用 the_custom_logo() 之外的自定义输出,记得按输出转义规范 esc_html esc_attr esc_url处理。

常见踩坑

  1. 挂在 init 上。 太晚,title-tag 等需要在模板渲染前完成登记。统一挂 after_setup_theme。
  2. header.php 里既手写 <title> 又开 title-tag。 页面源码里出现两个 <title>,搜索引擎抓取结果不稳定。
  3. 开了 post-thumbnails 但前台不显示。 声明只是让后台能上传,前台还必须调用 the_post_thumbnail(),且需要图片尺寸,见add_image_size 自定义缩略图尺寸。
  4. html5 传了字符串。 add_theme_support( 'html5', 'gallery' ) 会把整个参数存成字符串,判断时匹配失败。必须传数组。
  5. 子主题想去掉父主题的能力却改了父主题文件。 应在子主题里 remove_theme_support(),注意钩子优先级要更晚:
add_action( 'after_setup_theme', function () {
    remove_theme_support( 'post-formats' );
}, 11 );   // 父主题默认 10,子主题用 11 才能覆盖
  1. 案例: 某站升级主题后,Google Search Console 里大量页面报”标题重复/标题过短”。排查发现新主题没声明 title-tag,header.php 里手写了一个 <title><?php wp_title(); ?></title>,而 wp_title() 在 WP 4.4 之后已废弃且输出为空,导致部分页面 <title> 只剩站点名。补上 add_theme_support( 'title-tag' )、删除手写标签后两周内恢复正常。
  2. 把 add_theme_support 写在条件判断里。 比如 if ( is_home() ) 内部——此时 after_setup_theme 早已过去,is_home() 也还没确定,声明会静默失效。

总结

配置 add_theme_support 的标准动作是:在 after_setup_theme 里一次性声明,不做条件判断;基础三项(title-tag、post-thumbnails、automatic-feed-links)任何主题都该有;块编辑器时代再加 wp-block-styles、align-wide、responsive-embeds、editor-styles、custom-logo。验证别靠感觉,用 wp eval 'var_dump( current_theme_supports( "xxx" ) );' 一条命令确认。它是主题与核心之间最基础的一份契约,写得越完整,插件与编辑器的行为越可预期。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。