Hi,
Working on printing out the filepath of an mp3 file from a filefield - to feed to soundmanager2. I'm working on a zen subtheme and editing the node.tpl.php file.

On the site.com/node page, I was developing and got this array (the relevant part)

[field_mp3_file] => Array
                                           (
                                                    [und] => Array
                                                        (
                                                            [0] => Array
                                                                (
                                                                    [fid] => 60
                                                                    [display] => 1
                                                                    [description] =>
                                                                    [uid] => 1
                                                                    [filename] => kiosks.mp3
                                                                    [uri] => public://audiofiles/kiosks.mp3
                                                                    [filemime] => audio/mpeg
                                                                    [filesize] => 2431731
                                                                    [status] => 1
                                                                    [timestamp] => 1296851459
                                                                )
                                                        )
                                                )

On the full node page, I got this:

[field_mp3_file] => Array
        (
            [0] => Array
                (
                    [fid] => 60
                    [display] => 1
                    [description] =>
                    [uid] => 1
                    [filename] => kiosks.mp3
                    [uri] => public://audiofiles/kiosks.mp3
                    [filemime] => audio/mpeg
                    [filesize] => 2431731
                    [status] => 1
                    [timestamp] => 1296851459
                )
        )

To retrieve the first one, I used:

print 'files/'.substr($node->field_mp3_file['und'][0]['uri'],9);

or simply

$node->field_mp3_file['und'][0]['uri']

So there is no longer the 'und' array in the full display page. How can I deal with this? Am I going about retrieving this data the incorrect way?

Also, what does UND mean?

Thanks for you help!
Sam

Comments

I'm also having this problem after getting the value for my taxonomy like this:

$taxterm = $node->taxonomy_vocabulary_1['und']['0']['taxonomy_term']->name

UND stand for undefined. This key is used for the language. You can try $node->language. I've been trying to print a field in Drupal 7 to page.tpl.php with no success without getting the same error you are.

I'm trying to print out a value in a field array that has a 'und' with no luck.

Strangely, I've had success in printing the value of a field array that doesn't have a und by adding ['#items'].

Here is the working array and code:

[field_related_organization] => Array
(
[0] => Array
(
[nid] => 2
[access] => 1
[node] => stdClass Object
(...things in here not important )
)
)

code:
$myvar = $content['field_related_organization']['#items']['0']['nid'];
print $myvar;

//prints the correct 'nid'

This is the array that is giving me trouble:

[field_use_org_image] => Array
(
[und] => Array
(
[0] => Array
(
[value] => 1
)

)

)

And code:

$myothervar = $content['field_use_org_image']['und']['0']['value'];
print $myothervar;

//doesn't print anything

....the first one worked after adding in the mysterious ['#items'] key.... tried adding it to the second, even after knowing that it makes no sense. Can anyone shed light on this? Thanks!

Following this thread because I have the same problem.
Did you find any solution?

I will honestly love the person who comes up with a reasonable solution for this, since I have the exact same problem. I kind of solved it by checking if the node is displayed as a single node or as part in a page, and then altering the variable path accordingly. It works, but it's ugly.

Kind of related to this thread which I just posted:
http://drupal.org/node/1108048

There's a setting in the content type which solved my problem.

Go to the manage display tab. In the upper right corner you'll find "Default" and "Full content". In the "Full content" section, the fields seems to be set as hidden as default, which makes the field not appear correctly in $content and $node. Set the field as visible and it should now be reachable via $FIELD[0]['uri'], regardless of the context.

I don't know if this is the only and universal solution, but it worked for me.

This was my problem as well. Thank you!

Using ['und'] is working for me but errors get thrown every once in a while saying und is not an index.

I switched from using $node in node.tpl.php to $content and using the #items array which outputs consistent data.
eg. $content['field_your_field']['#items'][1]['value'];

Hi prev,

Doesn't work in page.tpl.php though, don't suppose you know how to print $content in there? Judging by this thread, any way to solve this [und] issue once and for all would be amazing!

In page.tpl.php i use:

$var = field_get_items('node', $node, 'field_title');
$var = $var [0]['value'];

Not sure if that helps..

Looks good but, how do you set the variable and use it in the same php function? - I'm not very good at that - could you throw the <?php brackets around it for me (sorry, I'm a basic php user)...

Thanks for any help!

So would be

<?php
$output
= field_get_items('node', $node, 'your_field_title');
$output = $output[0]['value'];
?>

<div><?php print $output; ?></div>

This was the only solution that worked for me!

What an utter pain! =/

That indeed works.

IMO it's a better practice than iterating through the $content array.

Thanks, it worked for me!

After much head-banging, I finally got this working in two different Drupal 7 sites, one that uses the Locale module (to allow content in different languages) and one that doesn't. Using Locale changes what you need to do in order to print the variable.

It also took me a while to figure out how to avoid the error messages I was getting by testing for content types before printing the variables.

In the site that does NOT use the Locale module (all content is in English), I did this to print the value of a custom field called "field_category" directly in page.tpl.php:

<?php print $node->field_category['und'][0]['value'];  ?>

To print the same field in the site that DOES use the Locale module (content is in multiple languages), I did this to print the value of a custom field called "field_category":

<?php print $node->field_category[$node->language][0]['value'];  ?>

Note: If you have multiple content types, you will get errors similar to this if you try to print variables on page.tpl.php that don't appear in all content types:

Notice: Undefined property: stdClass::$field_category in include() (line 73 of /var/www/html/d7/sites/sitename/themes/fusion/fusion_starter/page.tpl.php).

