Since release 1.3.0, the Themosis framework provides a plugin boilerplate in order to help you develop custom WordPress plugins that can leverage Themosis framework APIs.
The plugin boilerplate provides a similar folder structure borrowed from the themosis-theme
and let you develop WordPress plugins using manageable and scalable methods.
In order to start developing custom plugins using the Themosis framework, you fist need to download a copy of the plugin boilerplate from our GitHub account:
Clone or download
green button on the right of the screen.Download ZIP
and save the plugin file on your machine.htdocs/content/plugins
directory.For this example, let's imagine a custom plugin that handles an application documentation and is called themosis-documentation
.
If you have correctly followed the previous steps, you have the plugin boilerplate files into the following directory of your Themosis framework application: htdocs/content/plugins/themosis-documentation/
Let's configure our plugin.
You could activate the plugin now but its files names and properties do not correspond yet to our planned extension. Please read the following steps in order to properly configure your custom plugin and make it work with the Themosis framework.
The plugin boilerplate contains a default composer.json
file with basics informations. Please first update the composer.json
file properties in order to define your plugin as a correct PHP package as well. If you require PHP packages, you can define them here so when you install your complete Themosis framework application, any plugin dependencies are loaded into application root vendor
directory and not with your plugin.
Inside the composer.json
file, leave the type
property set to wordpress-plugin
. This helps composer to install your plugin in the correct folder when creating a project with your extension.
Make sure to add your plugin
vendor
directory to the.gitignore
file as you won't need to track those dependencies.
Following WordPress recommendations, let's first update our plugin root file name and its inner properties.
plugin-name.php
file as your plugin folder name; In our example, this file is renamed as themosis-documentation.php
.themosis-documentation.php
file).Domain Path
which is already set correctly for you.In each plugin, we have set a default textdomain constant for use into all your gettext functions calls. Check around the plugin root file line #35 and update the placeholder constant MY_PLUGIN_TD
. For example, based on our themosis-documentation
website, we'll update this constant statement like so:
defined('THEMOSIS_DOCS_TD') ? THEMOSIS_DOCS_TD : define('THEMOSIS_DOCS_TD', 'themosis-documentation');
In your plugin root file, find and replace all instances of MY_PLUGIN_TD
by your custom plugin textdomain constant.
Make sure to set your constant value ("themosis-documentation" in our example) as the same value as top file comment
Text Domain: themosis-documentation
.
Around line #45 of your custom plugin root file, you'll find a $vars
array containing plugin configuration properties:
$vars = [
'slug' => 'plugin-key',
'name' => 'Plugin Name',
'namespace' => 'tld.domain.plugin',
'config' => 'tld_domain_plugin'
];
The slug
property is a plugin key name. This is used by your theme in order to support the plugin. The name
property is your plugin display name used on admin notice.
The namespace
property is the most important one. It will help define a custom path to your plugin and avoid conflicts with others plugins. Like the placeholder value suggests, we recommend you to use your domain name, its tld extension and finally the plugin name, all separated with a dot .
.
Finally the config
property is your plugin configuration files names prefix to use. Same as the namespace
property except that you separate each term by an underscore _
. This is also important in order to avoid configuration file names conflicts.
Based on our documentation example, here is an example on how should look like our $vars
array properties:
$vars = [
'slug' => 'themosis-documentation',
'name' => 'Themosis Documentation',
'namespace' => 'com.themosis.documentation',
'config' => 'com_themosis_documentation'
];
When developing custom plugins, it is mandatory to work with a PHP namespace. This will help prevent class conflicts with all your plugins.
Before defining class namespace, we first need to update the file names of the given default configuration files stored inside the resources/config
directory of our custom plugin based on the config
plugin property we just set.
The resources/config
folder stores by default those 2 files:
Based on our example, we will rename those files like so:
Open your renamed tld_domain_plugin_loading.config.php
file and set the PHP namespace and paths for the pre-defined service providers and controllers like so (still based on our example):
return [
'Com\\Themosis\\Documentation\\Services\\' => themosis_path('plugin.com.themosis.documentation.resources').'providers',
'Com\\Themosis\\Documentation\\Controllers\\' => themosis_path('plugin.com.themosis.documentation.resources').'controllers'
];
The paths contains the plugin
namespace
string defined on your plugin root file inside the$vars
variable. Make sure to correctly define it here as well.
Open your renamed tld_domain_plugin_providers.config.php
file and update the default RoutingService class namespace. Base on our example, the default Tld\Domain\Plugin\Services\RoutingService::class
would be:
return [
Com\Themosis\Dcumentation\Services\RoutingService::class
];
As a last step, the plugin boilerplate comes with a sample controller class and a default RoutingService to refactor:
Sample.php
controller file stored in the resources/controllers
directory.tld_domain_plugin_loading.config.php
file. In our example the namespace would be namespace Com\Themosis\Documentation\Controllers;
The Sample
controller is there to give an example of a properly defined controller to use inside your plugin. We recommend you to rename the Sample
class controller for your needs.
The default RoutingService class, stored inside the resources/providers
directory, loads the plugin resources/routes.php
file for you and define its controllers namespace and path. Update the route namespace and path placeholders with your previously defined namespace from your tld_domain_plugin_loading.config.php
and plugin root files. Based on our example, the service register()
method would look like this:
public function register()
{
Route::group([
'namespace' => 'Com\Themosis\Documentation\Controllers'
], function () {
require themosis_path('plugin.com.themosis.documentation.resources').'routes.php';
});
}
You now have a fully configured custom plugin. From the WordPress administration, active your custom plugin and start developing your custom features.
You can define default routes from your plugin routes.php
file. This is useful for example if you would like to provide default views/templates without the need for the theme to handle them.
The theme routes.php
file can override routes defined inside the plugin. This behavior lets a theme developer customize the template.
Default plugin views are stored inside its resources/views
directory. Imagine the following scenario where your plugin stores those 2 views:
Now if your theme also has similar views stored in its resources/views
directory:
What would be the result?
If a theme calls its view like so: view(store.shop)
, it's the plugin view that is returned and not the one stored inside the theme. In order to avoid view conflicts, we recommend you to "namespace" your plugin views directory like so:
resources/views/
+-- tld/
+-- domain/
+-- plugin/
+-- layouts/
| +-- main.twig
+-- store/
| +-- shop.twig
Creating sub-folders using your domain name, tld extension and plugin name prevent any conflicts between plugins and theme views. So based on our example, our themosis-documentation
plugin would call its view like so: view('com.themosis.documentation.store.shop');
Since it is mandatory to use PHP namespace for all plugin classes, you can't call directly the Themosis framework facades like inside the theme admin
files. In order to use the APIs provided by the framework, you first need to import it.
For example, let's image that we want to define a custom post type of books
from our plugin resources/admin/plugin.php
default file, we would need to code it like so:
<?php
use Themosis\Facades\PostType;
PostType::make('books', 'Books', 'Book')->set();
This is also similar from "namespaced" classes of your custom theme.
Here is a list of available facades you can import:
Made in Belgium