¿Cuál es la mejor práctica cuando se trabaja con el idioma [und]?


51

Estoy empezando a usar este formulario para acceder a los datos en mi módulo. (Ver comentario # 1. )

$node->field_test[$node->language][0]['value']

Pensé que parecía una solución bastante buena, pero más abajo esa misma pregunta encontré esto :

No asuma que 'und' es para campos de entidades sin lenguaje, también es para campos que no son traducibles y sin el módulo de traducción de entidades que son todos los campos. Además, hay diferencias en esto entre las diversas versiones 7.x de Drupal.
Es mejor usar la field_get_items()función que resolverá según el código de idioma en el que se almacenan los datos.

Y ahora no sé si lo que estoy usando podría romper algo en el camino.

Respuestas:


39

Creo que usar el módulo Entity API es de gran ayuda y también hace que el código sea más legible. El código anterior no siempre funcionará, ya que el idioma del nodo y el idioma del campo pueden ser diferentes.

Con el módulo de API de entidad y su contenedor, puede usar el siguiente código:

 $node_wrapper = entity_metadata_wrapper('node', $node);
 $field_val = $node_wrapper->field_test->value();

Esto debería ser a prueba de balas. Una cosa sobre el uso del módulo de entidad es que si intenta acceder a un campo que no existe, obtendrá un error desagradable y una excepción en lugar de un aviso y un comportamiento incorrecto.

Para evitar esto, puedes intentar / atrapar así

try {
  $field_val = $node_wrapper->field_doesnt_exist->value();
} catch (EntityMetadataWrapperException $e) {
  $field_val = 'default/fallback value';
}

O puede usar lo isset()que EntityMetadataWrappermaneja internamente:

$field_val = 'default/fallback value';
if (isset($node_wrapper->field_doesnt_exist)) {
  $field_val = $node_wrapper->field_doesnt_exist->value();
}

¿Esta función entity_metadata_wrapper()ha quedado en desuso? Intenté llamar a esto en mi módulo, y obtuve Fatal error: Call to undefined function entity_metadata_wrapper(), ¡también hice una búsqueda de fuente en mi instalación de Drupal 7.12 en Dreamweaver, y obtuve 0 resultados en cualquier otro lugar del código!
Aditya MP

1
aditya - esto está en el módulo API de Entity - no en el núcleo.
lazysoundsystem

1
@adityamenon Como lazy dice que esto no está en el núcleo ... aún así, probablemente será para Drupal 8. Las API de la entidad al menos mejorarán enormemente. Realmente no había tiempo para crear todas las API necesarias para el sistema de entidades para Drupal 7, así que eso es lo que el módulo de API de entidades intenta lograr.
googletorp

Gracias chicos, fui estúpido por no leer la respuesta correctamente y seguir el enlace a la página del proyecto Entity API :)
Aditya MP

1
Cuando miro el código fuente de entity_metadata_wrapper y sigo el rastro del conejo a través de todas las clases que se instancian y amplían para darme una manipulación de campo más fácil, me pregunto si vale la pena. Agregar otras líneas de código de 3k + a mi rutina de arranque y ocupar más memoria para manejar todas las asignaciones de variables ... ¿hay algo más liviano? Parece que esa $node->field_name[LANGUAGE_NONE][0]['value'] = 'foo';es realmente la forma más eficiente.
Charlie Schliesser

19

Para leer, siempre debe poder usar field_get_items () , que elegirá el idioma correcto para usted y también comprobará si el campo tiene algún valor.

Desafortunadamente, la API de campo es muy limitada en 7.x, no hay forma de obtener, por ejemplo, el primer elemento de campo, ni siquiera se atreva a preguntar sobre cómo obtener el valor con una sola llamada de función ... Y no hay field_set_items ( ) contrapartida.

Así que sí, el módulo API entidad hace proporcionar una API más bonita con el inconveniente de que también viene con un poco de sobrecarga (Básicamente se convierte cada valor individual a objetos envolventes que tienen un montón de información de propiedad anidada matrices unidas a ellas). Intentar volcar un contenedor de entidades generalmente no le proporcionará nada o un muro de matrices ilegibles.


1
¿Tengo la impresión de lo que está diciendo que este tipo de cosas podrían mejorarse en Drupal 8? Si es así, ¿cómo se hace para descubrir cómo progresa este tipo de cosas? ¡Aparte de las páginas del módulo, Do es como un laberinto para mí! :)
Clive

1
Bueno, siempre hay esperanza :) Y es difícil mantener incluso una visión general de alto nivel de lo que está sucediendo en Drupal 8, una forma es seguir las iniciativas. Sin embargo, este no es un objetivo directo de las directivas existentes. Partes del módulo API de la entidad se mueven / se mueven al núcleo (ahora hay una clase de entidad y las entidades existentes se convierten al nuevo sistema). Por lo tanto, existe la posibilidad de que, por ejemplo, obtengamos métodos directamente en esas clases para tratar los campos. Para los cambios comprometidos, un buen recurso es el nuevo sistema de registro de cambios, consulte drupal.org/list-changes/drupal .
Berdir

¡Brillante, ese es exactamente el tipo de cosas que estaba buscando, muchas gracias! :) Espero que no les importe que pregunte, sé que no es realmente sobre el tema para el sitio ... Me encantaría participar en la contribución al núcleo, pero como nunca he estado realmente involucrado en el código abierto, encuentro todo el asunto. un poco desalentador ... es bueno tener un buen lugar para comenzar :)
Clive

Clive: visite drupalofficehours.org , es precisamente para ayudar a las personas a comenzar a contribuir. Más recursos allí. También recomendaría ir a una reunión de grupo de usuarios que los desarrolladores principales frecuentan o más probablemente un DrupalCamp donde estarán uno o dos desarrolladores principales. Encuentre su grupo local en groups.drupal.org y debería poder resolverlo. drupical.org también puede ser útil.
wizonesolutions

-2
$node = node_load($lot_id);
$field_language = field_language('node', $node, 'field_name');
$node->field_name[$field_language][0]['value'] = $custom_value;

¿Puedes agregar una breve explicación de por qué esto responde la pregunta?
Radical libre
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.