I'm modifying in a form in my custom module. Code looks like:

function my_module_form_alter(&$form, &$form_state, $form_id) {

    if ($form_id == "someID") {

        $form['field_charity_author']['und'][0]['value']['#value'] = arg(3);
        //$form['field_charity_author']['#type'] = 'hidden';



However, I think hard-coding und is bad. What should be the proper way to modify form fields properly in this case?

  • This comment is probably irrelevant since it's asked a long time ago. One simple way I use it by using a foreach loop. If it's just LANGUAGE_NONE, that's a single run. In form_alter sense, it should technically alter whatever the language the form has.
    – AKS
    Commented Apr 16, 2014 at 7:54

5 Answers 5


Unfortunately, your self-answer is not so universal. Field language and node language are not the same things.
Field language is needed only if you are using Field Translation API (for example Entity translation). When you start using it, some fields are converted to translatable.

Translatable fields have language code, which really makes sense. But if the field is not translatable, the language code will always be (and for all content types, entities, etc) — LANGUAGE_NONE (best to use the constant LANGUAGE_NONE and not the string 'und').
So with your solution you can get a situation when a node is Russian, but a field of the node uses LANGUAGE_NONE.
Happily, fields are attached to the form with '#language' key, which always contains the correct language code.

$lang = $form['FIELDNAME']['#language'];
$form['FIELDNAME'][$lang][0]['value']['#value'] = $value;

If you have no access to attached form, Field Language API functions can be useful.

  • 4
    This is the only correct answer in this thread. Commented May 19, 2012 at 21:45
  • This method can also be used while retreiving the image field path of a node/content-type. Thanks
    – Jayaram
    Commented Aug 23, 2015 at 12:11

If you know the entity type and bundle use something like the following code, which calls field_language().

$field_language = field_language('node', $node, 'field_charity_author');  
$form['field_charity_author'][$field_language][0]['value']['#value'] = arg(3);

It will figure out the right language, and will work in multilingual sites.

Also have a look at field_get_items().

  • This correct as API way.
    – Nikit
    Commented Jun 12, 2012 at 12:07
  • What about if the node has not been created?
    – AgA
    Commented Mar 8, 2014 at 16:14
  • @Nikit I'm not sure, because display language and form language are not the same. Author alters some form and it can be form for creating new node or for adding new translation of existing node.
    – kalabro
    Commented Mar 13, 2014 at 11:49
  • @kalabro - display language and form language - the same at current context.
    – Nikit
    Commented Mar 13, 2014 at 22:18

The whole und deal is one of the more annoying things in Drupal 7 that didn't work as well in practice as when it was designed.

Anyways you can get the first language using array_keys like this:

function my_module_form_alter(&$form, &$form_state, $form_id) {

  if ($form_id == "someID") {
      $langs = array_keys($form['field_charity_author']);
      $form['field_charity_author'][$langs[0]][0]['value']['#value'] = arg(3);

That should work all the time.

  • Thanks for your answer. I'm pasting what I've done to fix this issue in another answer. :)
    – Shafiul
    Commented Mar 21, 2012 at 5:15
  • Can I use $langs for accessing value of same field in the form_state too?
    – AgA
    Commented Mar 8, 2014 at 16:15
  • Is this really safe? Can you be sure $langs[0] is always the correct array item?
    – rooby
    Commented Dec 8, 2014 at 23:14

(Answering my own question in case it helps someone. The answer worked for me.)

I can write following line to get the language:

$lang = $form['language']['#value'];    //  Instead of "und"

re: kalabro's answer

his code didn't work for me - my code is a little different

$lang = $form['FIELDNAME']['#language'];
$form['FIELDNAME'][$lang]['#value'] = $value;

[$lang][0] returned "u" but the full value of [$lang] is "und" and I did not need the ['value'] either, because $form['FIELDNAME']['#language'] was not an array, it was a string.

  • 1
    The 0th character of 'und' is 'u'. You are in a maze of twisty little passages, all arrays. Commented Sep 4, 2013 at 6:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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