3

Let's say I create a function in a module file:

function _get_test() {
  return 'test';
}

How can I call this in any Twig file? For example *.html.twig, page.html.twig, node.html.twig etc.

OR

How can I pass a variable from PHP to Twig and display in any Twig file. For example *.html.twig, page.html.twig, node.html.twig etc.

0

2 Answers 2

9

You can define your own custom Twig functions in a custom module (but not in a theme). To find an example for how to do this, see this example in core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php.


Also see this blog post: Create Twig extensions for Drupal 8.

In this example, we will build an extension to display a Drupal block directly in a Twig template:

{{ display_block('my_block_id') }}

src/MyTwigExtension.php

<?php

namespace Drupal\MyTwigModule;

/**
 * Class DefaultService.
 *
 * @package Drupal\MyTwigModule
 */
class MyTwigExtension extends \Twig_Extension {

  /**
   * {@inheritdoc}
   * This function must return the name of the extension. It must be unique.
   */
  public function getName() {
    return 'block_display';
  }

  /**
   * In this function we can declare the extension function
   */
  public function getFunctions() {
    return array(
      new \Twig_SimpleFunction('display_block', 
        array($this, 'display_block'),
        array('is_safe' => array('html')
      )),
  }

  /**
   * The php function to load a given block
   */
  public function display_block($block_id) {
    $block = \Drupal\block\Entity\Block::load($block_id);
    return \Drupal::entityManager()->getViewBuilder('block')->view($block);
  }

}

src/MyTwigModule.services.yml

services:
  MyTwigModule.twig.MyTwigExtension:
    class: Drupal\MyTwigModule\MyTwigExtension
    tags:
      - { name: twig.extension }
4

You do not call PHP functions in Twig. You can either create a custom Twig extension (see answer from leymannx) or use the global preprocess

function MYTHEME_preprocess(array &$variables, $hook) {
  //this is a global hook, its variables are available in any template file
  $variables['foo'] = 'bar';
}

{{ foo }} will then render bar, but this global preprocess might run into caching problems though

2
  • It should better be hook_preprocess_HOOK to target a specific template.
    – leymannx
    Commented Oct 30, 2018 at 11:15
  • 2
    @leymannx I'm explicitly using the one without _HOOK suffix as global preprocess, the ones with a specfic _HOOK suffix aren't global
    – Hudri
    Commented Oct 30, 2018 at 11:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.