Programmgesteuertes Abrufen der NID des aktuellen Knotens

26

Ich habe über diesen alten Thread auf drupal.org geblättert und es bringt mich dazu, den Kopf herumzudrehen . Den Pfad runterziehen und versuchen, die NID aus ihm heraus zu analysieren? Es muss einen besseren Weg geben.

Und Lösungen wie

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

funktionieren nicht in meinem benutzerdefinierten Modul (obwohl mir gesagt wurde, dass sie in Vorlagen funktionieren?). Kein Fehler oder so, es wird nur $nodemit einem NULLWert instanziiert .

Es fühlt sich so an, als ob es etwas wirklich Offensichtliches geben muss, das mir fehlt.

Wie erhalten Sie die NID des aktuellen Knotens ohne Vorlage, während Sie die bewährten Methoden befolgen und ein relativ robustes Modul erstellen?

Beth
quelle

Antworten:

50

Angenommen, Ihr Code wird für eine Knotenseite ausgeführt, verwenden die in Core / Contrib-Modulen am häufigsten verwendeten Methoden entweder menu_get_object()oder arg():

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

oder

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

Ich persönlich bevorzuge die erste Methode (obwohl die Zuweisung im Zustand von einigen Leuten nicht als gute Idee angesehen wird), aber beide sind vollkommen gültig.

Clive
quelle
1
@ Letharion Ja, ich fühle mich jedes Mal ein bisschen schuldig;)
Clive
1
@beth Von welcher Funktion rufst du es auf? Und ist es definitiv eine Knotenseite, auf der Sie es aufrufen?
Clive
1
@beth Sie arbeiten zu 100% mit aktiviertem Pfad-Aliasing. Pfad Aliasing hat nichts mit dem zu tun , Router Pfad des Menüpunktes, das ist node/1, node/2usw. Wenn Sie immer noch Schwierigkeiten haben , es könnte wert Posting sein ein andere Frage mit dem genauen Code , den Sie verwenden, und bietet ein wenig Kontext. Dann können wir möglicherweise feststellen, wo das Problem auftritt
Clive
1
Eine einzeilige Lösung$nid = ($node = menu_get_object()) ? $node->nid : NULL;
timofey.com
3
@sheldonkreger Der Knoten, der zu diesem Zeitpunkt bereits geladen ist menu_get_object()(oder sogar node_load()), bezieht ihn nur aus dem statischen Cache. Auch wenn man es so nennt früh, es ist immer noch von einem Core - Modul geladen wurde , geht später in der Seite zu bauen (wie dies ein Knoten Seite ist), in diesem Fall würden Sie nur für den nächsten Prozess der statischen Cache werden Erwärmung
Clive
5

Der einfachste Weg, dies in Drupal 8 zu tun, da arg () nicht mehr funktioniert:

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

Datensatz ändern

Pouya Sanooei
quelle
2
Dies funktioniert auch in Drupal 7. Wenn Sie sich jedoch auf einer Seite befinden, die kein Knoten ist, z. B. admin / structure / blocks, erhalten Sie einen ungültigen Wert (in diesem Fall 'structure'). Überprüfen Sie einfach, ob path_args [1] eine Ganzzahl ist und es Ihnen wahrscheinlich gut geht.
Sheldonkreger
Sie werden wahrscheinlich arg (1) anstelle von explode verwenden wollen, da dies bereits für Sie erledigt wurde: api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/…
RobLoach
1
@ RobLoach aber arg () existiert nicht in D8
Pouya Sanooei
4

arg(0)gibt 'node' zurück und arg(1)gibt node nid zurück.

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

Dieser Link hat mir geholfen: http://www.webomelette.com/node-id-nid-url-path-alias - Gehen Sie zu Inhalt und filtern Sie nach unten, um den Inhalt zu finden, für den Sie die Knoten-ID anzeigen möchten, und bewegen Sie den Mauszeiger über Bearbeiten Verknüpfung. Schauen Sie nach unten, um den Hyperlink zu sehen, den Ihr Browser anzeigt, wenn Sie auf Bearbeiten klicken.

Ana
quelle
Hallo Ana, willkommen bei Drupal Answers. Ihre Antwort ist gut (und ich habe für den Versuch gestimmt), aber die Frage ist, wie die NID programmgesteuert abgerufen werden kann, da sie "aus einem Modul" im Titel enthält.
Darvanen
1

Die zweite Methode in der aktuell akzeptierten Antwort ist die sauberste in D7. Die erste Antwort:

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

ist nur optisch sauberer. Tatsächlich menu_get_object()ruft ziemlich viel Code auf und kann zu unvorhergesehenen Fehlern führen. Ich habe es in einer hook_node_grants()Funktion verwendet und bin auf einen schwerwiegenden PHP-Fehler gestoßen:

Maximale Funktionsverschachtelungsstufe von '256' erreicht, Abbruch!

Die Erklärung finden Sie unter https://drupal.stackexchange.com/a/69232/9158

Die Endlosschleife, die Sie bemerken, wird durch die Tatsache menu_get_object()verursacht , dass Drupal überprüft, ob der aktuell angemeldete Benutzer Zugriff auf den Knoten hat, wodurch Ihre Implementierung von hook_node_grants()erneut aufgerufen wird, welche Aufrufe menu_get_object(), wodurch Ihre Implementierung von hook_node_grants()erneut aufgerufen wird , welche...

Dies wurde mit der zweiten Methode gelöst:

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
quelle
1

In D8:

$node = \Drupal::routeMatch()->getParameter('node');
user373707
quelle
Wickeln Sie die Ausgabe besser wie in drupal.stackexchange.com/a/145826/15055 gezeigt um . Beachten Sie auch, dass dies auf Knotenvorschau- und Knotenrevisionsseiten nicht funktioniert.
Leymannx
-1

Eine weitere Option 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;
  }
}

Wenn Sie die Funktion außerhalb Ihres Moduls verwenden möchten, verwenden Sie nicht das führende _ am Anfang des Funktionsnamens.

Sheldonkreger
quelle
1
Dies ist das gleiche, jedoch mit einem teuren Watchdog-Aufruf auf allen Pfaden, die keine Knoten sind.
Beth
Ich möchte wissen, ob mein Code unerwartet ausfällt. Ich möchte nicht, dass dieser Code auf Nicht-Knoten ausgeführt wird. Watchdog zeigt mir, wo das passiert, damit ich es beheben kann. Andernfalls kann ich nicht nachvollziehen, dass dieser Code ohne Grund ausgeführt wird (auf Nicht-Knoten). Ansonsten ist es dasselbe wie die oben erwähnte D8-Methode.
Sheldonkreger
-1
<?php
if (isset($node->nid) && count($node->nid) > 0){
  $mynodeid = $node->nid;
}
?>
Cptstarling
quelle
Könnten Sie bitte ein paar "Warum" und "Wie" zu Ihrer Antwort hinzufügen? Nur-Code-Antwort könnte funktionieren, aber es hilft kaum, die eigenen Fehler zu verstehen.
Mołot,
Es prüft zunächst, ob der Knoten definiert ist, bevor es ausgeführt wird.
cptstarling