3

I was wondering how to specify a specific template for rendering a node when it's referenced from another content type.

For example I have a content-type (product) and I use the node--product.tpl.php template to render nodes of this type. Then I have a content-type named container that have a node reference field that may related a number of product nodes.
I would like to use a different template when rendering a product when the product is referenced from the container content-type.

I just installed the theme developer module and check suggested templates, I then created a new template named node-reference--product.tpl.php in the same folder as node--product.tpl.php but this file is only used if node--product.tpl.php is removed.

I guess one approach would be to use some kind of theme_preprocess hook and load a node based on the arg(1) value and then check if the type is container and if it is add a template suggestion in the $variables parameter.

5
+50

The simplest thing you can do is provide a new "View Mode" for nodes, so that you can use it with the "Rendered Node" display option for the node reference field.

This would be done in a small custom module using hook_entity_info_alter() like so:

function MYMODULE_entity_info_alter(&$info) {
  $info['node']['view modes']['node_reference_product'] = array(
    'label' => 'Node Reference Product',
    'custom settings' => TRUE
  );
}

Once the module is installed you'll have a new view mode under the "Rendered Node" display format options:

enter image description here

Now you can simply use the same node--product.tpl.php template file as normal and just test for the view mode to define what you want to display:

<?php if ($view_mode == 'full') : ?>

  <!-- HTML output for the full view mode -->

<?php elseif ($view_mode == 'teaser') : ?>

  <!-- HTML output for the teaser view mode -->

<?php elseif ($view_mode == 'node_reference_product') : ?>

  <!-- HTML output for your new view mode -->

<?php endif; ?>

Of course you still have access to the view mode in any hook_preprocess_node function so you could put your logic in there instead:

function MYTHEME_preprocess_node(&$vars) {
  if ($vars['view_mode'] == 'product_node_reference') {
    $vars['content'] = array('#markup' => 'Some other content');
  }
}

But perhaps the best part of solving your problem this way is that Drupal honours the new view mode in the UI, so for each content type you will now have a new view mode which you can choose options for as normal:

enter image description here

Just like the standard full and teaser view modes you will be able to decide which fields are displayed, and the ordering and format in which they are displayed too. It's entirely possible that after writing that tiny one-function module you won't need to write another line of code to solve the problem.

You'll also have this view mode available system wide for use in, for example, Views/Panels etc.

  • I created a module that included hook_entity_info_alter() and set the Render Node view mode to Node Product Reference for the reference field in the container content-type, but the view_mode for all nodes were still set to full, why is that? I managed to solve the problem using hook_preprocess_node() in wich I forcefully set the view_mode to the correct value. – Cyclonecode Feb 27 '12 at 11:35
  • I'm not sure to be honest, I used the exact code in the answer above and it worked fine for me :/ – Clive Feb 27 '12 at 11:38
  • I was thinking that it could be because the field already contained references when it changed the view mode. Anyway - Thanks alot for your nice answer=) – Cyclonecode Feb 27 '12 at 11:43
  • 1
    Glad to help, glad you got it sorted either way :) – Clive Feb 27 '12 at 12:04
2

It might be simplest to create a different field formatter for the entity reference on the container node. Instead of the default "Title(link)" or "Rendered Node" you can add one and theme it however you would theme the separate node templete you were trying to theme. See a writeup here: http://www.computerminds.co.uk/articles/creating-new-field-formatters-drupal-7 . In your hook_theme() you could specify a template instead of a function. I would choose this over creating a check in theme_preprocess() as it is easier to manipulate if you want to change it in the future.

I might also check out the Display Suite module if you haven't yet which will allow you to move parts of the node around in the content type settings form. It has some similar features to Panels but is much more lightweight. It might save you from creating separate node templates at all.

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.