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

        )
);

migrated from stackoverflow.com Jun 16 '16 at 19:41

This question came from our site for professional and enthusiast programmers.

  • What makes you think you can't do it in a preprocess_node ? That's the first place I would try doing it. – 2pha Jun 14 '16 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 – KraggTheGrimm Jun 14 '16 at 16:57
  • ? you want to add your own suggestion? or use one of the standard ones? link link – 2pha Jun 14 '16 at 17:03
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).
  • Thanks, for answer it essencially address what I described. But I wasn't fully clear in my question. – KraggTheGrimm Jun 14 '16 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. – KraggTheGrimm Jun 14 '16 at 19:25
  • I updated the answer with what should be a suitable solution to alter the suggestions for all templates. – Pierre Buyle Jun 15 '16 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? – KraggTheGrimm Jun 25 '16 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. – Pierre Buyle Jun 26 '16 at 19:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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