A simple template hook system for SilverStripe.
Sometimes extending / overriding a template is not enough or would produce a lot of duplicate markup. Maybe you just want to inject some markup at a specific point in your template file. This is where template hooks come into play.
With template hooks, you can add named "injection points" everywhere in your SilverStripe template files and hook into them from within your Controllers or DataObjects.
- silverstripe/framework 3.1+
$ composer require memdev/silverstripe-templatehooks
You'll need to do a flush by appending ?flush=1
to your site's URL.
To add a hook point to your template, simply call $TemplateHook()
, providing a name for this hook as the first parameter:
<div>
<nav class="primary">
<span class="nav-open-button">²</span>
<ul>
<% loop $Menu(1) %>
<li class="$LinkingMode"><a href="$Link" title="$Title.XML">$MenuTitle.XML</a></li>
<% end_loop %>
$TemplateHook('MainNavigation')
</ul>
</nav>
$TemplateHook('AfterMainNavigation')
</div>
You can subscribe to this hook by calling hookInto()
in your Controller or DataObject:
class Page_Controller extends ContentController implements TemplateHooks {
/**
* Use this method to globally subscribe to template hooks.
* If you wish to subscribe to hooks in the current controller / object scope,
* call "hookInto()" from within any other method, e.g. the controllers init() method.
*/
public function initHooks()
{
$this->hookInto('MainNavigation', function($hook) {
return SSViewer::execute_template('MyNavigationAppendix', array());
});
}
public function init() {
parent::init();
$this->hookInto('AfterMainNavigation', array($this, 'AfterMainNavigationHook'));
// OR
$self = $this;
$this->hookInto('AfterMainNavigation', function($hook) use ($self) {
return "You are currently reading page {$self->Title}";
});
}
public function AfterMainNavigationHook($hook) {
return "You are currently reading page {$this->Title}";
}
}
You can also pass parameters with the template hook:
<% loop $Menu(1) %>
<li class="$LinkingMode">
<a href="$Link" title="$Title.XML">
$TemplateHook('MainNavItem', $ID)
$MenuTitle.XML
</a>
</li>
<% end_loop %>
It will be available in your subscriber function:
$this->hookInto('MainNavItem', function($hook, $id) {
$page = Page::get()->byID($id);
// your code here
}
TODO
Please create an issue for any bugs you've found, or features you're missing.