Come ottenere a livello di codice il NID del nodo corrente


26

Ho studiato questo vecchio thread su drupal.org e mi fa girare la testa. Tirando giù il percorso e cercando di analizzare il NID al suo interno? Deve esserci un modo migliore.

E soluzioni simili

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

non funziona nel mio modulo personalizzato (anche se mi viene detto che funzionano nei modelli?). Nessun errore o altro, crea un'istanza $nodecon un NULLvalore.

Sembra che ci debba essere qualcosa di veramente ovvio che mi manchi.

Quindi, come si ottiene il NID del nodo corrente senza un modello, seguendo le migliori pratiche e costruendo un modulo ragionevolmente robusto?

Risposte:


50

Supponendo che il tuo codice sia in esecuzione per una pagina di nodo, i metodi che vedo usati più spesso nei moduli core / contrib stanno 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 preferisco il primo metodo (anche se l'assegnazione in condizione non è considerata una buona idea da alcune persone), ma entrambi sono perfettamente validi.


1
@Letharion Sì, mi sento un po 'in colpa ogni volta che lo faccio;)
Clive

1
@beth Da quale funzione lo chiami? Ed è sicuramente una pagina di nodo su cui la stai chiamando?
Clive

1
@beth Funzioneranno al 100% con l'aliasing dei percorsi abilitato. L'aliasing del percorso non ha nulla a che fare con il percorso del router della voce di menu, che è node/1, node/2ecc. Se hai ancora problemi, varrebbe la pena pubblicare un'altra domanda con il codice esatto che stai utilizzando e fornire un po 'di contesto. Quindi potremmo essere in grado di individuare dove si sta verificando il problema
Clive

1
Una soluzione a linea singola$nid = ($node = menu_get_object()) ? $node->nid : NULL;
timofey.com il

3
@sheldonkreger Il nodo è già caricato da quel punto menu_get_object()(o addirittura node_load()) lo sta semplicemente recuperando dalla cache statica. Anche se lo chiami in anticipo, verrà comunque caricato da un modulo principale più avanti nella compilazione della pagina (dato che si tratta di una pagina di nodo), in tal caso dovresti solo riscaldare la cache statica per il processo successivo
Clive

5

Il modo più semplice per farlo in Drupal 8 poiché arg () non funziona più:

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

Cambia record


2
Questo funziona anche in Drupal 7. Tuttavia, se ti trovi in ​​una pagina che non è un nodo, come admin / struttura / blocchi, riceverai un valore non valido (in questo caso, "struttura"). Controlla semplicemente se path_args [1] è un numero intero e probabilmente stai bene.
sheldonkreger,

Probabilmente vorrai usare arg (1) invece di esplodere, poiché lo ha già fatto per te: api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/…
RobLoach

1
@RobLoach ma arg () non esiste in D8
Pouya Sanooei

4

arg(0)restituisce 'nodo' e arg(1)restituisce nid nodo.

if (arg(0) == 'node' && is_numeric(arg(1))) {
  $nid = arg(1);
}

1

Questo link mi ha aiutato: http://www.webomelette.com/node-id-nid-url-path-alias - Vai su Contenuto e filtra verso il basso per trovare il contenuto per cui vuoi vedere l'ID nodo e passa con il mouse sopra Modifica collegamento. Guarda in basso per vedere il collegamento ipertestuale che il tuo browser ti dice che seguirà se fai clic su Modifica.


Ciao Ana, benvenuto in Drupal Answers. La tua risposta è buona (e l'ho votata per il tentativo), tuttavia la domanda è come ottenere il nid a livello di codice poiché contiene "da un modulo" nel titolo.
Darvanen,

1

Il secondo metodo nella risposta attualmente accettata è il più pulito in D7. La prima risposta:

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

è solo visivamente più pulito. In effetti, menu_get_object()sta chiamando un sacco di codice e può portare a errori imprevisti. Lo stavo usando all'interno di una hook_node_grants()funzione e ho riscontrato un errore irreversibile PHP:

Raggiunto il livello massimo di annidamento delle funzioni di "256", interruzione!

La spiegazione, disponibile su /drupal//a/69232/9158

Il ciclo infinito che stai notando è causato dal fatto che menu_get_object()Drupal verifica che l'utente attualmente connesso abbia accesso al nodo, il che fa sì che la tua implementazione hook_node_grants()venga invocata di nuovo, che chiama menu_get_object(), il che fa sì che la tua implementazione hook_node_grants()venga nuovamente richiamata , quale...

Ciò è stato risolto utilizzando il secondo metodo:

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


-1

Un'altra opzione, in 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 si prevede di utilizzare la funzione all'esterno del modulo, non utilizzare il _ iniziale all'inizio del nome della funzione.


1
Questa è la stessa cosa ma con un costoso watchdog su tutti i percorsi che non sono nodi.
Bet,

Mi piace sapere se il mio codice non riesce in modo imprevisto. Non vorrei che questo codice venisse eseguito su non nodi, il watchdog mi mostrerà dove sta succedendo così posso ripararlo. Altrimenti non avrò traccia che questo codice è in esecuzione senza motivo (su non nodi). Altrimenti è uguale al metodo D8 sopra menzionato.
Sheldonkreger,

-1
<?php
if (isset($node->nid) && count($node->nid) > 0){
  $mynodeid = $node->nid;
}
?>

Potresti per favore aggiungere "perché" e "come" alla tua risposta? La risposta di solo codice potrebbe funzionare, ma difficilmente aiuta a capire i propri errori.
Mołot,

Verifica innanzitutto se il nodo è definito prima dell'esecuzione.
scricchiolio il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.