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

sam_squarewave’s picture

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

rcastera’s picture

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.

aimeee’s picture

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!

maartenstorm’s picture

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

Undoredoo’s picture

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

Undoredoo’s picture

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.

daveparrish’s picture

This was my problem as well. Thank you!

gilcreque’s picture

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

prev’s picture

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'];

JamesMT’s picture

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!

prev’s picture

In page.tpl.php i use:

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

Not sure if that helps..

JamesMT’s picture

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!

prev’s picture

So would be

<?php 

$output= field_get_items('node', $node, 'your_field_title');
$output = $output[0]['value'];

?>

<div><?php print $output; ?></div>
tecjam’s picture

This was the only solution that worked for me!

What an utter pain! =/

lgomezma’s picture

That indeed works.

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

federico’s picture

Thanks, it worked for me!

ataxia’s picture

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

ataxia’s picture

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

jay.lee.bio’s picture

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.

____________________

https://jay.lee.bio

Jaypan’s picture

Please note this:

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

Should be this:

if ($node->type == 'basic_page') { print $node->field_category[LANGUAGE_NONE][0]['value']; }
jay.lee.bio’s picture

Thanks!

____________________

https://jay.lee.bio

alienzed’s picture

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]

32i’s picture

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);
          }
        }
      }
    }
?>
Geijutsuka’s picture

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.

32i’s picture

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.

awilliams’s picture

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. 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 :
    $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.
    $value = field_get_items('node', $node, 'field_name');
    
32i’s picture

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

scepticore’s picture

I did it like

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

it's pretty simple and works so far.

leymannx’s picture

that's fine.

Jaypan’s picture

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:

// Wrong way:
$color = $node->field_node_color['und'][0]['value'];

// Right way:
$color = $node->field_node_color[LANGUAGE_NONE][0]['value'];
tsorelle’s picture

I have a couple of rules about things like this.
1) Stick to the API rather than low level stuff.
So prefer:

$items = field_get_items('node',$node,'field_node_color');
$color = isset($tems[0]['value']) ? $items[0]['value'] : '';

Over:

$color = $node->field_node_color['und'][0]['value'];

That way you don't have to worry about 'und' unless you want to specify the language. And you get nice safe 'isset' checks that prevent errors if the field or any of it's elements do not exist.

Also you stand a better chance of your code surviving version changes. However :-(, many field API functions including field_get_items are getting ditched in Drupal 8. Which brings me to my other rule.

2) Encapsulate functionality in methods or functions so they are easier to update for a version change. So I'm using this:

function _mytemplate_getSingleFieldValue($entity,$fieldName,$entityType = 'node',$safeValue=true) {
    $items = field_get_items($entityType,$entity,$fieldName);
    if (!empty($items)) {
        $valueIndex = $safeValue ? 'safe_value' : 'value';
        if (isset($items[0][$valueIndex])) {
            return $items[0][$valueIndex];
        }
    }
    return false;
}

I'll post my Drupal 8 version when I have it tested.

Abhay Pai’s picture

Following is my code to use jurisdiction value in a variable $jurisdiction
even after switching from and flushing out cache it gives me same notice error

Notice: Undefined index: und in include()

$jurisdiction = $user_fields->field_jurisdiction['und'][0]['value'];

$jurisdiction = $user_fields->field_jurisdiction[LANGUAGE_NONE][0]['value'];
if ( $user->uid ){
				$user_fields = user_load($user->uid);
				$jurisdiction = $user_fields->field_jurisdiction[LANGUAGE_NONE][0]['value'];
jay.lee.bio’s picture

Dumb question: Is it ok to just ALWAYS use LANGUAGE_NONE instead of 'und'?

____________________

https://jay.lee.bio

Jaypan’s picture

Is it ok to just ALWAYS use LANGUAGE_NONE instead of 'und'?

It's not just OK, it's how you should be doing it. You shouldn't use 'und'.

jay.lee.bio’s picture

Thanks!

____________________

https://jay.lee.bio

joro78’s picture

Hi there,

I have a problem in a multi language site. The code from the previous developers is:

foreach ($node->field_image['und'] as $id => $field):
print render (file_create_url($field['uri'])); " href=" print render (file_create_url($field['uri'])); ">
endforeach;

I got an error on the site: Only variables should be passed by reference in include()... for this line.

I have tried to substitute this section with a variable but without any success so far. The error message goes away but the images from the changed section (data-rsBigImg) does not render.

Can somebody help me with that?

Thanks in advance.

Jaypan’s picture

This really deserves a new topic, as it has nothing to do with the original subject.

Start a new topic, and I'll tell you how to fix it there.