Thanks for that. I’ve rolled my own class-based solution mainly to make use of psr-4 autoloading in app/
, so no need to register the filters/files manually. For anybody else interested in removing soberwp/controller
, but still after a more OOP approach…
Update Sage’s template_include
filter in filters.php to:
/**
* Render page using Blade
*/
add_filter('template_include', function ($template) {
$data = collect(get_body_class())->reduce(function ($data, $class) use ($template) {
// Initialise the data injector if it exists:
$injector_class = __NAMESPACE__ . '\Injectors\\' . str_replace('-', '', ucwords($class, '-'));
if ( class_exists($injector_class) ) {
if ( ! is_subclass_of( $injector_class, Injectors\AbstractInjector::class ) ) {
throw new \Exception("The injector class must extend '" . Injectors\AbstractInjector::class . "'.");
}
$injector = sage()->makeWith($injector_class, ['data' => $data]);
$injector->run();
$data = $injector->getAll();
}
// Apply Sage's default filters:
$template = apply_filters("sage/template/{$class}/data", $data, $template);
// Return the template
return $template;
}, []);
if ($template) {
echo template($template, $data);
return get_stylesheet_directory().'/index.php';
}
return $template;
}, PHP_INT_MAX);
Create the AbstractInjector.php
class inside app/Injectors
directory:
<?php // app/Injectors/AbstractInjector.php
namespace App\Injectors;
abstract class AbstractInjector
{
protected $data = [];
/**
* Create a new AbstractInjector
*
* @param array $data
*/
public function __construct( array $data = [] )
{
$this->data = $data;
}
/**
* Run the AbstractInjector
*
* @return void
*/
abstract public function run();
/**
* Set a data key => value
*
* @param string $key
* @param mixed $val
* @return void
*/
protected function set( string $key, $val )
{
$this->data[ $key ] = $val;
}
/**
* Get a single data value
*
* @param string $key
* @return mixed
*/
public function get( string $key )
{
return isset( $this->data[ $key ] ) ? $this->data[ $key ] : null;
}
/**
* Get all data
*
* @return array
*/
public function getAll(): array
{
return $this->data;
}
}
Create your data Injector classes (also inside app/Injectors
directory):
i.e. where Single
provides data to the resources/views/single.blade.php
template (snake-case to CamelCase, as with controllers).
<?php // app/Injectors/Single.php
namespace App\Injectors;
use App\Injectors\AbstractInjector;
class Single extends AbstractInjector
{
public function __construct()
{
// We can also utilise the container's dependency injection here...
}
public function run()
{
// Set your view data...
$this->set( 'header_image', get_field('img') );
$this->set( 'text', 'Lorem Ipsum Dolor Sit Amet' );
}
}
Here’s hoping the next Sage iteration has a slightly more stable Controller included.