I am using contemplate to provide the layout of my node body. I have several node types created using CCK, and several of my node types reference other node types (using the CCK node reference field type). I am displaying field values from one node type in the body of a different node type. Oh, and I am using version 5.1

My example:
I have an 'Item' node type, one of its fields is 'Description' (name: dr_item_desc, type: text)
I have a 'Task' node type, one of its fields is an 'Item' (name: rel_dr_item, type: node reference)
In the body of the 'Task' I want to display the referenced 'Item' node's 'Description' field

My current methodology:
Get the 'nid' value of the referenced node
- $item_nid = $node->field_rel_dr_item[0]['nid'];
Load the corresponding node object using Drupal's node_load() function
- $item_node = node_load($item_nid);
Build the node content using Drupal's node_build_content() function
- $item_node = node_build_content($item_node);
Get the 'view' value of the field I want to display
- $item_desc = $item_node->field_dr_item_desc[0]['view'];

My question:
I am concerned about overhead, and it seems to me that my method takes a lot of overhead to get the value. Is there a better / quicker / more elegant approach I should be taking? I had thought about pulling the data directly using SQL and Drupal's database infrastructure, but it seems I shouldn't need to. Any thoughts would be appreciated.

Comments

Lioz’s picture

i tried your solution without success.
can you post the exact code? did you put it in the node template?

rjl’s picture

This is the exact code I am using...

$item_nid = $node->field_rel_dr_item[0]['nid'];
$item_node = node_load($item_nid);
$item_node = node_build_content($item_node);
$item_desc = $item_node->field_dr_item_desc[0]['view'];

I put the code in the "body template" field for the node-type template at
/admin/content/templates/{node-type}

Lioz’s picture

Worked perfectly!

I have a "library" content with a node reference to persona content (filed_persona) and i wanted to display the "qualifica" attribute of the refernced node.

<?php
$item_nid = $node->field_persona[0]['nid'] ;
$item_node = node_load($item_nid);
$item_node = node_build_content($item_node);
$item_desc = $item_node->field_qualifica[0]['view'];
print $item_desc;
?>

so i get into the library node

persona - qualifica

just another question. The reference can have mutliple values.

persona1 - qualifica1
persona2 - qualifica2
persona3 - qualifica3

any suggestion? maybe we can use something like

