gebruederheitz/wp-easy-customizer

Wordpress Customizer 的简化、面向对象的接口。

v3.1.0 2024-09-25 17:19 UTC

README

Wordpress Customizer 的简化、面向对象的接口。

安装

通过 composer

> composer require gebruederheitz/wp-easy-customizer

确保您有 Composer 自动加载或替代类加载器。

使用方法

有关从 v1.x 或 v2.x 迁移的信息,请参阅 UPGRADING.md

您至少需要一个 CustomizerPanel 对象来开始,可选地传递一个标签(默认为 "主题设置")。然后您可以为新的面板添加部分。

# functions.php (or controller class)
use Gebruederheitz\Wordpress\Customizer\CustomizerPanel;

// If your settings handler implement their getters as static methods, you will
// only need to instantiate the whole bunch on the customizer page:
if (is_customize_preview()) {
    // Set up a new customizer panel with the title 'My Settings'
    // It will also 'clean up' the Customizer by removing some panels (see below)
    // The ID is automatically prefixed with 'ghwp_customizer_panel_'.
    $panel = new CustomizerPanel('my_main_panel', 'My Settings');

向面板添加部分

部分是子面板或子菜单,其中包含实际设置。向面板添加部分有三种基本方法。您选择哪种方法主要取决于个人喜好和代码组织。主要区别在于通过过滤器钩子添加的部分(变体 (a) & (c),使用 $panel->addNewSection()$section->setPanel())是在渲染的面板 之后 添加的(变体 (b),使用 $panel->addSections())。因此,如果您需要特定的部分顺序,您需要确保通过相同的机制注册这些部分。

(a) 直接从面板使用自动过滤器钩子

use Gebruederheitz\Wordpress\Customizer\CustomizerPanel;

$panel = new CustomizerPanel('my_main_panel')
$panel->addNewSection(
    // A unique ID for the section
    'my_general_settings',
    // The title of the section / panel
    'General Settings',
    // An optional description shown on the top of the open panel
    null,
    // Some settings, more information below
    [
        CompanyInformation::get(),
    ]
)->addNewSection(/* This method can be chained */);

这允许非常紧凑的 Customizer 设置,特别适用于只有少量相当标准的设置的情况。缺点是您不能使用任何自定义部分类,因为 addNewSection() 总是实例化一个全新的 CustomizerSection。并且由于我们没有接收到创建的部分对象,我们必须立即添加所有设置。

(b) 实例对实例 - 直接使用对象

use Gebruederheitz\Wordpress\Customizer\CustomizerPanel;
use Gebruederheitz\Wordpress\Customizer\CustomizerSection;

$panel = new CustomizerPanel('my_main_panel')
$panel->addsSections(
    new CustomizerSection(
        'my_general_settings',
        'General Settings',
        null,
        [ CompanyInformation::get() ]
    ),
    // We could add more sections here if we wanted
);

(c) 实例对实例 - 通过自动钩子间接

use Gebruederheitz\Wordpress\Customizer\CustomizerSection;

$panelId = $panel->getId();

$section = new CustomizerSection(
    'ghwp_general_settings',
    'General Settings',
    null,
    [ CompanyInformation::get() ]
);

// We can associate the section with a panel in two ways:
// Using the actual panel instance directly...
$section->setPanel($panel);
// ...or using its ID.
$section->setPanel($panelId);

在所有这些示例中,我们都在构建部分时添加了设置。如果我们需要一些高级逻辑,它们可以单独添加。

// You can also create a section without any handlers and then add them 
// later:
$consentManagementSection = new CustomizerSection(
    'ghwp_consent_management_settings',
    'Consent Management'
);

// Associate with the panel one way...
$consentManagementSection->setPanel($panel);
// ...or another
$panel->addSections($consentManagementSection);
    
// Add hanlders retroactively
$consentManagementSection->addSettings(ConsentManagementEnabled::get());
$consentManagementSection->addSettings(
    OtherConsentManagementSetting::get(),
    ExtendedConsentManagementSetting::get(),
);

定义设置并将其添加到部分

现在您将必须定义您的设置。每个设置都是一个实现 CustomizerSetting 的类。您可以使用 BasicCustomizerSetting 进行扩展,以方便起见

use \Gebruederheitz\Wordpress\Customizer\BasicCustomizerSetting;

class TelephoneNo extends BasicCustomizerSetting 
{
    // These two methods are abstract in BasicCustomizerSetting, so your IDE 
    // will conveniently create stubs for you
    public function getKey(): string
    {
        // A unique key for the option's database entry
        return 'prefix_company_info_telephone';
    }
    
    public function getLabel(): string
    {
        // The input label shown to the user
        return 'Telephone No';
    }
}

BasicCustomizerSettings 是单例对象,因此您不需要构造它们,而是使用静态 get() 方法检索实例

$section = new CustomizerSection(
    $slug,
    $label,
    $description,
    [
        TelephoneNo::get(),
        /* ... more settings, if you like ... */
    ]
);

$section->addSettings(TelephoneNo::get(), OtherSetting::get());

检索值

# Somewhere in your code, like templates, action handlers, controllers, hook
# callbacks etc.
use My\TelephoneNo;

$phoneNumber = TelephoneNo::get()->getValue();
// or you can use our little shortcut with any BasicCustomizerSetting:
$phoneNumber = TelephoneNo::value();

设置:高级

您可以使用设置执行比上述基本示例更复杂的功能。以下是更多详细的使用示例

use Gebruederheitz\Wordpress\Customizer\BasicCustomizerSetting;

/**
 * A setting with an alternative input type and explicit default value. This 
 * example would of course be simpler to implement using the 
 * CheckboxCustomizerSetting, as described below.
 */
class ShowAddress extends BasicCustomizerSetting
{
    public function getKey() {
        return 'prefix_company_info_show_address';
    }
    
    public function getLabel() {
        return 'Show address in footer';
    }
    
    // Optional: default value, defaults to ''
    protected $default = false;
    
    // Optional: input type
    protected ?string $inputType = 'checkbox';
}

/**
 * A setting with an alternative sanitizer
 */
class StreetAddress extends BasicCustomizerSetting
{
    public function getKey() {
        return 'prefix_company_info_street_address';
    }
    
    public function getLabel() {
        return 'Street address';
    }
    
    // A "callable-string" for a function that will receive the raw value and
    // return a sanitized value.
    protected ?string $sanitizer = 'sanitize_text_field';
}

/**
 * A setting using a select field
 */
class SupportIcon extends BasicCustomizerSetting
{
    /* ... key and label */
    
    protected ?string $sanitizer = 'sanitize_text_field';
    
    protected ?string $inputType = 'select';
    
    public function getOptions: ?array
    {
        return [
            ExampleSelectValues::FIRST => 'Label for first option',
            ExampleSelectValues::SECOND => 'Label for the second option',
        ];
    }

/**
 * A setting for selecting a page from the current site, which is only visible
 * if the switch "ShowAddress" is active.
 */
class ContactPage extends BasicCustomizerSetting
{
    // ... key and label ...
    
    protected static $inputType = 'dropdown-pages';
   
    public function getActiveCallback() : ?callable
    {
        // Using an anonymous callback 
        return function () {
            $showAddress = ShowAddress::get();
            return CustomizerSettings::getValue(
                $showAddress->getKey(),
                $showAddress->getDefault()
            );
        }
        
        // Using a class method
        return [ShowAddress::get(), 'getValue'] // getValue() has a default implementation in BasicCustomizerSetting
    }
}

这些示例中的一些可能会导致大量重复。URL 输入始终具有类型 url,理想情况下始终应具有 sanitize_url 清洁器。对于这些情况,在 Gebruederheitz\Wordpress\Customizer\InputTypes 中提供了某些专用输入类

class MyCheckbox extends \Gebruederheitz\Wordpress\Customizer\InputTypes\CheckboxCustomizerSetting
{
    public function getKey(): string {
        return 'my-checkbox';
    }
    
    public function getLabel(): string {
        return 'My Checkbox';
    }
    
    /* The values below are already set on CheckboxCustomizerSetting: */
    // protected ?string $inputType = 'checkbox';
    // protected $default = false;
}

class MyUrlField extends \Gebruederheitz\Wordpress\Customizer\InputTypes\UrlCustomizerSetting
{
    public function getKey(): string {
        return 'my-url-field';
    }
    
    public function getLabel(): string {
        return 'My URL';
    }
    
    /* Already set: */
    // protected ?string $inputType = 'url';
    // protected ?string $sanitizer = 'sanitize_url';
}

class MyTextField extends \Gebruederheitz\Wordpress\Customizer\InputTypes\TextCustomizerSetting
{
    public function getKey(): string {
        return 'my-text';
    }
        
    public function getLabel(): string {
        return 'My Text';
    }
    
    /* Already set: */
    // protected ?string $sanitizer = 'sanitize_text_field';
}

自定义要删除的面板

默认情况下,CustomizerSettings "清理" Customizer,删除了一些很少使用的面板。您可以使用过滤器钩子来控制要删除哪些默认面板

use Gebruederheitz\Wordpress\Customizer\CustomizerSettings;

add_filter(
    CustomizerSettings::HOOK_FILTER_DECLUTTER_ITEMS, 
    function ($items) {
        unset($items['panels']['themes']);
        unset($items['sections']['static_front_page']);
        unset($items['sections']['custom_css']);
        unset($items['controls']['custom_logo']);
        unset($items['controls']['site_icon']);
        
        return $items;
        
        // To not "declutter" at all simply
        return [];
    }
);

使用自定义控件

如果您使用自定义控件,并且它们通过返回 CustomizerSetting::getInputType() 中的 FQCN 扩展默认的 WP_Customize_Control,则可以使用自定义控件

class MyCustomizeControl extends WP_Customize_Control {
    /* ... */
}

class MyCustomSetting implements CustomizerSetting
{
    /* ... */
    
    protected ?string $inputType = MyCustomizeControl::class;
}

使用分隔符字段

分隔符自定义字段允许在设置之间插入静态分隔,形状为 <hr>。可选地,您可以指定一个标签,该标签将在水平线下方渲染一个 <h2>。最简单的方法是使用 SeparatorSetting

use Gebruederheitz\Wordpress\Customizer\InputTypes\SeparatorSetting;

$settings = [
    // A plain horizontal rule with 2em vertical margin
    SeparatorSetting::factory('some-unique-id-for-this-separator'),
    TelephoneNo::get(),
    // With custom margin of 3em
    SeparatorSetting::factory(
        'sep-with-custom-margin',
        null,
        [
            'margin' => 3,
        ]
    ),
    // with a heading in the default color #08d
    SeparatorSetting::factory(
        'sep-general-settings',
        __('General Settings', 'namespace')
    ),
    // with heading in a custom color
    SeparatorSetting::factory(
        'some-unique-id-for-this-separator',
        'Heading',
        [
            'color' => 'hotpink',
        ]       
    ),
    // with heading in a custom color and custom margin
    // hr bottom margin is calc(${customMargin}em + 2em) to compensate for
    // the heading's margin collapsing
    SeparatorSetting::factory(
        'some-unique-id-for-this-separator',
        'Heading'
        [
            'color' => 'hotpink',
            'margin' => 1,
        ]       
    ),
];

开发

依赖项

  • asdf 工具版本管理器
  • nodeJS LTS (v18.x) 通过 asdf
  • PHP >= 7.4 (通过 asdf)
  • Composer 2.x(通过asdf)
  • 理想情况:GNU Make(或可替换的替代方案)