Comment obtenir par programme le NID du nœud actuel

26

J'ai parcouru ce vieux fil sur drupal.org et ça me fait juste tourner la tête. En descendant le chemin et en essayant d'analyser le NID de l'intérieur? Il doit y avoir une meilleure façon.

Et des solutions comme

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

ne fonctionne pas dans mon module personnalisé (même si on me dit qu'ils fonctionnent dans des modèles?). Aucune erreur ou quoi que ce soit, il instancie juste $nodeavec une NULLvaleur.

J'ai l'impression qu'il doit y avoir quelque chose de vraiment évident que je manque.

Alors, comment obtenir le NID du nœud actuel sans modèle, tout en suivant les meilleures pratiques et en construisant un module raisonnablement robuste?

beth
la source

Réponses:

50

En supposant que votre code s'exécute pour une page de nœud, les méthodes que je vois utilisées le plus souvent dans les modules core / contrib utilisent 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);
}

Personnellement, je préfère la première méthode (même si l'affectation en condition n'est pas considérée comme une bonne idée par certaines personnes), mais les deux sont parfaitement valables.

Clive
la source
1
@Letharion Ouais je me sens un peu coupable à chaque fois que je le fais;)
Clive
1
@beth De quelle fonction l'appelez-vous? Et est-ce vraiment une page de nœud sur laquelle vous l'appelez?
Clive
1
@beth Ils fonctionneront à 100% avec l'alias de chemin activé. L'alias de chemin n'a rien à voir avec le chemin du routeur de l'élément de menu, c'est-à-dire node/1, node/2etc. Si vous rencontrez toujours des problèmes, il peut être utile de poster une autre question avec le code exact que vous utilisez et de fournir un peu de contexte. Ensuite, nous pourrons peut-être déterminer où le problème se produit
Clive
1
Une solution $nid = ($node = menu_get_object()) ? $node->nid : NULL;
monoligne
3
@sheldonkreger Le nœud est déjà chargé par ce point, menu_get_object()(ou même node_load()), il ne fait que l'obtenir à partir du cache statique. Même si vous l'appelez tôt, il sera toujours chargé par un module principal plus tard dans la construction de la page (car il s'agit d'une page de nœud), dans ce cas, vous chaufferiez simplement le cache statique pour le processus suivant
Clive
5

Le moyen le plus simple de le faire dans Drupal 8 car arg () ne fonctionne plus:

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

Modifier l'enregistrement

Pouya Sanooei
la source
2
Cela fonctionne également dans Drupal 7. Cependant, si vous êtes sur une page qui n'est pas un nœud, comme admin / structure / blocks, vous recevrez alors une valeur invalide (dans ce cas, «structure»). Vérifiez simplement si path_args [1] est un entier et vous êtes probablement bien.
sheldonkreger
Vous voudrez probablement utiliser arg (1) au lieu d'exploser, car il l'a déjà fait pour vous: api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/…
RobLoach
1
@RobLoach mais arg () n'existe pas en D8
Pouya Sanooei
4

arg(0)retourne 'node' et arg(1)retourne node nid.

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

Ce lien m'a aidé: http://www.webomelette.com/node-id-nid-url-path-alias - Allez dans Contenu et filtrez vers le bas pour trouver le contenu pour lequel vous voulez voir l'ID de nœud et survolez le Modifier lien. Regardez vers le bas pour voir l'hyperlien que votre navigateur vous indique qu'il suivra si vous cliquez sur Modifier.

Ana
la source
Salut Ana, bienvenue dans Drupal Answers. Votre réponse est bonne (et je l'ai votée pour la tentative), mais la question demande comment obtenir le nid par programme car il contient «à partir d'un module» dans le titre.
Darvanen
1

La deuxième méthode dans la réponse actuellement acceptée est la plus propre de D7. La première réponse:

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

est seulement visuellement plus propre. En fait, menu_get_object()appelle beaucoup de code et peut conduire à des erreurs imprévues. Je l'utilisais dans une hook_node_grants()fonction et j'ai rencontré une erreur PHP fatale:

Le niveau maximal d'imbrication des fonctions de '256' est atteint, abandonné!

L'explication, trouvée sur /drupal//a/69232/9158

La boucle infinie que vous remarquez est due au fait que menu_get_object()Drupal vérifie que l'utilisateur actuellement connecté a accès au nœud, ce qui provoque l' hook_node_grants()invocation de votre implémentation de , qui appelle menu_get_object(), ce qui provoque l' hook_node_grants()invocation de votre implémentation de , lequel...

Cela a été résolu en utilisant la deuxième méthode:

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
la source
1

En D8:

$node = \Drupal::routeMatch()->getParameter('node');
user373707
la source
Mieux vaut envelopper la sortie comme indiqué dans drupal.stackexchange.com/a/145826/15055 . Et il convient également de noter que cela ne fonctionnera pas sur les pages d'aperçu des nœuds et les pages de révision des nœuds.
leymannx
-1

Une autre option, 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 vous prévoyez d'utiliser la fonction en dehors de votre module, n'utilisez pas le _ de début au début du nom de la fonction.

sheldonkreger
la source
1
C'est la même chose mais avec un appel de surveillance coûteux sur tous les chemins qui ne sont pas des nœuds.
beth
J'aime savoir si mon code échoue de façon inattendue. Je ne voudrais pas que ce code soit exécuté sur des non-nœuds, le chien de garde me montrera où cela se produit afin que je puisse le corriger. Sinon, je n'aurai aucune trace que ce code fonctionne sans raison (sur des non-nœuds). Sinon, c'est la même chose que la méthode D8 mentionnée ci-dessus.
sheldonkreger
-1
<?php
if (isset($node->nid) && count($node->nid) > 0){
  $mynodeid = $node->nid;
}
?>
cptstarling
la source
Pourriez-vous s'il vous plaît ajouter quelques «pourquoi» et «comment» à votre réponse? La réponse en code seul peut fonctionner, mais cela ne permet guère de comprendre ses erreurs.
Mołot
Il vérifie d'abord si le nœud est défini avant de s'exécuter.
cptstarling