Quelle est la meilleure pratique pour travailler avec la langue [und]?

51

Je commence à utiliser ce formulaire pour accéder aux données de mon module. (Voir commentaire n ° 1. )

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

Je pensais que cela semblait être une très bonne solution, mais un peu plus loin, j'ai trouvé ceci :

Ne supposez pas que 'und' concerne les champs d'entités sans langage, mais également pour les champs qui ne sont pas traduisibles, et sans le module de traduction d'entité qui comprend tous les champs. De plus, il existe des différences entre les différentes versions 7.x de Drupal.
Mieux vaut utiliser la field_get_items()fonction qui trie pour vous sous quel code de langue les données sont stockées.

Et maintenant, je ne sais pas si ce que j'utilise pourrait casser quelque chose sur la route.

Merrick
la source

Réponses:

39

Je trouve que l'utilisation du module API Entity est une aide précieuse et rend le code plus lisible. Le code ci-dessus ne fonctionnera pas toujours, car la langue du nœud et la langue du champ peuvent être différentes.

Avec le module API d'entité et son wrapper, vous pouvez utiliser le code suivant:

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

Cela devrait être à l'épreuve des balles. Une chose à propos de l’utilisation du module entité est que si vous essayez d’accéder à un champ qui n’existe pas, vous obtiendrez une erreur désagréable et une exception renvoyée à la place de la notification et du comportement incorrect.

Pour éviter cela, vous pouvez essayer / attraper comme ceci

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

Ou vous pouvez utiliser isset()qui EntityMetadataWrappergère en interne:

$field_val = 'default/fallback value';
if (isset($node_wrapper->field_doesnt_exist)) {
  $field_val = $node_wrapper->field_doesnt_exist->value();
}
googletorp
la source
Cette fonction entity_metadata_wrapper()est-elle obsolète? J'ai essayé d'appeler cela dans mon module, et j'ai obtenu Fatal error: Call to undefined function entity_metadata_wrapper()- j'ai également effectué une recherche de source sur mon installation de Drupal 7.12 dans Dreamweaver , et j'ai obtenu 0 résultats ailleurs dans le code!
Aditya MP
1
aditya - cela se trouve dans le module Entity API - pas dans le noyau.
lazysoundsystem
1
@adityamenon Comme le dit paresseux, ce n'est pas dans le coeur ... mais ça le sera probablement pour Drupal 8. Les API d'entités seront au moins grandement améliorées. Il n’était pas vraiment temps de créer toutes les API nécessaires au système d’entité pour Drupal 7, c’est ce que le module d’entité API tente de réaliser.
googletorp
Merci les gars, j'ai été stupide de ne pas lire la réponse correctement et de suivre le lien vers la page du projet Entity API :)
Aditya MP
1
Lorsque je regarde le code source de entity_metadata_wrapper et que je suis la trace des lapins parmi toutes les classes instanciées et étendues pour faciliter la manipulation sur le terrain, je me demande si cela en vaut la peine. Ajouter plus de 3k lignes de code à mon boot et utiliser plus de mémoire pour gérer toutes les affectations de variables ... y a-t-il quelque chose de plus léger? Il semble que ce $node->field_name[LANGUAGE_NONE][0]['value'] = 'foo';soit vraiment le moyen le plus efficace.
Charlie Schliesser
19

Pour la lecture, vous devriez toujours pouvoir utiliser field_get_items () , qui choisira la langue qui vous convient et vérifiera également si le champ contient des valeurs.

Malheureusement, l'API de champ est très limitée dans 7.x, il n'y a aucun moyen d'obtenir, par exemple, le premier élément de champ, n'osez même pas demander d'obtenir la valeur avec un seul appel de fonction ... Et il n'y a pas de champ_set_items ( ) contrepartie.

Alors oui, le module API entité ne fournir une API plus agréable avec l'inconvénient qu'il est également livré avec un peu de frais généraux (Il convertit fondamentalement chaque valeur unique aux objets wrapper qui ont des tonnes de tableaux d'information de propriété imbriquées qui leur sont rattachés). Essayer de vider une enveloppe d'entité ne vous apportera généralement rien ou un mur de tableaux illisibles.

Berdir
la source
1
J'ai l'impression de ce que vous dites que ce genre de chose pourrait être améliorée dans Drupal 8? Si oui, comment peut-on savoir comment ce genre de choses progresse? Mis à part les pages du module, Do est comme un labyrinthe pour moi! :)
Clive
1
Et bien, il y a toujours de l'espoir :) Et il est difficile de garder même un aperçu de haut niveau de ce qui se passe dans Drupal 8, un moyen consiste à suivre les initiatives. Ce n'est pas une cible directe des directives existantes, cependant. Des parties du module API d'entité sont déplacées / en cours de transfert dans le noyau (il existe maintenant une classe Entity et les entités existantes sont converties dans le nouveau système). Il est donc possible que nous obtenions, par exemple, des méthodes directement sur ces classes pour traiter des champs. Le nouveau système d'enregistrement des modifications est une bonne ressource pour les modifications validées , voir drupal.org/list-changes/drupal .
Berdir
Génial, c'est exactement le genre de chose que je cherchais, merci beaucoup! :) J'espère que votre demande ne me dérange pas Je sais que ce n'est pas vraiment sur le sujet pour le site ... J'aimerais beaucoup contribuer à core, mais n'ayant jamais vraiment été impliqué dans l'open source, je trouve le tout un peu intimidant ... c'est bien d'avoir un bon endroit pour commencer :)
Clive
Clive: Consultez drupalofficehours.org - c’est précisément pour aider les gens à commencer à contribuer. Plus de ressources là-bas. Je vous recommanderais également de vous rendre à une réunion de groupe d'utilisateurs comprenant des développeurs principaux, souvent ou plus probablement, un DrupalCamp contenant un ou deux développeurs principaux. Trouvez votre groupe local sur groups.drupal.org et vous devriez pouvoir le résoudre . drupical.org peut aussi être utile.
Wizonesolutions
-2
$node = node_load($lot_id);
$field_language = field_language('node', $node, 'field_name');
$node->field_name[$field_language][0]['value'] = $custom_value;
Tanvir Ahmad
la source
Pouvez-vous ajouter une brève explication pour expliquer pourquoi cela répond à la question?
Radical gratuit