Kick start your Disciple.Tools plugin project with this template!
This plugin is a modern, opinionated plugin starter template inspired by Laravel.
Tip: You can safely delete this README.md file and replace it with your own. You can always view this readme at github.com/thecodezone/dt-oikos.
At CodeZone, we recognize a developer or team might love Disciple.Tools, but miss the modern tooling found in PHP Application frameworks.
There growing community of Laravel and Symfony developers who bring exceptional expertise to the table.
Our purpose is to bridge the gap between these seasoned developers and the dynamic environment of Disciple.Tools. We strive to make Disciple.Tools plugin development not only accessible but also a delightful experience for those already well-versed in Laravel and Symfony frameworks.
Are you a WordPress developer? You may feel more at home using the Disciple Tools Starter Template.
- WordPress code style requirements.
phpcs.xml
- PHP Code Sniffer support (composer) @use
/vendor/bin/phpcs
and/vendor/bin/phpcbf
- GitHub Actions Continuous Integration
.githbub/workflows/ci.yml
- Disciple.Tools Theme presence check.
\DT\Test\plugin()->is_dt_theme();
- Remote upgrade system for ongoing updates outside the Wordpress Directory.
- Multilingual support.
/languages
&default.pot
- Composer support.
composer.json
- Scoped dependency autoloading using PHPScoper.
/composer.scoped.json
- Laravel-style service providers.
/src/Providers
- Laravel-style controllers.
/src/Controllers
- Vite build system.
/vite.config.js
&/resources/js
- Inversion of control container
using Laravel's Service Container.
/src/Container.php
- Routing system using FastRoute.
/routes/web.php
- Conditional routes, route groups, and request middleware provided by CodeZone Router.
- View layouts, partials, and escaping provided by the plain PHP templating engine, Plates.
- Validation provided by Laravel's Validation.
- Sample admin menu and admin page with starter tabs component.
- Sample custom post type.
- Sample REST api.
- Sample magic link.
Tip: This starter plugin does not attempt to provide every component provided by the Disciple Tools Starter Template. See the Disciple Tools Starter Template for implementation examples of charts, tiles and other components.
- Run
composer install
to install PHP dependencies. - Run
npm install
to install JS dependencies. - Run
npm run dev
to compile assets for development. - Open the WordPress admin and activate your plugin.
This plugin uses Composer to manage dependencies. The plugin's dependencies are scoped to
your plugin's namespace. This means you can use any package you want without worrying about conflicts with other
plugins. For example, if you want to use the Guzzle HTTP client, you can simply
add it to your composer.scoped.json
file, instead of the composer.json
file.
Guzzle would then be installed in the vendor-scoped
directory, instead of the vendor
directory. This allows you to
use Guzzle without worrying about conflicts with other plugins that may also use Guzzle.
See PHPScoper for more information.
WordPress's Internationalization functionality and Weblate via translate.disciple.tools are used to provide multilingual support.
Hard-coded strings should be wrapped in the __()
function. For example:
__( 'Hello World!', 'dt-oikos' );
Service providers are used to register services into the
plugin's inversion of control container or with
Disciple.Tools. Service providers are located in the src/Providers
directory. The register()
method is called when
the plugin is first loaded. The boot()
method is called after the theme have been loaded.
Register new service providers in /src/Providers/PluginServiceProvider.php
.
namespace DT\Test\Providers;
use DT\Test\Plugin;
class ExampleServiceProvider extends ServiceProvider
{
/**
* Called when the plugin is first loaded.
*
* @return void
*/
public function register()
{
// Register a service into the plugin's container.
$this->container->bind( 'example', function () {
return new Example();
} );
add_filter( 'some/filter', function () {
//some filter
});
}
/**
* Called when the theme is loaded.
*
* @return void
*/
public function boot()
{
add_action( 'some/action', function () {
//Some action
});
}
}
Routing is handled by CodeZone Router. Routes are located in
the routes/web
file. Read more about routing in the CodeZone Router
documentation.
Controllers are located in the src/Controllers
directory. Controllers are responsible for handling requests and
returning responses. Controllers are basic PHP classes with no parent class or base controller. Controllers are resolved
from the container using the controller's fully qualified class name. Controllers can be resolved from the container to
make use of automatic dependency injection.
Tip: Keep your controllers thin. Business logic should be moved to services. Controllers should only be responsible for handling requests and returning responses. Anything more than basic logic should be moved to a service.
The Illuminate validator can be used to validate requests. See Laravel Rules.
<?php
namespace DT\Oikos\Controllers\Admin;
use DT\Oikos\Illuminate\Http\RedirectResponse;
use DT\Oikos\Illuminate\Http\Request;
use DT\Oikos\Illuminate\Http\Response;
use function DT\Oikos\transaction;
use function DT\Oikos\validate;
use function DT\Oikos\view;
class ExampleController {
/**
* A GET route should map to this method via [ExampleController::class, 'show'].
*/
public function show( Request $request, Response $response ) {
return view( "example", [
'option1' => get_option( 'option1' ),
'option2' => get_option( 'option2' ),
] );
}
/**
* A POST route should map to this method via [ExampleController::class, 'update'].
*/
public function update( Request $request, Response $response ) {
$error = false;
// Add the settings update code here
$errors = validate( $request->all(), [
'option1' => 'required',
'option2' => 'required',
] );
if ( count( $errors ) > 0 ) {
$error = __( 'Please complete the required fields.', 'dt-oikos' );
}
if ( ! $error ) {
//Perform update in a MYSQL transaction
$result = transaction( function () use ( $request ) {
set_option( 'option1', $request->post( 'option1' ) );
set_option( 'option2', $request->post( 'option2' ) );
} );
if ( $result !== true ) {
$error = __( 'The form could not be submitted.', 'dt-oikos' );
}
}
if ( $error ) {
return new RedirectResponse( 302, admin_url(
'/dt/oikos/example/?' . http_build_query( [
'error' => $error,
'fields' => $errors,
] )
)
);
}
return new RedirectResponse( 302, admin_url( '/dt/oikos/example/?&updated=true' ) );
}
}
Templating is provided by the plain PHP templating engine, Plates.
The template service located at src/Services/Template.php
is used to bootstrap a blank template for your plugin.
Routes are mapped to controllers which load basic PHP templates from the resources/views
directory.
Tip: Be sure to use WordPress escaping functions when outputting data in your templates. See Data Validation for more information.
use DT\Test\view;
template( 'hello', [
'name' => 'World',
] );
use DT\Test\view;
view( 'hello', [
'name' => 'World',
] );
A basic user-based magic link is provided. See
the DT starter plugin template
for more examples, like contact and object magic links. To utilize magic links, you must first uncomment the magic link
service provider in the providers
array in /src/Providers/PluginServiceProvider
.
protected $providers = [
ViewServiceProvider::class,
ConditionsServiceProvider::class,
MiddlewareServiceProvider::class,
//AdminServiceProvider::class,
//PostTypeServiceProvider::class,
MagicLinkServiceProvider::class,
RouterServiceProvider::class,
];
A dt post type is included. To utilize post types, you must first uncomment the post type service provider in
the providers
array in /src/Providers/PluginServiceProvider
.
protected $providers = [
ViewServiceProvider::class,
ConditionsServiceProvider::class,
MiddlewareServiceProvider::class,
//AdminServiceProvider::class,
PostTypeServiceProvider::class,
//MagicLinkServiceProvider::class,
RouterServiceProvider::class,
];
PHP_CodeSniffer (phpcs
) is used for static code analysis
and PHP_CodeSniffer Beautifier (phpcbf
)
for automatic code formatting. Before committing your code, run the following commands to check and fix coding
standards:
/vendor/bin/phpcs
/vendor/bin/phpcbf
PHP_CodeSniffer and Beautifier work best when integrated with your IDE. See PHPSTORM and VSCode for more information.
This plugin uses PHPUnit for testing. Tests are located in the test
directory.
Before running tests you must install a local version of WordPress to test against using tests/install-wp-tests.sh
.
Here is an example using ddev database credentials:
- Create an empty database for testing.
ddev mysql;
create database testing;
exit;
-
Run
ddev describe
to get your database credentials. -
Run the
tests/install-wp-tests.sh
script with your ddev database credentials.
tests/install-wp-tests.sh testing db db 127.0.0.1:32770
- Run the tests.
vendor/bin/phpunit
Note Phpunit 10.0.0 is not compatible with WP testing. PHPUnit 9 is installed as a dependency. If you would rather use your global PHPUnit, make sure to use version 9 or below.
/**
* @test
*/
public function example_http_test() {
$response = $this->post( 'dt/oikos/api/page', ['someField' => 'value'], [
'X-WP-Nonce' => wp_create_nonce( 'dt_oikos' ),
] );
$this->assertEquals( 200, $response->getStatusCode() );
}
- Disciple.Tools Theme installed on a local Wordpress Server DDEV or localwp.com.
Contributions welcome. You can report issues and bugs in the Issues section of the repo. You can present ideas in the Discussions section of the repo. And code contributions are welcome using the Pull Request system for git. For a more details on contribution see the contribution guidelines.