1

In Drupal 8:

I have custom module code that declares its own theme can twig template. How do I make module variables available to my Drupal theme's page.html.twig?

I have tried various preprocess_page* functions; however, those functions don't see the variables the module is passing to it's own themed twig templates.

Can the module's controller inject something into the page variables?

Can a Drupal theme's preprocess functions access some variables flowing from a custom module to the module's twig templates?

The controller file:

class PromtController extends ControllerBase
{
    public function program($id)
    {
        $program = PromtService::program((int)$id);

        return [
            '#theme'   => 'promt_program',
            '#program' => $program,
            '#title'   => $program['title']
        ];
    }
}

The module code:

function promt_theme()
{
    return [
        'promt_program' => [
            'template' => 'promt_program',
            'variables' => [
                'program' => null
            ]
        ]
    ];
}
2
  • Normally, the hook_preprocess_page() implementation would appear in your .module file, the same file where you implemented hook_theme().
    – rjl
    May 11, 2017 at 20:19
  • The hook_preprocess_page() function; however, does not seem to have access to the programs variable being passed from the controller to the theme. I need to inspect the programs variable I'm passing in, in order to pull out phone numbers, etc to add as contact information in page.html.twig. Either hook_preprocess_page() needs to be able to find that variable some where in &$vars[] or the controller needs to pass it in, in a special way, such that it becomes part of the page array. May 12, 2017 at 13:47

1 Answer 1

1

As far as I can tell, this should be handled in the custom theme, not in the custom module. This is because the module really has no idea how a custom theme wants to render stuff.

In any case, in the custom theme, the only way I can figure out how to make the data available is to register a hook_preprocess() function in the theme, check the hook that's called, and declare a static variable that sticks around until it can be injected later on.

The custom module's "promt_program" hook will be called earlier than the theme's "page" hook. I'm pretty sure that will always be true. So, we grab the location_id and then inject it later on.

This preprocess function will get called many, many times, so it seems important to make it thin.

function cob_preprocess(&$vars, $hook)
{
    static $location_id = null;

    switch ($hook) {
        case 'promt_program':
            if (!empty($vars['program']['location_id'])) { $location_id = $vars['program']['location_id']; }
        break;

        case 'page':
            if ($location_id) {
                $query = \Drupal::entityQuery('node')
                    ->condition('status', 1)
                    ->condition('type', 'location')
                    ->condition('field_promt_id', $location_id);
                $nids  = $query->execute();
                if ($nids) {
                    $vars['node'] = \Drupal::entityTypeManager()->getStorage('node')->load(current($nids));
                }
            }
        break;
    }
}

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.