Cara pemrograman mendapatkan NID dari node saat ini

26

Saya sudah meneliti thread lama ini di drupal.org dan itu hanya semacam membuat kepala saya berputar. Menarik ke bawah jalan dan mencoba untuk mengurai NID dari dalamnya? Harus ada cara yang lebih baik.

Dan solusi seperti

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

tidak berfungsi di modul khusus saya (meskipun saya diberitahu mereka berfungsi di templat?). Tidak ada kesalahan atau apa pun, itu hanya instantiates $nodedengan NULLnilai.

Rasanya seperti pasti ada sesuatu yang sangat jelas bahwa saya hilang.

Jadi, bagaimana Anda mendapatkan NID dari node saat ini tanpa template, sambil mengikuti praktik terbaik dan membangun modul yang cukup kuat?

beth
sumber

Jawaban:

50

Dengan asumsi kode Anda berjalan untuk halaman simpul, metode yang saya lihat paling sering digunakan dalam modul inti / kontribu adalah menggunakan menu_get_object()atau arg():

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

atau

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

Saya pribadi lebih suka metode pertama (meskipun penugasan dalam kondisi tidak dianggap sebagai ide yang baik oleh beberapa orang), tetapi keduanya benar-benar valid.

Clive
sumber
1
@Letharion Ya saya merasa sedikit bersalah setiap kali melakukannya;)
Clive
1
@dengan fungsi apa Anda memanggilnya? Dan apakah ini benar-benar halaman simpul yang Anda panggil?
Clive
1
@beth Mereka 100% akan bekerja dengan path alias diaktifkan. Path aliasing tidak ada hubungannya dengan jalur router dari item menu, yaitu node/1, node/2dll. Jika Anda masih mengalami masalah, mungkin ada baiknya memposting pertanyaan lain dengan kode persis yang Anda gunakan, dan memberikan sedikit konteks. Maka kita mungkin bisa menentukan di mana masalahnya terjadi
Clive
1
Solusi satu baris$nid = ($node = menu_get_object()) ? $node->nid : NULL;
timofey.com
3
@sheldonkreger Node sudah dimuat pada titik itu, menu_get_object()(atau bahkan node_load()) baru saja mendapatkannya dari cache statis. Bahkan jika Anda menyebutnya sejak awal, itu masih akan dimuat oleh modul inti nanti di halaman build (karena ini adalah halaman node), dalam hal ini Anda hanya akan menghangatkan cache statis untuk proses selanjutnya
Clive
5

Cara termudah untuk melakukan ini di Drupal 8 sejak arg () tidak lagi berfungsi:

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

Ubah catatan

Pouya Sanooei
sumber
2
Ini juga berfungsi di Drupal 7. Namun, jika Anda berada di halaman yang bukan merupakan simpul, seperti admin / struktur / blok, maka Anda akan menerima nilai yang tidak valid (dalam hal ini, 'struktur'). Cukup periksa untuk melihat apakah path_args [1] adalah bilangan bulat dan Anda mungkin baik-baik saja.
sheldonkreger
Anda mungkin ingin menggunakan arg (1) alih-alih meledak, karena sudah melakukannya untuk Anda: api.drupal.org/api/drupal/includes%21bootstrap.inc/function/arg/…
RobLoach
1
@RobLoach tetapi arg () tidak ada di D8
Pouya Sanooei
4

arg(0)mengembalikan 'simpul' dan arg(1)mengembalikan simpul nid.

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

Tautan ini membantu saya: http://www.webomelette.com/node-id-nid-url-path-alias - Buka Konten dan filter downt untuk menemukan konten yang Anda inginkan untuk melihat Node ID dan arahkan ke Edit. link. Lihat ke bawah untuk melihat hyperlink yang memberitahu browser Anda bahwa itu akan mengikuti jika Anda mengklik Edit.

Ana
sumber
Halo Ana, selamat datang di Jawaban Drupal. Jawaban Anda baik (dan saya telah memberikan suaranya untuk upaya ini), namun pertanyaannya adalah bagaimana cara mendapatkan nid secara programatik karena memuat 'dari modul' pada judul.
Darvanen
1

Metode kedua dalam jawaban yang saat ini diterima adalah yang terbersih di D7. Jawaban pertama:

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

hanya lebih bersih secara visual. Bahkan, menu_get_object()memanggil kode cukup banyak dan dapat menyebabkan kesalahan yang tidak terduga. Saya menggunakannya di dalam hook_node_grants()fungsi dan mengalami kesalahan PHP Fatal:

Fungsi bersarang level maksimum '256' tercapai, batal!

Penjelasannya, ditemukan di /drupal//a/69232/9158

Loop tak terbatas yang Anda perhatikan disebabkan oleh fakta yang menu_get_object()menyebabkan Drupal memverifikasi pengguna yang saat ini masuk memiliki akses ke node, yang menyebabkan implementasi Anda hook_node_grants()dipanggil lagi, yang memanggil menu_get_object(), yang menyebabkan implementasi Anda hook_node_grants()dipanggil lagi , yang ...

Ini dipecahkan dengan menggunakan metode kedua:

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

Di D8:

$node = \Drupal::routeMatch()->getParameter('node');
pengguna373707
sumber
Lebih baik bungkus output seperti yang ditunjukkan di drupal.stackexchange.com/a/145826/15055 . Dan juga patut dicatat bahwa ini tidak akan berfungsi pada halaman pratinjau simpul dan halaman revisi simpul.
leymannx
-1

Opsi lain, di 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;
  }
}

Jika Anda berencana untuk menggunakan fungsi di luar modul Anda, jangan gunakan awalan _ pada awal nama fungsi.

sheldonkreger
sumber
1
Ini adalah hal yang sama tetapi dengan panggilan pengawas mahal di semua jalur yang bukan node.
beth
Saya ingin tahu apakah kode saya gagal secara tidak terduga. Saya tidak ingin kode ini dieksekusi pada non-node, pengawas akan menunjukkan kepada saya di mana itu terjadi sehingga saya dapat memperbaikinya. Kalau tidak, saya tidak akan memiliki jejak bahwa kode ini berjalan tanpa alasan (pada non-node). Kalau tidak sama dengan metode D8 yang disebutkan di atas.
sheldonkreger
-1
<?php
if (isset($node->nid) && count($node->nid) > 0){
  $mynodeid = $node->nid;
}
?>
cptstarling
sumber
Bisakah Anda menambahkan beberapa "mengapa" dan "bagaimana" ke jawaban Anda? Jawaban kode saja mungkin berhasil, tetapi tidak membantu untuk memahami kesalahan seseorang.
Mołot
Pertama-tama memeriksa apakah node didefinisikan sebelum mengeksekusi.
cptstarling