搜索全站
主题 15 分钟阅读

Kirki 框架加速 WordPress 主题选项开发:控件与默认值设置

原生 Customizer 写十个设置项要两百行代码?Kirki 用 add_config、add_section、add_field 三步搞定,还能自动生成前台 CSS。本文讲清安装方式、常用控件、默认值与 output 写法,以及该不该在项目里用它。

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

引言:选项一多,原生写法就开始重复

上篇用 Customizer API 做设置项,三四个字段很清爽;做到第十五个字段时你会发现自己在反复复制 add_setting + add_control 的样板代码,颜色控件还要额外处理 sanitize_hex_color,排版字段(字号、行高、字重、字族)更是得拆成四五个 Setting 才能拼出来。

Kirki 就是在这个位置出现的:它把「注册一个字段」压缩成一次 Kirki::add_field() 调用,内部帮你补上 sanitize、存储、控件渲染,甚至能根据字段值自动输出前台 CSS。对独立开发者来说,它把选项开发从「写架构」变成「填配置」——但代价是引入一个体积不小的依赖,这点后面要单独谈。

原理分析:Kirki 到底替你做了什么

Kirki 本质上是 Customizer API 的封装层,不是另一套存储机制。它仍然把值写进 theme_mod 或 option,你依然用 get_theme_mod() 取值。它的价值集中在四件事:

能力 原生 Customizer Kirki
字段注册 add_setting + add_control 两次调用 一次 add_field
安全过滤 每个字段手写 sanitize_callback 按控件类型自动匹配
前台 CSS 自己写 wp_head 内联样式 output 参数自动生成
复杂控件 需自行开发 typography / dimension / repeater / sortable 开箱即用
依赖体积 0 约 1MB(含控件脚本与样式)

output 是 Kirki 最有杀伤力的功能:声明 element(CSS 选择器)和 property(CSS 属性)后,Kirki 会在前台生成一段内联样式,值一改样式就变,省掉自己写 wp_head 的那段代码。它同样支持 units、media_query 和 prefix。

需要注意的是 Kirki 的版本演进:4.x 之后官方推荐以插件形式安装(WordPress.org 的 Kirki Customizer Framework),主题内嵌版本(kirki/kirki.php)虽然仍可用,但会与插件版产生重复加载告警。老项目常见 Kirki::add_config(),新版本命名空间为 Kirki\Compatibility\Kirki,这点在迁移时要留意。

保姆级实操

第一步:安装 Kirki

推荐插件方式,避免主题内嵌带来的合规问题(官方主题目录不允许捆绑强制激活的库):

wp plugin install kirki --activate

若坚持内嵌,用 Composer 拉到主题目录:

cd wp-content/themes/mimangfei
composer require kirki-framework/kirki

然后在 functions.php 顶部引入自动加载:

require_once get_template_directory() . '/vendor/autoload.php';

第二步:配置 config、panel、section

add_action( 'init', 'mimangfei_kirki_config' );

function mimangfei_kirki_config() {

    Kirki::add_config( 'mimangfei', array(
        'capability'  => 'edit_theme_options',
        'option_type' => 'theme_mod',
    ) );

    Kirki::add_panel( 'mimangfei_panel', array(
        'priority' => 160,
        'title'    => esc_html__( '主题设置', 'mimangfei' ),
    ) );

    Kirki::add_section( 'mimangfei_typo', array(
        'panel'    => 'mimangfei_panel',
        'title'    => esc_html__( '排版', 'mimangfei' ),
        'priority' => 10,
    ) );
}

option_type 可选 theme_mod(默认)或 option,决定值存到哪里。

第三步:常用控件逐个写

Kirki::add_field( 'mimangfei', array(
    'type'     => 'typography',
    'settings' => 'body_typography',
    'label'    => esc_html__( '正文字体', 'mimangfei' ),
    'section'  => 'mimangfei_typo',
    'default'  => array(
        'font-family'    => 'system-ui',
        'font-size'      => '16px',
        'line-height'    => '1.75',
        'font-weight'    => '400',
    ),
    'output'   => array(
        array(
            'element' => 'body',
        ),
    ),
) );

Kirki::add_field( 'mimangfei', array(
    'type'      => 'dimension',
    'settings'  => 'container_width',
    'label'     => esc_html__( '内容区最大宽度', 'mimangfei' ),
    'section'   => 'mimangfei_typo',
    'default'   => '1200px',
    'output'    => array(
        array(
            'element'  => '.container',
            'property' => 'max-width',
        ),
    ),
) );

