brain / context
No-dependencies package to provide context to templates based on query.
Requires
- php: >=7.1
- psr/log: ^1 || ^2 || ^3
Requires (Dev)
- brain/monkey: ^2.6.1
- inpsyde/php-coding-standards: ^1@dev
- mockery/mockery: ^1.3.0 || ^1.5.0
- php-stubs/wordpress-stubs: >=5.9@stable
- phpunit/phpunit: ^7.5.20 || ^9.5.13
- vimeo/psalm: ^4.20.0
This package is auto-updated.
Last update: 2024-10-09 20:02:52 UTC
README
Context is package that aims to collect "context" to pass to templates based on a query object.
Best paired with a template engine. And maybe with Hierarchy.
Quick start
Let's assume a couple of classed designed to provide context for the homepage and the singular view, respectively:
use Brain\Context; class HomepageContext implements Context\ProviderFactory { public function create(\WP_Query $query, LoggerInterface $logger): ?Provider { return Context\Provider\ArrayMerge::new(fn() => $query->is_front_page()) ->addProvider(new MyHeroProvider()) ->addProvider(new Context\Provider\Posts(['posts_per_page' => 5], 'latest_posts')); } } class SingularContext implements Context\ProviderFactory { public function create(\WP_Query $query, LoggerInterface $logger): ?Provider { return Context\Provider\ArrayMerge::new(fn() => $query->is_singular()) ->addProvider(new Context\Provider\ByCallback(fn() => ['post' => $query->post])) ->addProvider(new Context\Provider\Comments(['post_id' => $query->post->ID])); } }
Now we can make use of the Context
class to generate the context for our templates:
namespace MyTheme; use Brain\Context; add_action('template_redirect', function () { $context = Context\Context::new() ->withProviderFactory(new HomepageContext()) ->withProviderFactory(new SingularContext()) ->provide(); // pass context to templates here ... });
Context
class emit the action `"brain.context.providers" that can be used to add providers from
different places:
namespace MyTheme; use Brain\Context; add_action('brain.context.providers', function (Context\Context $context) { $context ->withProviderFactory(new HomepageContext()) ->withProviderFactory(new SingularContext()); }); add_action('template_redirect', function () { $context = Context\Context::new()->provide(); // pass context to templates here ... });
Examples using Hierarchy
Here's an example of using context in combination with Brain Hierarchy to render mustache templates passing them context.
namespace My\Theme; use Brain\Hierarchy\{Finder, Loader, QueryTemplate}; use Brain\Context; class MustacheTemplateLoader implements Loader\Loader { private $engine; public function __construct(\Mustache_Engine $engine) { $this->engine = $engine; } public function load(string $templatePath): string { // It will be possible to hook 'brain.context.providers' to add context providers $data = Context\Context::new() ->convertEntitiesToPlainObjects() ->forwardGlobals() ->provide(); return $this->engine->render(file_get_contents($templatePath), $data); } } add_action('template_redirect', function() { if (!QueryTemplate::mainQueryTemplateAllowed()) { return; } $queryTemplate = new QueryTemplate( new Finder\BySubfolder('templates', 'mustache'), new MustacheTemplateLoader(new \Mustache_Engine()) ); $content = $queryTemplate->loadTemplate(null, true, $found); $found and die($content); });
Above is all the necessary code to render *.mustache
templates from a /templates
subfolder
in current theme (or parent theme, if any), according to WP template hierarchy, passing to templates
context data that can be extended via ad-hoc "view context" classes which will implement
Context\ProviderFactory
interface.
Providers
Composite providers
The "Quick start" section above uses Context\Provider\ArrayMerge
class to "merge" several
providers.
Besides that class, there's also a Context\Provider\ArrayMergeRecursive
"composite" provider.
Atomic providers
The "composite" providers merge multiple "atomic" providers that can be either custom (anything
implementing Context\Provider
) or one of the shipped provider classes:
ByArray
- which provides a given array as-isByCallback
- which provides an array returned by a given callbackComments
- which provides an array of comments using given comment query argumentsPosts
- which provides an array of posts using given post query argumentsSubquery
- which provides aWP_Query
instance using given query argumentsTerms
- which provides an array of comments using given taxonomy terms query argumentsUsers
- which provides an array of comments using given user query arguments
Custom providers
The Context\Provider
interface has a single method:
public function provide(\WP_Query $query, LoggerInterface $logger): ?array;
Which can be implemented to build custom providers. In the case the provider should not be used
based on conditions, it can return null
.
The given PSR-3 logger interface can be used to log errors and distinguish a provider that returns
null due to errors form another that returns null
because, for example, not targeting the current
query.
Logger
All providers support a PSR-3 logger. Context
class implements PSR-3 LoggerAwareInterface
, so
it is possible to call setLogger
when instantiating it.
There's also a "brain.context.logger"
action that passes a callback that can be used to set the
logger:
add_action('brain.context.logger', function (callable $setter) { $setter(new MyPsr3Logger()); });
Requirements
Context requires PHP 7.1+ and Composer to be installed.
Installation
Best served by Composer, available on Packagist with name brain/context
.
License
Context is released under MIT.