<?php foreach ($field_persona as $alias) { ?>

don't have big knowledge of php
:(

rjl’s picture

Looking at the code presented by contemplate for CCK fields. This foreach statement is used to print out each value

    <?php foreach ((array)${EXAMPLE FIELD NAME} as $item) { ?>
      <div class="field-item"><?php print $item['view'] ?></div>
    <?php } ?>

So in your code, where you assign the variable $item_desc to a specific value, here...

$item_desc = $item_node->field_qualifica[0]['view'];

If you instead assigned it the object (or array - not sure which it is at this point, but it shouldn't matter) value, like so...

$item_desc = $item_node->field_qualifica;

Then, in theory, following the contemplate code, the following should output each value (I think)

    <?php foreach ((array)$item_desc as $item) { ?>
      <div class="field-item"><?php print $item['view'] ?></div>
    <?php } ?>
two2the8’s picture

Thanks, these snippets were very useful!

I needed to print the title & body of multiple nodes referenced from a single node-reference field. For anyone who's looking to do this, here's the code that worked for me:

<?php foreach ((array)$field_example_node_reference_field as $item) { ?>
<?php 
$item_nid = $item['nid'];
$item_node = node_load($item_nid);
$item_node = node_build_content($item_node);
$item_desc = $item_node->body;  ?>
<div class="field-item"><h3><?php print $item['view'] ?></h3></div>
<div class="field-item" style="margin-left:20px;"><?php print $item_desc ?></div>
    <?php } ?>

I'm reasonably sure you could change the $item_node->body to $item_node->whatever_field_you_want.

megg’s picture

nevermind

vood002’s picture

I'm loading up the node, then doing a print...and all of the fields don't have a ['view'] option. My understanding is that this is the field that has processed the input filter. In the interest of keeping everything consistent across the site, using the ['view'] is the best option.

node_build_content() did not produce the ['view'] option on any fields, but node_view() did. Therefore the code I'm using at the moment is:


foreach($node->field_referenced_field as $item)
{
  $refNode = node_load($item['nid']);
  node_view($refNode);

  print $exercise->field_field[0]['view'];
  //etc.

I understand this is probably the most processor intensive way to do it...but with caching on, who cares? Seems like the best option to me--but I just made it up as I went.

kulfi’s picture

I couldn't get a very overview of what you're working towards. Wouldn't views be more appropriate for collating the fields from various content types? You can also fuse views for more complex aggregates.

rjl’s picture

Yes, I tried using Views, but I only wanted to get the specific value of a field ("field_dr_item_desc") from a "parent" node.

In my case - one "item" node may have many "task" nodes (so "item" is the so-called 'parent' of "task". I am using the nodereference field type with my "task" nodes to be able to choose the related "item" node. The "item" node has the field ""field_dr_item_desc" that I want to display on the node page of the ""task" node.

Views only appears to allow me to show a Full Node, a Teaser, Table, or a Node List. I was able to get the value of the field "field_dr_item_desc" in a Table or a Node List. I was also able to insert that View in the "task" node page, but the View gave me all the extra html markup that I didn't want or need. I couldn't figure out how to get Views to just output the value of "field_dr_item_desc" without any additional markup - I don't think that is an option?

I haven't tried to "fuse" anyting - Is this the views fusion module you are referring to or something else?

kulfi’s picture

Unfortunately, it sounds like views isn't working for you due to 2 constraints: (1) the item node wouldn't know which task view it was in (2) the item node fields are not rendered when added to the view.

Unless your tasks/items was just an example, have you looked into the task module: http://drupal.org/project/tasks

herb’s picture

I was trying to get a CCK node-reference loaded into a separate block on the page and was having a tough time until I found your post. I'm just starting so (node_build_content) was the key. If there is a more efficient way of doing this, then maybe someone else will update this thread.

jarea’s picture

I am trying to display the title of a node referenced node using your technique. I node reference a location_type from another CCK node type and then use a computed field to compute the title of the location type node that I selected.

$item_nid = $node->field_location_type[0]['nid'] ;
$item_node = node_load($item_nid);
$item_node = node_build_content($item_node);
$item_desc = $item_node->field_title[0]['value'];
$node_field[0]['value'] = "title = " . $item_desc;

The display that I get is ... title =

I can confirm that item_nid is returning the correct node. That content type only has a title field, and no other fields.

I tried using both

$item_desc = $item_node->field_title[0]['value'];

and

$item_desc = $item_node->field_title[0]['view'];

with the same results.

Any idea where I might be going astray?

Your help is appreciated.

rjl’s picture

Try doing a print_r() on your $item_node, it can really help when trying to figure out if you should use ['value'] or ['view'] or ['nid'] or something else.

Here's a chunk of code I use with some success (place in a body field with input format set to PHP code)

$nid = arg(1);
$node = node_load($nid);
$out = strip_tags(print_r($node, TRUE));
print '<textarea cols="100" rows="40">'. $out .'</textarea>';

Sorry I also haven't worked with any calculated fields yet, so have nothing to offer on that level.

dsamuel’s picture

Thanks, that was helpful. For me though, it does not provide the full answer, although I am trying to do something quite different. This may not be the right place to ask but maybe someone here can help me or direct me to the right place.

I want to place a "node within a node", specifically a webform node, complete with fields and submit button.

Does anyone know a general way to render a complete node of any type that will function within another node just as if it was on its own page?

Thanks!
Doug

------------------------
Partly Technical
About Allergies
------------------------

csc4’s picture

Not exactly what you're trying to do the Addnode incorporates a node and creation form inside a node does that help?

mptrader’s picture

Is there any way you could retrieve the filepath field of an image using your method?
I'm using imagefield to upload images into my node, I just can't find a way to retrieve the filepath of the image when I'm using views.

obrigado’s picture

If you're using CCK, you can call module_invoke to return the formatted item without resorting to node_build_content.

For example, I needed an image from a node's imceimage field to display in a block... I was able to get the rendered html by calling CCK's format function.

$image = module_invoke('content', 'format', 'field_image', $node->field_image[0]);

Print $image wherever you want the image HTML to end up.

Here's the full description of the format function from content.module:

/**
 * Format a field item for display.
 *
 * Used to display a field's values outside the context of the $node, as
 * when fields are displayed in Views, or to display a field in a template
 * using a different formatter than the one set up on the Display Fields tab
 * for the node's context.
 *
 * @param $field
 *   Either a field array or the name of the field.
 * @param $item
 *   The field item(s) to be formatted (such as $node->field_foo[0],
 *   or $node->field_foo if the formatter handles multiple values itself)
 * @param $formatter_name
 *   The name of the formatter to use.
 * @param $node
 *   Optionally, the containing node object for context purposes and
 *   field-instance options.
 *
 * @return
 *   A string containing the contents of the field item(s) sanitized for display.
 *   It will have been passed through the necessary check_plain() or check_markup()
 *   functions as necessary.
 */

function content_format($field, $item, $formatter_name = 'default', $node = NULL) {
...
tajabosc’s picture

Using

$image = module_invoke('content', 'format', 'field_image', $node->field_image[0]);

worked for me.

In my case default formatter was not enough, so i added a custom imagecache formatter at the end using this code:

$image = module_invoke('content', 'format', 'field_image', $node->field_image[0], 'name_of_imagecache_preset');

Hope helps someone

MissyM’s picture

** bookmark **

Fairytree’s picture

Subscribing

Summit’s picture

Subscribing, greetings, Martijn

akalyptos’s picture

Subscribing

ycimlynn’s picture

subscribe

kevinqin’s picture

subscribe

wOOge’s picture

This works for me:

Inside node.tpl.php, OR node-TYPE.tpl.php

Where: field_FIELDNAME = the nodereference field you want to retrieve entries from. To locate this, print_r($node) so you can see what the field is called.

<?
	/* Setup Variables — this isn't needed if this code is inside node.tpl.php */
	//$field_FIELDNAME = $node->field_FIELDNAME;
	/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
	 * loop through all node-reference related items and print a list */
	if ($field_FIELDNAME[0]['nid']) {
	print "<h3>" . t("Related Items") . "</h3>";
	print "<ul>";
	foreach ($field_FIELDNAME as $value) {
			$value2 = node_load($value[nid]);
			$nodetoview = $value2;
			print "<li>";
			print "<strong>" . $nodetoview->title . "</strong>";
			print node_view($nodetoview,$teaser = FALSE, $page = True, $links = FALSE);
			print "</li>";
		}
		print "</ul>";
	}		

?>

----
For Keyword Searching:
Load node referenced nodes, view nodereference nodes, load referenced node

--
wOOge | adrianjean.ca

drupalfan81’s picture

Subscribing!

Great thread. But did anyone answer the original posters question about the overhead? I am interested in that as well.

rjl’s picture

OMG - I have always wanted an answer to my original question too! So, of course the overhead is terrible, and I would avoid using it in a teaser, if possible. Caching helps a great deal as well. Views has also advanced greatly since I originally posted the question, so if you can put the value you need in a block or something that might be a good way to go as well.

cdesautels’s picture

function custom_misc_retrieve_single_field($nid, $field) {
$query = db_select('field_revision_' . $field, 'f');
$query
->condition('f.entity_id', $nid)
->fields('f', array($field . '_value'))
->orderBy('revision_id', 'DESC')
->range(0, 1);
$result = $query->execute()->fetchCol();
return $result[0];
}

halloffame’s picture

Hey guys. This does not work on Drupal 7/Contemplate 7.x-1.0.

How do you print node reference field values on D7?

hockey2112’s picture

I, too, need to know how to print node reference values in D7. Anyone know how?

gaellafond’s picture

Drupal 7 solution
I spent hours to find that one so I will share it.

$node = node_load($nid);
$values = field_get_items('node', $node, 'field_XXXX');
$output = field_view_value('node', $node, 'field_XXXX', $values[0]);
print render($output);

This solution works with "node_reference" fields, "select" fields, "text" fields or any other field types, so you can loop through all fields and do the same process without exception.