Come devo implementare hook_menu ()?


103

Quali sono i fondamenti dell'attuazione hook_menu()?

Vorrei vedere le basi trattate in una sola domanda, per evitare di dover rispondere sempre alle stesse domande simili ma diverse.

Risposte:


148

Questa informazione è valida per Drupal 6 e 7. In Drupal 8, hook_menu()è stata sostituita dal nuovo sistema di routing . Di seguito implementiamo hook_menu()in tre semplici passaggi.

Primo passo

Crea un modulo vuoto seguendo le istruzioni in Come creare un modulo vuoto . Nel codice mostrato qui, si presume che il modulo sia chiamato helloworld .

Passo due

Aggiungi il seguente codice al file del modulo.

/**
 * Implements hook_menu().
 */
function helloworld_menu() {
  $items['hello'] = array(
    'title' => 'Hello world!',
    'page callback' => 'helloworld_page',
    'access callback' => TRUE,
  );

  return $items;
}

/**
 * Page callback for /hello.
 */
function helloworld_page() {
  return 'Hello world!';
}

Fase tre

Abilita il modulo e visita http://example.com/hello . (Sostituisci esempio.com con il nome di dominio per il tuo server.)
Dovresti vedere il messaggio "Ciao mondo!". Questo è tutto! Hai hook_menu()un'implementazione pienamente funzionante . Quelli che seguono sono vari argomenti più avanzati riguardanti hook_menu(). In particolare, potresti voler leggere le autorizzazioni, poiché la pagina sopra sarà visibile a chiunque.

argomenti

Se si desidera passare più dati al callback della pagina, è possibile utilizzare gli argomenti della pagina per raggiungere questo obiettivo. Gli argomenti della pagina dovrebbero essere una matrice di argomenti da passare al callback della pagina. Se un intero viene usato come argomento, rappresenterà una parte dell'URL, a partire da 0, incrementato una volta per ogni barra (/). Nel seguente esempio, ciò significa che lo 0 verrà trasformato in "ciao".

function helloworld_menu() {
  $items['hello'] = array(
    'page callback' => 'helloworld_page',
    'page arguments' => array(0),
  );

  return $items;
}

function helloworld_page($argument1) {
  return $argument1;
}

Le stringhe verranno inviate alla lettera, quindi array(0, 'world')potrebbero essere utilizzate per hello worlduscire di nuovo.

function helloworld_page($argument1, $argument2) {
  return $argument1 . ' ' . $argument2;
}

I "caratteri jolly" possono essere utilizzati per accettare dati arbitrari dall'URL.

function helloworld_menu() {
  $items['hello/%'] = array(
    'page callback' => 'helloworld_page',
    'page arguments' => array(1),
  );

  return $items;
}

function helloworld_page($argument1) {
  return $argument1;
}

Visitando ciao / mondo, $argument1sarà uguale world.

Argomento caricamento automatico

Spesso un argomento URL sarà il numero che identifica, ad esempio, un'entità. Per evitare la duplicazione del codice che converte questo ID nel suo oggetto corrispondente, Drupal supporta il caricamento automatico dei caratteri jolly "nominati". Quando viene utilizzato un jolly con nome, Drupal verificherà una funzione con lo stesso nome del jolly, con il suffisso _load. Se viene trovata una tale funzione, verrà chiamata con il valore del valore nell'URL e tutto ciò che viene restituito dalla funzione caricatore verrà passato al callback della pagina al posto del valore originale. Poiché Drupal ha già una tale funzione per il caricamento dei nodi node_load(), possiamo ottenere nodi caricati automaticamente e passati al callback della pagina.

function helloworld_menu() {
  $items['hello/%node'] = array(
    'page callback' => 'helloworld_page',
    'page arguments' => array(1),
  );

  return $items;
}

function helloworld_page($node) {
  return t('Hello node (ID = !nid)', array('!nid' => $node->nid));
}