Kirki::add_field( 'mimangfei', array(
    'type'     => 'switch',
    'settings' => 'show_breadcrumb',
    'label'    => esc_html__( '显示面包屑', 'mimangfei' ),
    'section'  => 'mimangfei_typo',
    'default'  => true,
    'choices'  => array(
        'on'  => esc_html__( '开启', 'mimangfei' ),
        'off' => esc_html__( '关闭', 'mimangfei' ),
    ),
) );

Kirki::add_field( 'mimangfei', array(
    'type'     => 'sortable',
    'settings' => 'single_layout',
    'label'    => esc_html__( '文章页模块顺序', 'mimangfei' ),
    'section'  => 'mimangfei_typo',
    'default'  => array( 'title', 'meta', 'content', 'share' ),
    'choices'  => array(
        'title'   => esc_html__( '标题', 'mimangfei' ),
        'meta'    => esc_html__( '元信息', 'mimangfei' ),
        'content' => esc_html__( '正文', 'mimangfei' ),
        'share'   => esc_html__( '分享按钮', 'mimangfei' ),
    ),
) );

常用 type 一览:text、textarea、color、image、upload、select、radio、radio-image、checkbox、switch、toggle、slider、number、dimension、spacing、typography、background、repeater、sortable、code、link、multicolor。

第四步:前台取值与兜底

$show_breadcrumb = get_theme_mod( 'show_breadcrumb', true );

if ( $show_breadcrumb ) {
    get_template_part( 'template-parts/breadcrumb' );
}

$order = get_theme_mod( 'single_layout', array( 'title', 'meta', 'content', 'share' ) );

Kirki 的 default 只在字段未保存时生效,前台取值仍要写兜底参数——因为主题刚启用、数据库还没写入时,get_theme_mod() 不会自动读 Kirki 的默认值。

第五步:partial refresh 让预览不刷新

Kirki::add_field( 'mimangfei', array(
    'type'     => 'text',
    'settings' => 'footer_text',
    'label'    => esc_html__( '页脚文字', 'mimangfei' ),
    'section'  => 'mimangfei_typo',
    'default'  => esc_html__( '© 2026 迷忙飞', 'mimangfei' ),
    'partial_refresh' => array(
        'footer_text' => array(
            'selector'        => '.site-footer__text',
            'render_callback' => function() {
                echo esc_html( get_theme_mod( 'footer_text', '' ) );
            },
        ),
    ),
) );

比手写 postMessage 的 JS 省事得多,适合纯文本内容。

常见踩坑

  1. 插件版与内嵌版同时存在:后台出现重复字段,控制台报 Kirki 多次初始化;二选一。
  2. Kirki::add_config 的 id 与取值无关:很多人以为 get_theme_mod( 'mimangfei_body_typography' ),实际取值 key 就是 settings 的值,config id 不参与拼接。
  3. option_type 改成 option 后旧数据丢失:theme_mod 的历史值不会自动迁移,需要写一次性迁移脚本。
  4. output 生成的选择器不生效:多因 element 写成了类名的简写或前台根本没有对应元素,用浏览器审查元素确认选择器命中。
  5. typography 字段返回值是数组:echo get_theme_mod('body_typography') 会报 Array to string conversion,必须取 $value['font-size'] 这样的子项。
  6. 案例:某主题把 Kirki 内嵌在 inc/ 目录并强制 require,客户站点后来装了 Kirki 插件做其他配置,两个版本控件脚本互相覆盖,Customizer 打开后滑块控件全部失灵。最终改为检测 class_exists( 'Kirki' ) 后再注册,冲突才消失。
  7. 字段数量过多导致 Customizer 卡顿:超过 60 个字段时建议拆 panel,并关闭不必要的 transport 实时刷新。
  8. 主题上架官方目录不建议内嵌:捆绑库属于「需要额外激活」的灰色地带,建议改为推荐安装插件。

总结

选型判断:字段少于 15 个、类型简单——用原生 Customizer(见 Customizer API 添加设置项);字段多、需要排版/尺寸/排序这类复合控件、且是自用或客户定制项目——Kirki 能省下大量时间;要做上架销售的主题——优先考虑把选项收敛到区块编辑器与 theme.json,或用「按需推荐安装插件」的方式,别把库硬塞进主题包。这一点和 主题选项框架对比 里的取舍逻辑是一致的。

U
UFO_PF作者

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

留下你的想法

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