Cómo obtener programáticamente el NID del nodo actual

26

He examinado este viejo hilo en drupal.org y me da vueltas. ¿Bajando por el camino e intentando analizar el NID desde dentro? Tiene que haber una mejor manera.

Y soluciones como

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

no funciona en mi módulo personalizado (¿aunque me han dicho que funcionan en plantillas?). Sin error ni nada, solo se instancia $nodecon un NULLvalor.

Parece que debe haber algo realmente obvio que me estoy perdiendo.

Entonces, ¿cómo se obtiene el NID del nodo actual sin una plantilla, mientras se siguen las mejores prácticas y se construye un módulo razonablemente robusto?

beth
fuente

Respuestas:

50

Suponiendo que su código se está ejecutando para una página de nodo, los métodos que veo que se usan con más frecuencia en los módulos principales / contrib están usando menu_get_object()o arg():

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

o

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

Personalmente, prefiero el primer método (aunque algunas personas no consideran una buena asignación en condiciones), pero ambos son perfectamente válidos.

Clive
fuente
1
@Letharion Sí, me siento un poco culpable cada vez que lo hago;)
Clive
1
@beth ¿Desde qué función lo llamas? ¿Y definitivamente es una página de nodo en la que está llamando?
Clive
1
@beth Ellos 100% funcionarán con alias de ruta habilitado. El alias de ruta no tiene nada que ver con la ruta del enrutador del elemento del menú, que es node/1, node/2etc. Si todavía tiene problemas, puede valer la pena publicar otra pregunta con el código exacto que está usando y proporcionar un poco de contexto. Entonces podríamos determinar dónde está sucediendo el problema
Clive
1
Una solución de línea única$nid = ($node = menu_get_object()) ? $node->nid : NULL;
timofey.com
3
@sheldonkreger El nodo ya está cargado en ese punto, menu_get_object()(o incluso node_load()) solo lo está obteniendo de la caché estática. Incluso si lo llama desde el principio, aún será cargado por un módulo central más adelante en la construcción de la página (ya que esta es una página de nodo), en ese caso simplemente estaría calentando la caché estática para el siguiente proceso
Clive
5

La forma más fácil de hacer esto en Drupal 8 ya que arg () ya no funciona:

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

Cambio de registro

Pouya Sanooei
fuente
2
Esto también funciona en Drupal 7. Sin embargo, si está en una página que no es un nodo, como admin / estructura / bloques, recibirá un valor no válido (en este caso, 'estructura'). Simplemente verifique si path_args [1] es un entero y probablemente esté bien.
sheldonkreger
Es probable que desee utilizar arg (1) en lugar de explotar, ya que ya lo ha hecho por usted: api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/…
RobLoach
1
@RobLoach pero arg () no existe en D8
Pouya Sanooei
4

arg(0)devuelve 'nodo' y arg(1)devuelve el nodo nid.

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

Este enlace me ayudó: http://www.webomelette.com/node-id-nid-url-path-alias - Vaya a Contenido y filtre hacia abajo para encontrar el contenido para el que desea ver la ID de nodo y pase el cursor sobre Editar enlazar. Mire hacia abajo para ver el hipervínculo que su navegador le dice que seguirá si hace clic en Editar.

Ana
fuente
Hola Ana, bienvenido a Drupal Answers. Su respuesta es buena (y lo he votado por el intento), sin embargo, la pregunta es cómo obtener el nid mediante programación, ya que contiene 'desde un módulo' en el título.
Darvanen
1

El segundo método en la respuesta actualmente aceptada es el más limpio en D7. La primera respuesta:

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

es solo visualmente más limpio. De hecho, menu_get_object()está llamando una gran cantidad de código y puede provocar errores imprevistos. Lo estaba usando dentro de una hook_node_grants()función y encontré un error fatal de PHP:

¡Se alcanzó el nivel máximo de anidación de funciones de '256', abortando!

La explicación, que se encuentra en /drupal//a/69232/9158

El bucle infinito que está notando se debe al hecho de que menu_get_object()Drupal verifica que el usuario actualmente conectado tiene acceso al nodo, lo que hace que su implementación hook_node_grants()sea ​​invocada nuevamente, qué llamadas menu_get_object(), lo que hace que su implementación hook_node_grants()sea ​​invocada nuevamente , cual...

Esto se resolvió utilizando el 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
fuente
1

En D8:

$node = \Drupal::routeMatch()->getParameter('node');
usuario373707
fuente
Mejor ajuste el resultado como se muestra en drupal.stackexchange.com/a/145826/15055 . Y también vale la pena señalar que esto no funcionará en las páginas de vista previa de nodo y las páginas de revisión de nodo.
leymannx
-1

Otra opción, en 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;
  }
}

Si planea usar la función fuera de su módulo, no use el principio _ al principio del nombre de la función.

Sheldonkreger
fuente
1
Esto es lo mismo pero con una costosa llamada de vigilancia en todas las rutas que no son nodos.
beth
Me gusta saber si mi código falla inesperadamente. No me gustaría que este código se ejecute en no nodos, watchdog me mostrará dónde está sucediendo para que pueda solucionarlo. De lo contrario, no tendré rastro de que este código se esté ejecutando sin motivo (en no nodos) De lo contrario, es el mismo que el método D8 mencionado anteriormente.
sheldonkreger
-1
<?php
if (isset($node->nid) && count($node->nid) > 0){
  $mynodeid = $node->nid;
}
?>
cptstarling
fuente
¿Podría agregar algunos "por qué" y "cómo" a su respuesta? La respuesta de solo código podría funcionar, pero difícilmente ayuda a comprender los errores de uno.
Mołot
Primero verifica si el nodo está definido antes de ejecutarlo.
cptstarling