Download the PHP package bernskioldmedia/wp-plugin-base without Composer
On this page you can find all versions of the php package bernskioldmedia/wp-plugin-base. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download bernskioldmedia/wp-plugin-base
More information about bernskioldmedia/wp-plugin-base
Files in bernskioldmedia/wp-plugin-base
Package wp-plugin-base
Short Description A WordPress plugin base that contains helpful base classes and functions that we can extend upon when developing WordPress plugins.
License MIT
Informations about the package wp-plugin-base
WP Plugin Base
The WP Plugin Base is a feature-rich composer project to be included in WordPress plugins. It provides a good base scaffolding, as well as many common base features to speed up development.
Note: We recommend scoping your end plugin using PHP Scoper to prevent version conflicts across plugins.
Installation
The plugin base is used by the Bernskiold Media WP Plugin Scaffold. We generally use this to start off new plugin development.
To use the Plugin Base, load it via composer in your plugin:
composer require bernskioldmedia/wp-plugin-base
Overview
In this plugin base you'll find classes to help you create:
- Base Plugin (Main Plugin Class)
- Installer
- Data Stores (Custom Post Types & Taxonomies)
- Data (Getters/Setters for a data store)
- FacetWP Facet
- ACF Field Group
- Custom REST Endpoint
- Customizer Settings
- Admin Columns Pro Sets
- Asset Loading
- Custom Blocks
- Jobs Class
Forge CLI
Included in the plugin base is our forge
CLI that helps you scaffold new classes that extend the base classes provided by the plugin base. The CLI is automatically installed to
your vendor's bin folder for easy access.
For even simpler access, you may define a composer script in your project, such as our scaffold has:
You can then access the CLI by running: composer forge COMMAND
.
The following commands are available:
forge make:customizer {name}
- Customizer
Generate a class that can be used to add a customizer section and settings.
Options:
--namespace="MyPlugin\Namespace"
The root plugin namespace.--prefix="my-plugin"
An optional prefix for your settings.
forge make:data {name}
- Data Class
Generate a data class where getters and setters are used to interact with a data store.
Options:
--namespace="MyPlugin\Namespace"
The root plugin namespace.--type="taxonomy"
Create a taxonomy data class instead of the default custom post type.
forge make:cpt {name}
- Custom Post Type Data Store Class
Generate a custom post type data store.
Options:
--namespace="MyPlugin\Namespace"
The root plugin namespace.
--textdomain="my-plugin"
The plugin textdomain.
forge make:taxonomy {name}
- Taxonomy Data Store Class
Generate a taxonomy data store.
Options:
-
--namespace="MyPlugin\Namespace"
The root plugin namespace. --textdomain="my-plugin"
The plugin textdomain.
forge make:facet {name}
- Facet WP Facet Class
Generate a class to register a FacetWP Facet based on a FacetWP facet export.
Options:
--namespace="MyPlugin\Namespace"
The root plugin namespace.
forge make:fieldgroup {name}
- ACF Field Group Class
Generate a class to register an ACF field group based on the ACF field group export.
Options:
--namespace="MyPlugin\Namespace"
The root plugin namespace.
forge make:rest {name}
- REST Endpoint Class
Generate a class to create a custom REST API endpoint.
Options:
--namespace="MyPlugin\Namespace"
The root plugin namespace.
forge make:block {prefix} {name}
- Creating a custom block
Generate all the files needed for a custom block.
Options:
--dynamic
or-d
Creates a dynamic block which renders using PHP.--namespace="MyPlugin\Namespace"
The root plugin namespace. Only needed if dynamic is set.
Example:
forge setup:block-build
- Sets up build assets for blocks
Generates the webpack config file as well as requires all the various NPM dependencies for building blocks.
Booting Classes
We typically need to boot (run) a series of classes and hooks/init functions when the plugin loads. This to boot further features.
Normally we do this by running the function (usually containing action calls) within the init_hooks()
function.
To make this simpler, you can add your class to the $boot = []
array on the base plugin class. It will then be run on the init hooks function automatically. This way you don't
have to extend the init hooks method for simple bootable operations.
Note: A function that you load via the boot property must implement the Hookable
interface.
Loading Assets
The abstract class AssetManager
can be used to load styles and script both public or admin intelligently.
It gives you two options. Either defining all values yourself, or if you are using @wordpress/scripts
(which we almost always are), rely on the name.asset.php
file that it
generates for dependencies and version.
The process is the same for public/admin scripts and styles.
When extending the class, you can define four arrays and methods. The array properties auto-registers the scripts, while the four methods are responsible for enqueuing.
Because you likely want to enqueue the scripts conditionally, the helper library doesn't do this automatically.
Registering scripts
Registering scripts by using the asset meta file, requires just the simple config:
This configuration assumes the following structure:
- Script is called
my-script.js
. - Script is placed in the
assets/scripts/dist
folder. - There is a
my-script.asset.php
file next to the script file in the same folder.
Alternatively, you can define the full settings (with their defaults):
Scripts are registered with the array key name as handle.
Registering styles
Registering styles by using the asset meta file, requires just the simple config:
This configuration assumes the following structure:
- Stylesheet is called
my-style.css
. - Stylesheet is placed in the
assets/styles/dist
folder. - There is a
my-style.asset.php
file next to the stylesheet file in the same folder.
Alternatively, you can define the full settings (with their defaults):
Styles are registered with the array key name as handle.
Enqueue scripts and styles
We don't automatically enqueue scripts or styles. Instead we have four magic methods that hook in correctly when defined. This allows you to conditionally enqueue scripts and styles easily as needed.
When they exist in the file, they are hooked appropriately:
They are run at priority 100 by default. To override, you can set the protected static int $enqueue_priority
.
Customizing Register Priority
By default we run the registration at priority 10. To customize, set the protected static int $register_priority
to a custom value.
Adding Admin Columns Support
To easily share Admin Columns Pro sets between environments, it's often a good idea to commit them. To export and save them easily, the plugin base hooks into Admin Columns for custom data stores.
First, include the HasAdminColumns
trait on the main plugin class.
Then, on the custom data stores that you want to store admin column sets for, set the $store_admin_columns
property to true:
Data Stores
Adding a new data store is best done via the Forge CLI forge make:cpt MyDataStore
.
To register the data store, add it to the $data_stores
property in the main plugin class:
Note: When creating a data store, you should also create a matching Data class with getters and setters.
Special data store features:
- Extend the
$metadata
array on the data store with names of the data class get/set method to automatically add the data to the REST API endpoint for the data store. - Automated permissions handling on the data store level. You may adjust default permissions by adjusting the permissions array.
- Simple hook for adjusting data store queries on
pre_get_posts
. Just add theprotected static query_modifications( \WP_Query $query ): \WP_Query;
method to the data store class. It will be automatically loaded. - Create Field Groups and add their class names to the
$field_groups
array to automatically load them. - Disable the block editor by setting the class property:
protected static $block_editor = false;
- CRUD methods for the data store.
Data Class
By creating a data class, we have a simple method for interacting with data from the data store. It's best created with the Forge CLI forge make:data {name}
. It's name should
match the data store.
It's used as: $data = new DataClass( $id );
. Within the class $this->get_id()
will always get you the current object ID.
Note: When creating a data class for a taxonomy, the TaxonomyData
class will ensure ACF taxonomy compatibility automatically.
Add your getters and setters to the data class. It has built-in support for ACF fields especially through the following methods:
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
It also has some easy querying features that return the data class.
::find( $name )
looks up an object based on the name.::find_or_create( $name )
looks up an object based on the name, and creates it if it doesn't exist.
You may convert all the data for an object into an array with the to_array()
method.
Custom Blocks
We find ourselves increasingly creating a bunch of plugins that add one or more blocks to the block editor. This requires a few functions to load and register.
All you need to do is include the Has_Blocks
trait in the base plugin class.
Blocks are assumed to be placed in a blocks
subfolder, and they are being built to dist/blocks
.
Required Folder Structure for Blocks
The trait assumes the following folder structure:
blocks/
is the location of all blocks with one folder per block. The index.js
file in each block folder is the entrypoint for the build script.
dist/blocks
is the location of built JavaScript blocks with the same filename as the main folder name.
languages/
is the location of the translation files. The handle and domain are both set to {$block_prefix}-{$block_name}
.
Defining a custom block prefix
The trait will default to using the 'bm' prefix for blocks. Blocks are named with a prefix to scope them to the project they are a part of. This also influences how the script and style handles are registered ($prefix-block-$block_name).
Your project probably requires its custom prefix. You can set it on the main plugin class like so:
Defining a custom job
When you have a long-running process that you need to run in the background, a job is what you want to run.
You can then dispatch your job like this:
Adding a bulk action
The framework contains an abstract class that you can extend to add a bulk action to one of the post type table views.
Don't forget to load the bulk action by adding it to the $boot
array in the main plugin file.
Adding a multisite tab
Extend this abstract class to add a new tab to the network admin website edit screen.
Don't forget to load the tab by adding it to the $boot
array in the main plugin file.
All versions of wp-plugin-base with dependencies
php Version ^7.4|^8.0
symfony/console Version ^4.0|^5.0
symfony/process Version ^4.0|^5.0