Як програмно отримати NID поточного вузла


26

Я перебрав цю стару нитку на drupal.org, і це просто змушує мою голову крутитися. Спустивши шлях і намагаючись розібрати NID зсередини? Має бути кращий спосіб.

І такі рішення, як

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

не працюють у моєму користувальницькому модулі (хоча мені кажуть, що вони працюють у шаблонах?). Ніякої помилки чи нічого, вона просто $nodeстворює NULLзначення.

Таке враження, що я маю щось дійсно очевидно, що я пропускаю.

Отже, як отримати NID поточного вузла без шаблону, дотримуючись кращих практик та створивши досить надійний модуль?

Відповіді:


50

Якщо припустити, що ваш код працює для сторінки вузла, методи, які я бачу найчастіше, використовуються в модулях core / contrib, або використовують, menu_get_object()або arg():

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

або

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
@Letharion Так, я відчуваю себе трохи винним кожен раз, коли це роблю;)
— Клайв

1
@beth Яку функцію ви викликаєте? І це напевно сторінка вузла, на яку ви її називаєте?
— Клайв

1
@beth Вони на 100% працюватимуть із включеним згладжуванням шляху. Псевдонім шляху не має нічого спільного з маршрутизатором пункту меню, який є node/1і node/2т. Д. Якщо у вас все ще виникають проблеми, можливо, варто поставити ще одне питання з точним кодом, який ви використовуєте, і надайте трохи контексту. Тоді ми, можливо, зможемо точно визначити, де відбувається проблема
— Клайв

1
Рішення для єдиного рядка$nid = ($node = menu_get_object()) ? $node->nid : NULL;
— timofey.com

3
@sheldonkreger Вузол, який вже завантажений до цього моменту, menu_get_object()(або навіть node_load()) просто отримує його з статичного кешу. Навіть якщо ви називаєте це на початку, він все одно буде завантажений основним модулем пізніше в збірці сторінки (оскільки це сторінка вузла), у такому випадку ви просто зігрієте статичний кеш для наступного процесу
— Клайв

5

Найпростіший спосіб зробити це в Drupal 8, оскільки arg () більше не працює:

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

Змінити запис


2
Це також працює в Drupal 7. Однак, якщо ви знаходитесь на сторінці, яка не є вузлом, наприклад, адміністратор / структура / блоки, ви отримаєте недійсне значення (у цьому випадку - "структура"). Просто перевірте, чи є path_args [1] цілим числом, і ви, напевно, добре.
— sheldonkreger

Ви, ймовірно, захочете використовувати arg (1) замість вибухати, оскільки це вже зробили для вас: api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/…
— RobLoach

1
@RobLoach, але arg () не існує в D8
— Pouya Sanooei


1

Це пов’язане мені допомогло: http://www.webomelette.com/node-id-nid-url-path-alias - Перейдіть до вмісту та відфільтруйте спад, щоб знайти вміст, для якого ви хочете побачити ідентифікатор вузла, і наведіть на нього курсор на Змінити посилання. Подивіться вниз, щоб побачити гіперпосилання, у якому ваш веб-переглядач повідомляє, що воно відбуватиметься, якщо натиснути Редагувати.


Привіт, Ана, ласкаво просимо до друпальських відповідей. Ваша відповідь хороша (і я проголосував за спробу), однак питання полягає в тому, як програмно отримати nid, оскільки він містить "з модуля" в заголовку.
— Дарванен

1

Другий метод у прийнятій на даний момент відповідь є найчистішим у D7. Перша відповідь:

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

є лише візуально чистішим. Насправді, menu_get_object()виклик досить багато коду і може призвести до непередбачених помилок. Я використовував його всередині hook_node_grants()функції і натрапив на фатальну помилку PHP:

Досягнуто максимального рівня гніздування функції '256', перериваючи!

Пояснення, знайдене на веб- сайті /drupal//a/69232/9158

Нескінченний цикл, який ви помічаєте, викликаний тим, що menu_get_object()змушує Drupal перевіряти, що користувач, який зараз увійшов, має доступ до вузла, що призводить до того, що ваша реалізація hook_node_grants()буде викликана ще раз, що викликає menu_get_object(), що призводить до того, що ваша реалізація hook_node_grants()знову буде викликана , котрий...

Це було вирішено за допомогою другого методу:

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

Ще один варіант у 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;
  }
}

Якщо ви плануєте використовувати функцію поза модулем, не використовуйте _ _ на початку імені функції.


1
Це те саме, але з дорогим сторожовим викликом на всіх шляхах, які не є вузлами.
— beth

Мені подобається знати, якщо мій код несподівано виходить з ладу. Я не хотів би, щоб цей код виконувався на невузлах, сторожовий собака покаже мені, де це відбувається, щоб я міг його виправити. Інакше я не матиму жодного сліду, що цей код працює без причини (на невузлах). Інакше це те саме, що і метод D8, згаданий вище.
— sheldonkreger

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

Не могли б ви додати до своєї відповіді кілька "whys" та "hows"? Відповідь, кодовий лише для коду, може спрацювати, але навряд чи допоможе зрозуміти помилки.
— Молот

Він спочатку перевіряє, чи визначений вузол перед виконанням.
— cptstarling
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.