it-swarm-es.com

¿Cómo debo implementar hook_menu ()?

¿Cuáles son los fundamentos de la implementación de 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.

102
Letharion

Esta información es válida para Drupal 6 y 7. En Drupal 8, hook_menu() ha sido reemplazado por nuevo sistema de enrutamiento . A continuación implementamos hook_menu() en tres simples pasos.

Paso uno

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 .

Segundo paso

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!';
}

Paso tres

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! Tiene una implementación hook_menu() totalmente funcional. Lo que sigue son varios temas más avanzados con respecto a hook_menu(). En particular, es posible que desee leer sobre los permisos, ya que cualquiera podrá ver la página anterior.

Argumentos

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 utiliza un número 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ía usarse para obtener hello world 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 hello/world, $argument1 Será igual a world.

Argumento de carga automática

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 carga automática para comodines "con nombre". Cuando se usa un comodín con nombre, Drupal verificará para 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 pasar a la página de devolución de llamada en lugar del valor original. Dado que Drupal ya tiene dicha función para cargar nodos, node_load() , podemos consigue 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));
}

Carga automática avanzada

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

Permisos

'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 cierta medida de control es proporcionar una devolución de llamada de acceso, muy similar a 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, permitiendo así 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 forma mejor 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.

Temas más avanzados

La documentación oficial de hook_menu() proporciona mucha más información sobre los casos de uso más complejos para el gancho.

147
Letharion