Qual é a melhor prática ao trabalhar com o idioma [und]?

51

Estou começando a usar este formulário para acessar dados no meu módulo. (Veja o comentário nº 1 ).

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

Eu pensei que parecia uma solução muito boa, mas mais abaixo nessa mesma pergunta eu encontrei o seguinte :

Não assuma que 'und' é para campos de entidades sem idioma, é também para campos que não são traduzíveis e sem o módulo de conversão de entidades que é todos os campos. Além disso, existem diferenças entre as várias versões 7.x do Drupal.
Melhor usar a field_get_items()função que classificará para você sob qual código de idioma os dados são armazenados.

E agora não sei se o que estou usando pode quebrar algo na estrada.

Merrick
fonte

Respostas:

39

Acho que usar o módulo API da entidade é uma grande ajuda e também torna o código mais legível. O código acima nem sempre funciona, pois o idioma do nó e o idioma do campo podem ser diferentes.

Com o módulo API da entidade e seu wrapper, você pode usar o seguinte código:

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

Isso deve ser à prova de balas. Uma coisa sobre o uso do módulo de entidade é que, se você tentar acessar um campo que não existe, receberá um erro desagradável e uma exceção lançada, em vez de um aviso e comportamento errado.

Para evitar isso, você pode tentar / capturar assim

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

Ou você pode usar o isset()que EntityMetadataWrappermanipula internamente:

$field_val = 'default/fallback value';
if (isset($node_wrapper->field_doesnt_exist)) {
  $field_val = $node_wrapper->field_doesnt_exist->value();
}
googletorp
fonte
Esta função entity_metadata_wrapper()foi preterida? Tentei chamar isso no meu módulo e obtive Fatal error: Call to undefined function entity_metadata_wrapper()- também fiz uma pesquisa de fontes na minha instalação do Drupal 7.12 no Dreamweaver e obtive 0 resultados em qualquer outro lugar do código!
Aditya MP
11
aditya - isso está no módulo da API da entidade - não no núcleo.
Lazysoundsystem #
11
@adityamenon Como o preguiçoso diz que isso não está no cerne ... ainda, provavelmente será para o Drupal 8. As APIs da entidade pelo menos melhorarão bastante. Não havia realmente tempo para criar todas as APIs necessárias para o sistema de entidades do Drupal 7, e é isso que o módulo de API da entidade tenta obter.
googletorp
Obrigado rapazes, eu era estúpido para não ler a resposta corretamente e siga o link para a página do projeto API Entity :)
Aditya MP
11
Quando olho o código-fonte para entity_metadata_wrapper e sigo a trilha do coelho através de todas as classes que são instanciadas e estendidas para me facilitar a manipulação de campo, me pergunto se vale a pena. Adicionando mais 3k + linhas de código ao meu bootstrap e ocupando mais memória para lidar com todas as atribuições de variáveis ​​... existe algo mais leve? Parece que essa $node->field_name[LANGUAGE_NONE][0]['value'] = 'foo';é realmente a maneira mais eficiente.
Charlie Schliesser
19

Para leitura, você sempre deve poder usar field_get_items () , que escolherá o idioma correto para você e também verificará se o campo possui algum valor.

Infelizmente, a API do campo é muito limitada no 7.x, não há como obter, por exemplo, o primeiro item do campo, nem se atreva a perguntar sobre obter o valor com uma única chamada de função ... E não há field_set_items ( ) contraparte.

Então, sim, módulo entidade API faz fornecer uma API mais agradável com a desvantagem de que ele também vem com um pouco de sobrecarga (basicamente converte cada valor único de objetos de mensagens publicitárias que têm toneladas de informações de propriedade aninhada matrizes anexados a eles). Tentar despejar um wrapper de entidade geralmente não oferece nada ou uma parede de matrizes ilegíveis.

Berdir
fonte
11
Percebo pelo que você está dizendo que esse tipo de coisa pode ser melhorado no Drupal 8? Se sim, como descobrir como esse tipo de coisa está progredindo? Além das páginas do módulo Do, é como um labirinto para mim! :)
Clive
11
Bem, sempre há esperança :) E é difícil manter uma visão geral de alto nível do que está acontecendo no Drupal 8, uma maneira é seguir as iniciativas. Porém, este não é um alvo direto das diretivas existentes. Partes do módulo API da entidade são movidas / sendo movidas para o núcleo (existe a classe Entity agora e as entidades existentes são convertidas no novo sistema). Portanto, há uma chance de, por exemplo, obtermos métodos diretamente nessas classes para lidar com campos. Para alterações confirmadas, um bom recurso é o novo sistema de registro de alterações, consulte drupal.org/list-changes/drupal .
Berdir 6/03/12
Brilhante, esse é exatamente o tipo de coisa que eu estava procurando, muito obrigado! :) Espero que você não se importe com a minha pergunta. Eu sei que não é realmente um tópico para o site ... Eu adoraria me envolver em contribuir para o núcleo, mas nunca tendo realmente sido envolvido em código aberto. um pouco assustador ... É bom para ter um bom lugar para começar :)
Clive
Clive: Confira drupalofficehours.org - é precisamente para ajudar as pessoas a começar a contribuir. Mais recursos lá. Também recomendo ir a uma reunião de grupo de usuários que os desenvolvedores principais freqüentem ou mais provavelmente um DrupalCamp em que um ou dois desenvolvedores principais estarão. Encontre o seu grupo local em groups.drupal.org e você poderá resolvê -lo. O drupical.org também pode 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;
Tanvir Ahmad
fonte
Você pode adicionar uma breve explicação sobre por que isso responde à pergunta?
Free Radical