bernskioldmedia/wp-plugin-base

这是一个包含有助于扩展的基类和函数的WordPress插件基,可用于开发WordPress插件。

2.4.1 2021-10-05 11:11 UTC

README

Total Downloads Latest Stable Version License

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'
];

此配置假设以下结构

  1. 脚本名为 my-script.js
  2. 脚本放在 assets/scripts/dist 文件夹中。
  3. 在同一文件夹中,脚本旁边有一个 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'
];

此配置假设以下结构

  1. 样式表名为 my-style.css
  2. 样式表放在 assets/styles/dist 文件夹中。
  3. 在同一文件夹中,样式表旁边有一个 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 数组中来加载该标签。