Skip to content

Using template hooks to enhance Craft CMS

Template hooks allow you to insert a template or some custom CSS or Javascript into a page, for example in the Craft CMS Control Panel.

Find the template hook you need

First up, figure out which template the view you want to insert your template, JS or CSS into is using. For pages in Craft core, you can look in /vendor/craftcms/cms/src/templates.

Say you want to add a custom button to the sidebar for entries of a specific section, you'll need /vendor/craftcms/cms/src/templates/entries/_edit.html and the cp.entries.edit.details hook here.

You can find an overview of all hooks available in Craft here.

Hooking into the hook

In the example below, we're hooking into said entry page, in the sidebar specifically. First, we check if the entry is in the section we're targeting and we return if it's not. Then we render a template and pass the current entry to it.

This code goes into your main module or plugin class.

use Craft;
use yii\base\Exception;

// in public function init()
Craft::$app->view->hook('cp.entries.edit.details', function (array &$context) {
    try {
        $entry = $context['entry'];
        if ($entry->section->handle !== 'events') {
        echo Craft::$app->getView()->renderTemplate(
                'entry' => $context['entry']
    } catch (Exception $e) {
        Craft::error("Error rendering template: {$e->getTraceAsString()}");

Usage example from a real project

One of the reasons I've been using this specific template hook is to make related entries of the entry you're viewing easily exportable. An example:

We have an "Events" section and a "Registrations" section. Registrations belong to an event and contain all the data for said registration. A couple of days before the event, the client wants to make an export of all registrations. Viewing the full list of registrations isn't super useful here, since there's no quick way to just view entries for a specific event.

So we use a template hook to insert a button into the event entry sidebar. That button links to a controller action (to which we pass the entry ID). In the controller, we then get the related registrations, parse them to a preferred file format and return them as a file to be downloaded.

That way, the client can find the registrations with the event itself.

Hope you found this useful, feel free to share the post if you did.

Have suggestions or remarks? Get in touch!