¿Cuáles son los fundamentos de la implementación hook_menu()
?
Me gustaría ver los conceptos básicos cubiertos en una sola pregunta, para evitar tener que responder una y otra vez las mismas preguntas similares pero diferentes.
Esta información es válida para Drupal 6 y 7. En Drupal 8, hook_menu()
ha sido reemplazado por un nuevo sistema de enrutamiento . A continuación implementamos hook_menu()
en tres simples pasos.
Cree un módulo vacío siguiendo las instrucciones en Cómo crear un módulo vacío . En el código que se muestra aquí, se supone que el módulo se llama helloworld .
Agregue el siguiente código al archivo del módulo.
/**
* 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!';
}
Habilite el módulo y visite http://example.com/hello . (Reemplace example.com con el nombre de dominio de su servidor).
Debería ver el mensaje "¡Hola, mundo!". ¡Eso es! Tienes una hook_menu()
implementación totalmente funcional . Lo que sigue son varios temas más avanzados con respecto hook_menu()
. En particular, es posible que desee leer acerca de los permisos, ya que cualquiera podrá ver la página anterior.
Si desea pasar más datos a la devolución de llamada de la página, puede usar argumentos de página para lograr esto. Los argumentos de la página deben ser una matriz de argumentos para pasar a la devolución de llamada de la página. Si se usa un entero como argumento, representará una parte de la URL, comenzando desde 0, incrementada una vez por cada barra inclinada (/). En el siguiente ejemplo, esto significa que el 0 se convertirá en 'hola'.
function helloworld_menu() {
$items['hello'] = array(
'page callback' => 'helloworld_page',
'page arguments' => array(0),
);
return $items;
}
function helloworld_page($argument1) {
return $argument1;
}
Las cadenas se enviarán literalmente, por lo que array(0, 'world')
podrían usarse para hello world
salir nuevamente.
function helloworld_page($argument1, $argument2) {
return $argument1 . ' ' . $argument2;
}
Los "comodines" se pueden usar para aceptar datos arbitrarios de la URL.
function helloworld_menu() {
$items['hello/%'] = array(
'page callback' => 'helloworld_page',
'page arguments' => array(1),
);
return $items;
}
function helloworld_page($argument1) {
return $argument1;
}
Visitando hola / mundo, $argument1
será igual world
.
A menudo, un argumento de URL será el número que identifica, por ejemplo, una entidad. Para evitar duplicar el código que convierte esta ID en su objeto correspondiente, Drupal admite la carga automática de comodines "con nombre". Cuando se utiliza un comodín con nombre, Drupal buscará una función con el mismo nombre que el comodín, con el sufijo _load
. Si se encuentra dicha función, se llamará con el valor del valor en la URL, y lo que devuelva la función del cargador se pasará a la devolución de llamada de la página en lugar del valor original. Dado que Drupal ya tiene dicha función para cargar nodos node_load()
, podemos hacer que los nodos se carguen automáticamente y pasen a la página de devolución de llamada.
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));
}
A veces, será necesario cargar automáticamente más en función de más de un argumento. Dado que solo el argumento nombrado se pasa al cargador de forma predeterminada, es necesario decirle explícitamente a Drupal qué argumentos de carga adicionales se deben pasar al cargador. Por ejemplo, para cargar una revisión específica de un nodo, es necesario pasar a node_load()
una ID de nodo y una ID de revisión. Eso se puede lograr con el siguiente código.
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));
}
'access callback' => TRUE,
es necesario para que el simple ejemplo anterior sea visible, pero no es ideal, ya que no permite ningún control. Cualquier persona que intente visitar / hola tendrá acceso. La forma más fácil de proporcionar alguna medida de control es proporcionar una devolución de llamada de acceso, al igual que la devolución de llamada de la página desde arriba. El siguiente código todavía permite el acceso a cualquier persona, pero muestra cómo mover la lógica a una función llamada en el momento de acceso, lo que permite una lógica más compleja.
/**
* 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;
}
Esta no es necesariamente la mejor manera, ya que el uso de una función personalizada a menudo duplicará innecesariamente el código. Una mejor manera será, la mayoría de las veces, usar user_access()
. Juntos, la devolución de llamada de acceso es posible establecer argumentos de acceso. Es posible requerir que la página sea visible para los usuarios con el permiso de acceso a los perfiles de usuario con el siguiente código.
/**
* 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;
}
Como la devolución de llamada de acceso por defecto es user_access, puede omitirse, como en el código anterior.
La hook_menu()
documentación oficial proporciona mucha más información sobre los casos de uso más complejos para el gancho.
title
propiedad se requiere para todos los artículos devueltos desdehook_menu()