{{craftSnippets}}
Home Articles Plugins Starter theme Components on Github Gists About
  • Home
  • Articles
  • Using template hooks in Craft CMS
Posted on Jan 17, 2021 by Piotr Pogorzelski

Using template hooks in Craft CMS

Template hooks can be used to inject content into various places of the control panel to enhance its functionality
Table of contents:
  • Template hooks
  • Injecting content into template hooks
  • Example use - Freeform related elements
  • Useful links

In Using template UI elements to extend Craft CMS control panel article, I talked about enhancing control with UI elements. While useful, UI elements can be added only into field layouts. In this article, I will describe template hooks which are more versatile.

Template hooks #

Template hooks are Twig tags that can have content injected into them using PHP code. While you could potentially add hooks to your own templates, their main power lies in injecting content into layouts made by other people - into the control panel or interface of plugins. Here's an example hook used by Craft control panel template, placed in the sidebar of "edit entry" page. This specific hook is located in templates\entries_edit.html file:

{% hook 'cp.entries.edit.meta' %}

Plugins sometimes use template hooks to inject their functionality into the control panel. For example, seomatic SEO preview is injected into entry edit page that way.

You can find list of control panel hooks on Template Hooks page in Craft documentation. Craft Commerce also has many template hooks, listed in its documentation. Plugins sometimes have template hooks that are not documented - you can easily find them by searching for hook in their source code.

Injecting content into template hooks #

Time to use hooks in practice. Place this code into your main module file init() method:

Craft::$app->view->hook('cp.entries.edit.meta', function(array &$context) {
    return '<p>Hello there.</p>';
});

This will make "Hello there." appear in entry edit page sidebar. Now, how about using Twig template to render content and append it to hook?

Craft::$app->getView()->hook('cp.entries.edit.meta', function(array &$context) {
    $templatePath = 'some_template';
    $context['someVariable'] = 'xyz';
    $html = Craft::$app->view->renderTemplate(
        $templatePath, $context, Craft::$app->view::TEMPLATE_MODE_SITE
    );
    return $html;
});

This will take some_template Twig file from our templates directory, render it and inject content into hook. Note that we passed $context variable to our rendering function (and even added a new someVariable to it) - now some_template will have access to all variables available in template where hook tag was used. In our case, we will be able to use {{entry}} variable.

If we want to place our template not in templates directory, but in our module directory, we need to register new template root. Put this code in module init() method:

\yii\base\Event::on(
    \craft\web\View::class,
    \craft\web\View::EVENT_REGISTER_SITE_TEMPLATE_ROOTS,
    function(\craft\events\RegisterTemplateRootsEvent $event) {
        $event->roots['customHandle'] = __DIR__ . '/custom_templates';
    }
);

Now you will be able to include Twig files placed in custom_templates directory that lives within your module - just use customHandle prefix when specifying their path. With our example, you should use customHandle/some_template path. Keep in mind that unlike modules, plugins have their template roots already defined - prefix is set to plugin handle.

Example use - Freeform related elements #

Here's an example use of template hooks functionality. Freeform plugin allows us to relate elements to form submissions. For example, when we have a form on some kind of product page, visitors can ask questions about this specific product - and form submission will be related to that product in the database.

The problem is, that Freeform does not display these related elements on submission page in control panel. It only allows for displaying related submissions on the entry page - so other way around. We can easily add this missing functionality to Freeform interface using template hooks.

Here's our Twig template:

{% set relatedElements = craft.entries.relatedTo(submission).all() %}
{% if relatedElements is not null %}
<div class="meta read-only">
<strong>Related elements:</strong>
<br>
{% for element in relatedElements %}
    <a href="{{element.getCpEditUrl()}}">{{element.title}}</a>
    <br>        
{% endfor %}
</div>
{% endif %}

As you can see, we use submission variable representing a single submission element and loop through related entries (we could also do the same for categories, or other elements). submission variable is available in the context of the template that has hook we are injecting content into.

Time to inject content into hook. We will use freeform.submissions.edit.meta that will inject content into the submission page sidebar. This hook actually is not documented - I found it by searching through freeform templates code.

Craft::$app->getView()->hook('freeform.submissions.edit.meta', function(array &$context) {
    $cart_template = '_admin/freeform_related';
    $html = Craft::$app->view->renderTemplate(
        $cart_template, $context, Craft::$app->view::TEMPLATE_MODE_SITE
    );
    return $html;
});

Here's the result. Injected content is sitting in a gray box which is styled thanks to use of meta and read-only classes, which were already used by control panel styling.

Useful links #

  • Craft CMS - template hooks
  • Craft Commerce - template hooks

TAGS:
#modules
If you want to get latest updates on Craft CMS tutorials and components, follow me on Twitter or subscribe to RSS feed.
Articles on blog:
  • Building reactive Craft Commerce product page with Sprig plugin
  • Dynamically generated PDF attachments for Freeform submissions
  • Using template hooks in Craft CMS
  • Alpine JS modal component for Craft CMS
  • Using template UI elements to extend Craft CMS control panel
  • Matrix within a Matrix - possible solutions for Craft CMS
  • Universal email template for Craft CMS
  • Creating attributes table from entry fields in Craft CMS
  • Namespacing forms in Craft CMS
  • Creating map-based navigation for Craft CMS
  • Placeholder image macro for Craft CMS
  • Building AJAX contact form with Craft CMS
  • Using incognito field plugin for Craft CMS
  • Email footer creator made with Craft CMS
  • Infinite scrolling and lazy loading with Craft CMS
  • Using Javascript in Twig templates with Craft CMS
  • Twig templating tips and tricks for Craft CMS
  • Basic SEO functionality for Craft CMS
  • Working with dates in Craft CMS templates
  • Working with SVG images in Craft CMS templates
  • Responsive and lazy-loaded youtube videos with Craft CMS
  • Debugging and inspecting Twig templates in Craft CMS
  • Creating article excerpts with Twig component in Craft CMS
  • Adding favicons to Craft CMS website
  • Truncating text with Twig macros in Craft CMS
  • Universal language switcher for Craft CMS
  • Read time macro for Craft CMS
  • Using attr() function to render HTML attributes in Craft CMS
  • Building dynamic, AJAX based pagination for Craft CMS
  • How to add Disqus comments to Craft CMS website
  • Ellipsis pagination component for Craft CMS
  • Converting email addresses into links using Twig macro
  • Breadcrumb created from URL for Craft CMS
  • Best developer-oriented Craft CMS plugins
  • Search autocomplete component for Craft CMS
  • RSS feed - template component for Craft CMS
  • Testing emails sent by Craft CMS using Mailtrap
  • Quick edit link - Twig component for Craft CMS
  • Filtering entries in control panel using Searchit plugin
  • Fetching routes into Twig templates in Craft CMS


Building reactive Craft Commerce product page with Sprig plugin

Dynamically generated PDF attachments for Freeform submissions

Alpine JS modal component for Craft CMS

Using template UI elements to extend Craft CMS control panel

Matrix within a Matrix - possible solutions for Craft CMS

Universal email template for Craft CMS

Creating attributes table from entry fields in Craft CMS

Namespacing forms in Craft CMS

Copyright ©2022 Piotr Pogorzelski