To avoid this, you can either use a separate template for each content type (page--article.tpl.php, page--story.tpl.php, etc.) or you can check the value of the content type before printing the variable in page.tpl.php, like this example:

<?php if ($node->type == 'basic_page') { print $node->field_category['und'][0]['value']; }  ?>

or, if using Locale:

<?php if ($node->type == 'basic_page') { print $node->field_category[$node->language][0]['value']; }  ?>

Hope this saves someone a few hours!
- Ataxia

Of course, after testing this and posting my solution, I found another scenario that causes problems. Two, actually. Heavy sigh.

Let's say you have a page that displays multiple nodes....in that case, there are multiple values for $node->type, and everything explodes when you check for the node type. Actually, you just get an error message displayed on the page, similar to this:

Notice: Undefined variable: node in include() (line 67 of /var/www/html/d7/sites/sitename/themes/fusion/fusion_starter/page.tpl.php)

To avoid this, you can check for a specific content type before printing out the value on the template.

<?php if (isset ( $node->type ) && ( $node->type == 'basic_page' ) )
                     { print
$node->field_category['und'][0]['value']; }
?>

That seemed to fix the problem on my all-English site.

However, I'm getting a new error message now related to the default language on the multi-language site. The basic_page content type on this site doesn't have different languages, so the default language is English and I hadn't enabled multilingual support for that content type. This is the error message I'm getting:

Notice: Undefined index: en in include() (line 77 of /var/www/html/d7/sites/sitename/themes/fusion/fusion_starter/page.tpl.php).

To halt that error message, I changed "Multilingual support" for the basic_page content type to 'enabled'. Since the default language is set to English, this won't cause any extra work for anyone who is adding basic_page content to the site, but I had to re-save all of my existing pages so that the variable would be set for each one.

This is working so far, but I'm not overly confident and it's not a very good solution.

I suspect this problem is caused by a bug in the way Drupal 7 handles multiple languages, but I've been wrong before. At least once.

- A

Great discussion here. For me, the <?php if ($node->type == 'basic_page') { print $node->field_category['und'][0]['value']; }  ?> part got rid of all my error messages. Thank you.

Please note this:

<?php
if ($node->type == 'basic_page') { print $node->field_category['und'][0]['value']; }
?>

Should be this:

<?php
if ($node->type == 'basic_page') { print $node->field_category[LANGUAGE_NONE][0]['value']; }
?>

Jaypan
Our newest Drupal site: PacificAikido.com (Drupal showcase)

Testing the variable with an isset() before printing hides the errors for me. I also just default to passing $node->language to make it future proof.

So something like:
[code]
if (isset($node->field_exif_aperturefnumber[$node->language]['0']['safe_value'])){
print $node->field_exif_aperturefnumber[$node->language]['0']['safe_value']; //voila, no warning
}
[/code]

it's not just a theming problem.

I've worked with apachesolr and got same in hook_update_index.
plus, if there's multilingual content, it seems that field can be "und" while $node->language can be set on "en", for example.

However, code like this works without warnings. I know, this approach won't work in templates, but in my particular case with indexing fields for search, this worked well.

<?php if (count($node->field_jackpots)) {
     
$field = $node->field_jackpots;
      foreach (
$field as $lang => $values) {
        foreach (
$values as $value) {
          if (isset(
$value['safe_value']) && $value['safe_value']) {
           
$document->setMultiValue('sm_jackpots',1);
          }
        }
      }
    }
?>

I'm digging holes that are going nowhere. I'm having the same problem finding documentation on grabbing specific elements from fields. For instance: I want to wrap some other field in the URL of a link field—just the URL; I don't want the link's title (that is used somewhere else in the node). I can't find any documentation about how to grab certain things from fields.

I've come across this site that might help some of you: http://www.computerminds.co.uk/articles/rendering-drupal-7-fields-right-way
but.... it doesn't really touch on extracting only part of a field.

[Exit, pursued by a bear.]

www.StudioRLM.com
www.RLMacaulay.com

it can be done via hook_preprocess_node - in variables you receive node object, so that you can grab your particular piece of field, and use it in node template later.

if you are using multilingual on your site. In Drupal 7, i think its better to check the language at field level using field_language. The function below will return the code of the field in question and inside your template you can call function when needed.

  1. <?php
    function _get_field_lang_code($field_name, $node) {
          return
    $language = field_language('node', $node, $field_name );
    }
    ?>
  2. And then in your node template, you could do something below :

    <?php
    $field_name
    = 'field_name';
    $language = _get_field_lang_code($field_name, $node);
    print
    $node->{$field_name}[$language][0]['value'];
    ?>
  3. Alternatively, you could call field_get_items($entity_type, $entity, $field_name, $langcode = NULL) directly.
    <?php
    $value
    = field_get_items('node', $node, 'field_name');
    ?>

Thanks for suggestion, I'm using field_get_items, it fits perfectly.
I hadn't worked with entities & related stuff that close, so it took me some time to find this function.

However, I guess it still should be in hook_preprocess_node or any other hook in the module, not in the template - ideally templates should work with data ready to output, without any data processing functions.

Regards, Slava

I did it like

if(isset($...->field['und'][0]['value'])){
// Actions to do in here
}

it's pretty simple and works so far.

that's fine.

A note for everyone in this thread, 'und' refers to 'undefined'. When pulling values out of an array, you should never use 'und', as it may change at some time. You should instead use the constant LANGUAGE_NONE. Ex:

<?php
// Wrong way:
$color = $node->field_node_color['und'][0]['value'];
// Right way:
$color = $node->field_node_color[LANGUAGE_NONE][0]['value'];
?>

Jaypan
Our newest Drupal site: PacificAikido.com (Drupal showcase)