td / framework
10 Degrees base theme and plugin framework
Requires
- php: ^7.3|^8.0
- erusev/parsedown: ^1.7
- illuminate/container: ^8.33
- illuminate/filesystem: ^8.33
- illuminate/http: ^8.33
- illuminate/support: ^8.33
- jgrossi/corcel: ^5.0
- johnbillion/extended-cpts: ^4.5
- symfony/finder: ^5.2
This package is auto-updated.
Last update: 2025-11-12 00:43:23 UTC
README
The 10 Degrees framwork is a collection of components to streamline development.
The framework has a namespaced wp-cli command and a set of frequently used commands.
Installation
composer require td/framework
Components
Acf
Blocks
Advanced Custom Fields service provider and commands.
Make a Block located in the app/Acf/Blocks directory.
wp td make:block BlockName
Then add the block classname to the $blocks property in the AcfServiceProvider. The block will be loaded by the provider.
Field Groups
Make a FieldGroup located in the app/Acf/FieldGroups directory.
wp td make:field-group FieldGroupName
Then add the field group classname to the $fieldGroups property in the AcfServiceProvider. The field group will be loaded by the provider.
Console
The Console component is the core command service which is used for all the make commands in the framework.
Foundation
The foundation components includes the base application and core framework services and commands.
The Mailer class provides a fluent interface for writing emails.
Make a Mail located in the app/Mail directory.
wp td make:mail UserRegistered
The mailer class provides a constructor to pass arguments to the class, and a build method to construct the mail.
The build method should have the non-changeable logic, such as the email subject and the template. When you call the mailable, you can add email specific properties such as the to, cc, bcc addresses.
<?php
namespace App\Mail;
use TenDegrees\Mail\Mailer;
class UserRegistered extends Mailer
{
/**
* The registration pdf file path
*
* @var string
*/
protected $attachment;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(string $attachment)
{
$this->attachment = $attachment;
}
/**
* Build the message.
*
* @return \TenDegrees\Mail\Mailer
*/
public function build(): Mailer
{
return $this->from('support@10degrees.uk')
->subject('Thanks for registering')
->attachment($this->attachment)
->markdown('emails.registered');
}
}
You can send mails once the wp_mail function is loaded, so you should wrap Mail classes with an add_action('init') to ensure the function is available.
<?php
use App\Mail\UserRegistered;
use Tendegrees\Database\Models\User;
use Tendegrees\Support\Facades\Mail;
use WP_User;
// pass an email string:
Mail::to('email@example.com')->send(new UserRegistered());
Mail::to('Name <email@example.com>')->send(new UserRegistered());
// pass a WP_User instance:
Mail::to(wp_get_current_user())->send(new UserRegistered());
// pass a User model instance
Mail::to(User::find(1))->send(new UserRegistered());
// you can test your emails by using the render method.
echo Mail::render(new UserRegistered());
The to, cc, and bcc methods are versatile, accepting the following:
- a string
- a WP_User instance
- a User instance
- an array of the above
- a collection of the above
Routing
Routes are defined in the routes/ajax.php or routes/api.php files.
AJAX routes are defined with the ajax method. $uri refers to the "action" parameter. $action parameter is the Closure or Controller classname.
Route::ajax($uri, $action);
For example:
// wp-admin/admin-ajax.php?action=ajax_action
Route::ajax('ajax_action', function () {
return td_view('ajax.view');
});
REST routes are defined with the methods get, post, put, patch, delete, options, any or matches. The $uri is the REST endpoint (without the namespace) and $action is the Closure or Controller classname
// Standard HTTP methods
Route::get($uri, $action);
Route::post($uri, $action);
Route::put($uri, $action);
Route::patch($uri, $action);
Route::delete($uri, $action);
Route::options($uri, $action);
// or you can specify any:
Route::any($uri, $action); // GET, HEAD', POST, PUT, PATCH, DELETE, OPTIONS
// or you can match certain methods:
Route::matches(['PUT', 'PATCH'], $uri, $action)
For example:
// wp-json/api/rest/action
Route::get('rest/action', function () {
return ['data' => []];
});
REST URIs are parsed to allow for parameters to be passed:
Route::get('users/{id}', function(int $id) {
return (new WP_User($id))->to_array();
});
Route Actions
Route "actions" can be either a closure:
Route::ajax('ajax_action', function () {
return td_view('ajax.view');
});
...or a Controller:
Route::ajax('ajax_action', AjaxActionController::class); // will use the __invoke method
Specific methods can be defined:
Route::ajax('ajax_action', [AjaxActionController::class, 'index']);
Controllers 🚧
Make a Controller located in the app/Http/Controllers directory.
wp td make:controller LoginController
AJAX and REST controllers are the same
Middleware 🚧
Make a Middleware located in the app/Http/Middleware directory.
wp td make:middleware VerifyApiKey
UrlGenerator
The URLGenerator class brings together many WordPress URL functions into one api, that can be used with the URL facade.
URL::home() // https://example.com
URL::to('members') // https://example.com/members
URL::login() // https://example.com/wp-login.php?redirect_to=%2F
URL::logout() // https://example.com/wp-login.php?action=logout&redirect_to=%2F&_wpnonce=dd5186a703
URL::register() // https://example.com/wp-login.php?action=register
URL::ajax('ajax_action') // https://example.com/wp-admin/admin-ajax.php?action=ajax_action
URL::admin() // https://example.com/wp-admin/
URL::rest('api/rest-action') // https://example.com/wp-json/api/rest-action
URL::redirect('/') // wp_redirect(); die();
URL::current()
URL::full()
URL::previous()
URL::isValidUrl('https://example.com')
Support 🚧
Support includes the ServiceProvider, Pipeline and Facades.
View
A view class to easily include templates. Views are stored in the views directory.
The View::make method accepts a path relative from the views directory, this can use dots to denote directories E.g.
/views/posts/single.php would be posts.single.
The second argument is an optional array that will be extracted into the template.
$post = get_post(1);
echo View::make('posts.single', compact('post'));
<!-- /views/posts/single.php -->
<h1><?php echo $post->post_title; ?></h1>
WordPress 🚧
WordPress service provider and commands.
Make a PostType located in the app/WordPress/PostTypes directory.
wp td make:post-type PostTypeName
Make a Shortcode located in the app/WordPress/Shortcodes directory.
wp td make:shortcode ShortcodeName