0

I want to add a record do theme_hook_suggestions variable but only when specific conditions are met, especially when system is going to use a specific template in theme. In effect I want to replace one template with other.

I.e. - when user sees node with id = 50 and view mode == teaser and user has set some specific parameters system should use template node-special.tpl.php. In any other condition system should use base template node-50.tpl.php

I cannot do this, as far as I understand, in any *preprocess or *process functions basing on variables because there is no information available about what template are candidate for use.

How can I achieve this?

EDIT, more detailed explanation:

I'm trying to build a A/B testing system for e-commerce site I run. I want to set a A/B test where for selected base template a new variant will be defined and for chosen group of users this new variant will be used. I want to have a universal solution where I could configure this just by one line of code. It should work both for nodes, fields, blocks, pages templates. I just simply need to substitute one template field with another.

ie I want to have a universal config:

$ABconfig = array(
        'ABbigrelated' => array( //test name
                'basetemplate' => 'related-nodes', //base template
                'newtemplate' => 'related-nodes-bigimages', //new template
                'GAdimensions'  =>  'dimension2' //config for googleanalitics

        )
);
3
  • What makes you think you can't do it in a preprocess_node ? That's the first place I would try doing it.
    – 2pha
    Commented Jun 14, 2016 at 16:51
  • @2pha I don't see how in any *process function get information about current hook suggestions. If know how to get this information just give me a hint Commented Jun 14, 2016 at 16:57
  • ? you want to add your own suggestion? or use one of the standard ones? link link
    – 2pha
    Commented Jun 14, 2016 at 17:03

1 Answer 1

1

You can alter the list of template suggestions in your preprocess hook:

function drop_preprocess(&$variables) {
  $variant = drop_get_variant_for_current_user($variables);
  if ($variant) {
    $suggestions = array();
    foreach ($variables['theme_hook_suggestions'] as $suggestion) {
      $suggestions[] = $suggestion
      $suggestions[] = $suggestion . '--' . $variant;
    }
    $variables['theme_hook_suggestions'] = $suggestions;
  }
}

This will add templates variants for all theme hook. So for instance, this allow you to override the node.tpl.php and page.tpl.php templates with node--special.tpl.php and page--special.tpl.php ones (when drop_get_variant_for_current_user() returns 'special'. If the template for a variant does not exists, it will simply be ignored.

Note that the order of suggestions is preserved. If you have three specialized node templates: node.tpl.php, node--special.tpl.php and node-article.tpl.php (the default one, the 'special' variant and the template for article nodes), when rendering an article node, the 'node-article.tpl.php' will be used since 'node_article' will be after both 'node' and 'node__special' in $variables['theme_hook_suggestions'].

Because it will run for all templates used on the page, the use a static cache in get_variant_for_current_user() so the actual variant won't be computed again and again for the same request/template.

Update:

  • The exact used template with be the last one in $variables['theme_hook_suggestions'] for which a template file exits. For instance if $variables['theme_hook_suggestions'] == array('node', 'node--special', 'node-article', 'node-article--special'), but only the node.tpl.php, node-article.tpl.php and node--special.tpl.php files exist, then node--special.tpl.php will be used.
  • The drop_get_variant_template() function is the one where you put your variant selection logic (and that has to be written).
5
  • Thanks, for answer it essencially address what I described. But I wasn't fully clear in my question. Commented Jun 14, 2016 at 19:15
  • I'm looking for something more general or universal. I'm trying to build a A/B testing system for e-commerce site I run. I want to set a A/B test where for selected base template a new variant will be defined and for chosen group of users this new variant will be used. I want to have a universal solution where I could configure this just by one line of code. It should work both for nodes, fields, blocks, pages templates. I just simply need to substitute one template field with another. Commented Jun 14, 2016 at 19:25
  • I updated the answer with what should be a suitable solution to alter the suggestions for all templates. Commented Jun 15, 2016 at 13:37
  • thanks for the update but it didn't address main issue - how to know which onexactly template file will be used. Those drop_get_variant_template is an existing function? Commented Jun 25, 2016 at 18:23
  • The exact used template with be the last one in $variables['theme_hook_suggestions'] for which a template file exits. The drop_get_variant_template() function is supposed to be the one where you put your variant selection logic. Commented Jun 26, 2016 at 19:05

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.