bernskioldmedia / wp-plugin-base
这是一个包含有助于扩展的基类和函数的WordPress插件基,可用于开发WordPress插件。
Requires
- php: ^7.4|^8.0
- monolog/monolog: ~1.25
- symfony/console: ^4.0|^5.0
- symfony/process: ^4.0|^5.0
README
WP插件基是一个功能丰富的composer项目,可包含在WordPress插件中。它提供了一个良好的基础框架,以及许多常用功能,以加快开发速度。
注意:我们建议使用PHP Scoper来定义您的最终插件,以防止插件之间的版本冲突。
安装
插件基由Bernskiold Media的WP插件框架使用。我们通常使用它来开始新的插件开发。
要使用插件基,请在您的插件中使用composer加载它
composer require bernskioldmedia/wp-plugin-base
概述
在这个插件基中,您将找到帮助您创建的类
- 基本插件(主插件类)
- 安装程序
- 数据存储(自定义文章类型和分类法)
- 数据(数据存储的获取器和设置器)
- FacetWP 面板
- ACF 字段组
- 自定义REST端点
- 定制器设置
- 管理列专业集
- 资产加载
- 自定义块
- 作业类
Forge CLI
在插件基中包含我们的forge
CLI,该CLI可以帮助您根据插件基提供的基类构建新的类。CLI会自动安装到您的供应商的bin文件夹中,以便于访问。
为了更简单的访问,您可以在项目中定义一个composer脚本,例如我们的框架所做的那样
"scripts": {
"forge": "./vendor/bin/forge",
}
然后,您可以通过运行: composer forge COMMAND
来访问CLI。
以下命令可用
forge make:customizer {name}
- 定制器
生成一个可以用于添加定制器部分和设置的类。
选项
--namespace="MyPlugin\Namespace"
根插件命名空间。--prefix="my-plugin"
设置的前缀(可选)。
forge make:data {name}
- 数据类
生成一个数据类,其中使用获取器和设置器与数据存储交互。
选项
--namespace="MyPlugin\Namespace"
根插件命名空间。--type="taxonomy"
创建一个分类法数据类而不是默认的自定义文章类型。
forge make:cpt {name}
- 自定义文章类型数据存储类 生成一个自定义文章类型数据存储。
选项:--namespace="MyPlugin\Namespace"
根插件命名空间。 --textdomain="my-plugin"
插件文本域。
forge make:taxonomy {name}
- 分类法数据存储类
生成一个分类法数据存储。
选项
-
--namespace="MyPlugin\Namespace"
根插件命名空间。 -
--textdomain="my-plugin"
插件文本域。
forge make:facet {name}
- Facet WP 面板类
生成一个基于FacetWP面板导出的类,用于注册FacetWP面板。
选项
--namespace="MyPlugin\Namespace"
根插件命名空间。
forge make:fieldgroup {name}
- ACF 字段组类
生成一个基于ACF字段组导出的类,用于注册ACF字段组。
选项
--namespace="MyPlugin\Namespace"
根插件命名空间。
forge make:rest {name}
- REST 端点类
生成一个用于创建自定义REST API端点的类。
选项
--namespace="MyPlugin\Namespace"
根插件命名空间。
forge make:block {prefix} {name}
- 创建自定义块
生成创建自定义块所需的所有文件。
选项
--dynamic
或-d
创建一个使用 PHP 渲染的动态块。--namespace="MyPlugin\Namespace"
根插件命名空间。如果设置为动态,则必须。
示例
./bin/forge make:block bm my-block
forge setup:block-build
- 为块设置构建资源
生成 webpack 配置文件,以及构建块所需的各个 NPM 依赖。
启动类
通常在插件加载时需要启动(运行)一系列类和 hooks/init 函数,以便启动更多功能。
通常我们通过在 init_hooks()
函数中运行函数(通常包含动作调用)来完成此操作。
为了简化操作,您可以将您的类添加到基插件类上的 $boot = []
数组中。然后它将在初始化钩子函数中自动运行。这样,您不必扩展初始化钩子方法来执行简单的启动操作。
注意:通过启动属性加载的函数必须实现 Hookable
接口。
protected static $boot = [
Assets::class,
];
加载资源
可以使用的抽象类 AssetManager
智能地加载样式和脚本,无论是公开的还是管理界面。
它提供了两种选项。要么自行定义所有值,要么如果您正在使用 @wordpress/scripts
(我们几乎总是使用),则依赖于它为依赖关系和版本生成的 name.asset.php
文件。
公开/管理脚本和样式的处理过程相同。
扩展类时,您可以定义四个数组和四个方法。数组属性自动注册脚本,而四个方法负责排队。
因为您可能希望有条件地排队脚本,所以辅助库不会自动执行此操作。
注册脚本
使用资产元文件注册脚本只需要简单的配置
protected static array $public_scripts = [
'my-script' => 'assets/scripts/dist'
];
此配置假设以下结构
- 脚本名为
my-script.js
。 - 脚本放在
assets/scripts/dist
文件夹中。 - 在同一文件夹中,脚本旁边有一个
my-script.asset.php
文件。
或者,您还可以定义完整的设置(及其默认值)
protected static array $public_scripts = [
'my-script' => [
'subfolder' => 'assets/scripts/dist', // Required.
'dependencies' => [], // Defaults to empty array if not set.
'version' => '1.0', // Defaults to plugin version if not set.
'in_footer' => true, // Defaults to true if not set.
],
];
脚本使用数组键名作为处理程序进行注册。
注册样式
使用资产元文件注册样式只需要简单的配置
protected static array $public_styles = [
'my-style' => 'assets/styles/dist'
];
此配置假设以下结构
- 样式表名为
my-style.css
。 - 样式表放在
assets/styles/dist
文件夹中。 - 在同一文件夹中,样式表旁边有一个
my-style.asset.php
文件。
或者,您还可以定义完整的设置(及其默认值)
protected static array $public_styles = [
'my-style' => [
'subfolder' => 'assets/styles/dist', // Required.
'dependencies' => [], // Defaults to empty array if not set.
'version' => '1.0', // Defaults to plugin version if not set.
'media' => 'screen', // Defaults to 'all' if not set.
],
];
样式使用数组键名作为处理程序进行注册。
排队脚本和样式
我们不自动排队脚本或样式。相反,我们定义了四个魔术方法,可以在定义时正确挂钩。这使得您可以根据需要轻松有条件地排队脚本和样式。
当它们存在于文件中时,它们会适当地挂钩
public static function enqueue_public_scripts(): void
public static function enqueue_admin_scripts(): void
public static function enqueue_public_styles(): void
public static function enqueue_admin_styles(): void
默认情况下,它们以优先级 100 运行。要覆盖,您可以将 protected static int $enqueue_priority
设置为。
自定义注册优先级
默认情况下,我们以优先级 10 运行注册。要自定义,将 protected static int $register_priority
设置为自定义值。
添加管理列支持
为了在环境之间轻松共享 Admin Columns Pro 设置,通常最好将它们提交。为了轻松导出和保存它们,插件基础通过挂钩 Admin Columns 来自定义数据存储。
首先,在主插件类上包含 HasAdminColumns
特性。
import BernskioldMedia\WP\PluginBase\BasePlugin;
import BernskioldMedia\WP\PluginBase\Admin\HasAdminColumns;
class Plugin extends BasePlugin {
use HasAdminColumns;
// ...
}
然后,对于您想要存储管理列集的自定义数据存储,将 $store_admin_columns
属性设置为 true
/**
* When set to true the admin columns in Admin Columns Pro
* will be stored in a directory in this plugin as opposed to in the database.
*
* @var bool
*/
protected static $store_admin_columns = false;
数据存储
最好通过 Forge CLI forge make:cpt MyDataStore
来添加新的数据存储。
要注册数据存储,将其添加到主插件类中的 $data_stores
属性
/**
* The data stores (class names) that will be loaded
* alongside this plugin.
*
* @var string[]
*/
protected static $data_stores = [
MyDataStore::class,
];
注意:在创建数据存储时,还应创建相应的数据类,并包含获取器和设置器。
特殊数据存储功能
- 通过在数据存储上扩展
$metadata
数组,并添加数据类的get/set方法名称,可以自动将数据添加到数据存储的REST API端点。 - 数据存储级别自动处理权限。您可以通过调整权限数组来调整默认权限。
- 在
pre_get_posts
上调整数据存储查询的简单钩子。只需将protected static query_modifications( \WP_Query $query ): \WP_Query;
方法添加到数据存储类中。它将被自动加载。 - 创建字段组,并将它们的类名添加到
$field_groups
数组中,以自动加载它们。 - 通过设置类属性禁用块编辑器:
protected static $block_editor = false;
- 数据存储的CRUD方法。
数据类
通过创建数据类,我们有一个简单的方法来与数据存储中的数据交互。最好使用Forge CLI forge make:data {name}
来创建。它的名称应与数据存储匹配。
它被用作:$data = new DataClass( $id );
。在类中$this->get_id()
将始终获取当前对象ID。
注意:当为分类创建数据类时,TaxonomyData
类将自动确保ACF分类兼容性。
将您的获取器和设置器添加到数据类中。它内置了对ACF字段的支持,特别是以下方法
get_prop( $field_key )
set_prop( $field_key, $value )
get_date_prop( $field_key, $format )
get_bool_prop( $field_key ): bool
get_term_id_prop( $field_key ): ?int
get_taxonomy_prop( $field_key, bool $multiple )
get_taxonomy_string( $field_key, $separator, $key ): string
它还具有一些易于查询的功能,这些功能返回数据类。
::find( $name )
根据名称查找对象。::find_or_create( $name )
根据名称查找对象,如果不存在则创建它。
您可以使用to_array()
方法将对象的全部数据转换为数组。
自定义块
我们发现自己越来越多地创建添加一个或多个块的插件。这需要一些加载和注册函数。
您只需在基本插件类中包含Has_Blocks
特性即可。
假设块位于blocks
子文件夹中,并且它们被构建到dist/blocks
。
use BernskioldMedia\WP\PluginBase\BasePlugin;
use BernskioldMedia\WP\PluginBase\Blocks\Has_Blocks;
class My_Plugin extends BasePlugin {
use Has_Blocks;
}
块的必需文件夹结构
特性假定以下文件夹结构
blocks/
是所有块的位置,每个块一个文件夹。每个块文件夹中的index.js
文件是构建脚本的入口点。
dist/blocks
是构建JavaScript块的位置,文件名与主文件夹名相同。
languages/
是翻译文件的位置。处理程序和域都设置为{$block_prefix}-{$block_name}
。
定义自定义块前缀
特性默认使用'bm'前缀用于块。块使用前缀来限定它们所属的项目。这也影响了脚本和样式的处理方式($prefix-block-$block_name)。
您的项目可能需要自定义前缀。您可以在主要插件类中设置它,如下所示
use BernskioldMedia\WP\PluginBase\BasePlugin;
use BernskioldMedia\WP\PluginBase\Blocks\Has_Blocks;
class My_Plugin extends BasePlugin {
use Has_Blocks;
// Set my custom block prefix.
protected static string $block_prefix = 'my-prefix';
}
定义自定义工作
当您需要运行在后台的长时间运行进程时,工作就是您要运行的内容。
use BernskioldMedia\WP\PluginBase\Jobs\Job; class My_Job extends Job { protected $action = 'clone_media_job'; /** * Process the Queue * * @param array $data * * @return bool */ protected function task( $data ) { // Do things here... return false; } protected function complete() { parent::complete(); // This code will run once the entire job is complete. } }
然后您可以像这样调度您的作业
$job = new MyJob(); foreach( $items as $item ) { $item_data = []; $job->push_to_queue( $item_data ); } $job->save()->dispatch();
添加批量操作
框架包含一个抽象类,您可以通过它扩展来向帖子类型表视图添加批量操作。
use BernskioldMedia\WP\PluginBase\Admin\Bulk_Action; class My_Bulk_Action extends Bulk_Action { protected static $scope = 'edit-post'; protected static $slug = 'my_bulk_action'; public static function process( int $object_id ): void { // Do something with each post here. } protected static function get_name(): string { return __( 'My Bulk Action', 'TEXTDOMAIN' ); } }
别忘了通过将它们添加到主插件文件中的$boot
数组来加载批量操作。
添加多站点标签
扩展这个抽象类以在网络的编辑屏幕中添加一个新标签。
use BernskioldMedia\WP\PluginBase\Admin\Multisite_Tab; class My_Tab extends Multisite_Tab { protected static string $nonce = 'my-tab-nonce'; protected static string $slug = 'my-tab'; protected static string $capability = 'manage_sites'; protected static function get_title(): string { return __( 'My Tab', 'TEXTDOMAIN' ); } public static function notice(): void { if ( ! isset( $_GET['updated'], $_GET['page'] ) || self::$slug !== $_GET['page'] ) { return; } ?> <div class="notice is-dismissible updated"> <p><?php esc_html_e( 'Success message.', 'TEXTDOMAIN' ); ?></p> </div> <?php } public static function save( WP_Site $site, $request_data ): void { // Handle saving. } public static function render(): void { $site = self::get_site_from_request(); if ( ! $site ) { return; } ?> <div class="wrap"> <p>Tab Content</p> </div> <?php } }
别忘了通过将标签添加到主插件文件中的 $boot
数组中来加载该标签。