Лучшая практика для языкового ключа для «und» в hook_form_alter


30

Я изменяю форму в моем пользовательском модуле. Код выглядит так:

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

    }

}

Тем не менее, я думаю, что жесткое кодирование undэто плохо. Каким должен быть правильный способ корректного изменения полей формы в этом случае?


Этот комментарий, вероятно, не имеет значения, так как он задан давно. Один простой способ использовать его с помощью foreachцикла. Если это просто LANGUAGE_NONE, это один запуск. В смысле form_alter, он должен технически изменить любой язык формы.
AyeshK

Ответы:


40

К сожалению, ваш ответ не так универсален. Язык полей и язык узлов не одно и то же.
Язык полей необходим только в том случае, если вы используете API перевода полей (например, перевод сущностей ). Когда вы начинаете использовать его, некоторые поля преобразуются в переводимые.

У переводимых полей есть код языка, который действительно имеет смысл. Но если поле не переводимо, код языка всегда будет (и для всех типов контента, сущностей и т. Д.) - LANGUAGE_NONE(лучше всего использовать константу, LANGUAGE_NONEа не строку 'und').
Таким образом, с вашим решением вы можете получить ситуацию, когда узел является русским, но поле узла использует LANGUAGE_NONE.
К счастью, поля прикрепляются к форме с '#language'ключом, который всегда содержит правильный код языка.

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

Если у вас нет доступа к прикрепленной форме, могут быть полезны функции API Field Language .


4
Это единственный правильный ответ в этой теме.
Боян Живанович

Этот метод также можно использовать при получении пути к полю изображения узла / типа контента. Спасибо
Jayaram R

10

Если вы знаете тип сущности и комплект, используйте что-то вроде следующего кода, который вызывает field_language () .

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

Он определит правильный язык и будет работать на многоязычных сайтах.

Также взгляните на field_get_items () .


Это правильно как способ API.
Никит

Что делать, если узел не был создан?
AgA

@Nikit Я не уверен, потому что язык отображения и язык форм не совпадают. Автор изменяет некоторую форму, и это может быть форма для создания нового узла или для добавления нового перевода существующего узла.
Калабро

@kalabro - отображать язык и язык форм - то же самое в текущем контексте.
Никит

4

Вся эта undсделка - одна из самых раздражающих вещей в Drupal 7, которая не сработала так хорошо на практике, как когда она была разработана.

В любом случае вы можете получить первый язык, используя array_keysэто:

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);
  }
}

Это должно работать все время.


Спасибо за Ваш ответ. Я вставляю то, что я сделал, чтобы исправить эту проблему в другом ответе. :)
Шафиул

Могу ли я использовать $ langs для доступа к значению того же поля в form_state?
AgA

Это действительно безопасно? Можете ли вы быть уверены, что $ langs [0] всегда является правильным элементом массива?
Роби

0

(Отвечая на мой вопрос на случай, если это кому-нибудь поможет. Ответ сработал для меня.)

Я могу написать следующую строку, чтобы получить язык:

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

5
Это не правильно. Смотрите ответ Калабро .
Боян Живанович

0

Re: ответ Калабро

его код не работает для меня - мой код немного отличается

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

[$ lang] [0] вернул "u", но полное значение [$ lang] равно "und", и мне также не понадобилось ['value'], потому что $ form ['FIELDNAME'] ['# language' ] не был массивом, это была строка.


1
0-й символ «und» - «u». Вы находитесь в лабиринте извилистых маленьких проходов, всех массивов.
Крис Берджесс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.