Como obter programaticamente o NID do nó atual

26

Eu examinei esse tópico antigo no drupal.org e isso meio que faz minha cabeça girar. Descendo o caminho e tentando analisar o NID de dentro dele? Tem que haver uma maneira melhor.

E soluções como

global $node;
$nid = $node->nid;

não funciona no meu módulo personalizado (embora me disseram que eles funcionam em modelos?). Sem erro ou qualquer coisa, apenas instancia $nodecom um NULLvalor.

Parece que deve haver algo realmente óbvio que estou perdendo.

Então, como você obtém o NID do nó atual sem um modelo, enquanto segue as práticas recomendadas e constrói um módulo razoavelmente robusto?

beth
fonte

Respostas:

50

Supondo que seu código esteja sendo executado para uma página de nó, os métodos que eu vejo usados ​​com mais frequência nos módulos core / contrib estão usando menu_get_object()ou arg():

if ($node = menu_get_object()) {
  // Get the nid
  $nid = $node->nid;
}

ou

if (arg(0) == 'node' && is_numeric(arg(1))) {
  // Get the nid
  $nid = arg(1);

  // Load the node if you need to
  $node = node_load($nid);
}

Pessoalmente, prefiro o primeiro método (embora a atribuição em condições não seja considerada uma boa ideia por algumas pessoas), mas ambos são perfeitamente válidos.

Clive
fonte
11
@Letharion Sim, eu me sinto um pouco culpado toda vez que faço isso;)
Clive
11
@ bet De que função você está chamando? E é definitivamente uma página de nó em que você está acessando?
Clive
11
@beth Eles 100% funcionarão com o alias de caminho ativado. O alias de caminho não tem nada a ver com o caminho do roteador do item de menu node/1, node/2etc. Se você ainda estiver com problemas, pode valer a pena postar outra pergunta com o código exato que você está usando e fornecer um pouco de contexto. Talvez possamos identificar onde o problema está acontecendo
Clive
11
Uma solução de linha única$nid = ($node = menu_get_object()) ? $node->nid : NULL;
timofey.com
3
@sheldonkreger O nó já está carregado nesse ponto menu_get_object()(ou mesmo node_load()) está apenas obtendo-o do cache estático. Mesmo se você chamá-lo desde o início, ele ainda será carregado por um módulo principal posteriormente na compilação da página (como essa é uma página de nó); nesse caso, você estaria apenas aquecendo o cache estático para o próximo processo
Clive
5

A maneira mais fácil de fazer isso no Drupal 8, pois arg () não funciona mais:

$path_args = explode('/', current_path());
print $path_args[1];

Alterar registro

Pouya Sanooei
fonte
2
Isso também funciona no Drupal 7. No entanto, se você estiver em uma página que não seja um nó, como admin / structure / blocks, receberá um valor inválido (neste caso, 'structure'). Simplesmente verifique se path_args [1] é um número inteiro e você provavelmente está bem.
sheldonkreger
Você provavelmente desejará usar arg (1) em vez de explodir, já que isso já foi feito por você: api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/…
RobLoach
11
Não @RobLoach mas arg () não existe no D8
Pouya Sanooei
4

arg(0)retorna 'nó' e arg(1)retorna o nó nid.

if (arg(0) == 'node' && is_numeric(arg(1))) {
  $nid = arg(1);
}
Sébastien Gicquel
fonte
1

Esse link me ajudou: http://www.webomelette.com/node-id-nid-url-path-alias - Acesse Conteúdo e filtre downt para encontrar o conteúdo para o qual deseja ver o ID do nó e passe o mouse sobre o botão Editar ligação. Olhe para baixo para ver o hiperlink que seu navegador indica que ele seguirá se você clicar em Editar.

Ana
fonte
Olá Ana, bem-vindo ao Drupal Answers. Sua resposta é boa (e eu votei na tentativa), mas a questão é perguntar como obter o nid programaticamente, pois ele contém 'de um módulo' no título.
Darvanen
1

O segundo método na resposta atualmente aceita é o mais limpo em D7. A primeira resposta:

if ($node = menu_get_object()) {
  // Get the nid
  $nid = $node->nid;
}

é apenas visualmente mais limpo. De fato, menu_get_object()está chamando bastante código e pode levar a erros imprevistos. Eu estava usando-o dentro de uma hook_node_grants()função e tive um erro fatal do PHP:

Nível máximo de aninhamento de funções de '256' atingido, abortando!

A explicação, encontrada em /drupal//a/69232/9158

O loop infinito que você está percebendo é causado pelo fato de fazer com que o menu_get_object()Drupal verifique se o usuário conectado no momento tem acesso ao nó, o que faz com que sua implementação hook_node_grants()seja chamada novamente, quais chamadas menu_get_object(), o que faz com que sua implementação hook_node_grants()seja chamada novamente , qual...

Isso foi resolvido usando o segundo método:

if (arg(0) == 'node' && is_numeric(arg(1))) {
  // Get the nid
  $nid = arg(1);

  // Load the node if you need to
  $node = node_load($nid);
}
Jan Ehrhardt
fonte
1

No D8:

$node = \Drupal::routeMatch()->getParameter('node');
user373707
fonte
Melhor agrupar a saída como mostrado em drupal.stackexchange.com/a/145826/15055 . E também vale a pena notar que isso não funcionará nas páginas de visualização do nó e nas páginas de revisão do nó.
Leymannx
-1

Outra opção, no D7:

function _my_module_get_nid() {
  $path_args = explode('/', current_path());
  //$nid = $path_args[1];
  if(is_int($path_args)) {
    return($path_args[1]);
  }
  // Log that we failed to load a NID.
  else {
    watchdog('my_module', 'Unable to gather NID at: ' . current_path(),  WATCHDOG_WARNING, NULL);
  return FALSE;
  }
}

Se você planeja usar a função fora do seu módulo, não use o _ inicial no início do nome da função.

sheldonkreger
fonte
11
É a mesma coisa, mas com uma chamada de vigilância cara em todos os caminhos que não são nós.
beth
Eu gosto de saber se meu código está falhando inesperadamente. Eu não gostaria que esse código fosse executado em não-nós, o watchdog me mostrará onde isso está acontecendo, para que eu possa corrigi-lo. Caso contrário, não rastreamos que esse código esteja sendo executado sem motivo (em não-nós). Caso contrário, é o mesmo que o método D8 mencionado acima.
sheldonkreger
-1
<?php
if (isset($node->nid) && count($node->nid) > 0){
  $mynodeid = $node->nid;
}
?>
cptstarling
fonte
Você poderia adicionar alguns "porquês" e "comos" à sua resposta? A resposta somente de código pode funcionar, mas dificilmente ajuda a entender os erros.
Mołot 16/01
Ele primeiro verifica se o nó está definido antes da execução.
Csstarling