Caricamento automatico avanzato

A volte, sarà necessario caricare automaticamente di più in base a più di un argomento. Dal momento che solo l'argomento denominato viene passato al caricatore per impostazione predefinita, è necessario indicare esplicitamente a Drupal quali argomenti di carico extra devono essere passati al caricatore. Ad esempio, per caricare una revisione specifica di un nodo, è necessario passare a node_load()un ID nodo e un ID revisione. Ciò può essere realizzato con il seguente codice.

function helloworld_menu() {
  $items['hello/%node/revision/%'] = array(
    'page callback' => 'helloworld_page',
    'page arguments' => array(1),
    'load arguments' => array(3),
  );

  return $items;
}

function helloworld_page($node) {
  return t('Hello node (ID = !nid, revision ID = !rid)', array('!nid' => $node->nid, '!rid' => $node->vid));
}

permessi

'access callback' => TRUE,è necessario per rendere il semplice esempio sopra visibile a tutti, ma non è certo l'ideale, in quanto non consente alcun controllo. A chiunque tenti di visitare / ciao verrà concesso l'accesso. Il modo più semplice per fornire una certa misura di controllo è fornire un callback di accesso, proprio come il callback della pagina dall'alto. Il codice seguente consente ancora l'accesso a chiunque, ma mostra come spostare la logica in una funzione chiamata al momento dell'accesso, consentendo in tal modo una logica più complessa.

/**
 * Implements hook_menu().
 */
function helloworld_menu() {
  $items['hello'] = array(
    'page callback' => 'helloworld_page',
    'access callback' => 'helloworld_access',
  );

  return $items;
}

/**
 * Access callback for /hello.
 */
function helloworld_access() {
  return TRUE;
}

Questo non è necessariamente il modo migliore, poiché l'uso di una funzione personalizzata spesso duplicherà inutilmente il codice. Un modo migliore sarà, il più delle volte, da usare user_access(). Insieme al callback di accesso è possibile impostare argomenti di accesso. È possibile richiedere che la pagina sia visualizzabile dagli utenti con l' autorizzazione di accesso ai profili utente con il seguente codice.

/**
 * Implements hook_menu().
 */
function helloworld_menu() {
  $items['hello'] = array(
    'page callback' => 'helloworld_page',
    'access callback' => 'user_access',
    'access arguments' => array('access user profiles'),
  );

  return $items;
}

Poiché il callback di accesso per impostazione predefinita è user_access, può essere lasciato fuori, come nel codice sopra.

Argomenti più avanzati

La hook_menu()documentazione ufficiale fornisce molte più informazioni sui casi d'uso più complessi per il hook.


3
Eccezionale! Per motivi di completezza, la titleproprietà è richiesta per tutti gli articoli restituiti dahook_menu()
Clive

1
So che i documenti lo dicono, ma quando ho provato in D7, non era così. Potrei aggiungerlo al primo esempio, suppongo, ma volevo mantenere le cose al minimo assoluto per renderlo il più semplice possibile.
Letharion,

1
Direi che aggiungere un titolo a una pagina è una delle cose minime assolute che potresti voler fare con hook_menu () ma è il tuo post: P Potrebbe valere la pena correggere gli errori di sintassi (esempi di codice 2, 4, 5 & 6), in modo che le persone possano copiare e incollare
Clive

1
Argh, inizialmente ero diligente nell'esecuzione del codice, ma col passare del tempo sono diventato più sciatto e ho iniziato a copiare e incollare. Risolti gli errori di sintassi, almeno quelli che ho visto;) Bene, hai ragione che ci dovrebbe essere un titolo ovviamente, quindi ne ho aggiunto uno all'esempio iniziale.
Letharion,

1
Come potrei registrare un file php in un percorso usando hook_menu? È un file php scritto personalizzato che include bootstrap drupal, utilizza variabili di sessione drupal e accetta un argomento che è un ID utente.
Елин Й.
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.