Quais são os fundamentos da implementação hook_menu()
?
Gostaria de ver o básico abordado em uma única pergunta, para evitar ter que responder repetidamente as mesmas perguntas semelhantes, mas diferentes.
Esta informação é válida para o Drupal 6 e 7. No Drupal 8, hook_menu()
foi substituído por um novo sistema de roteamento . Abaixo, implementamos hook_menu()
em três etapas simples.
Crie um módulo vazio seguindo as instruções em Como criar um módulo vazio . No código mostrado aqui, supõe-se que o módulo seja chamado helloworld .
Adicione o seguinte código ao arquivo do 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 o módulo e visite http://example.com/hello . (Substitua example.com pelo nome de domínio do seu servidor.)
Você deverá ver a mensagem "Olá, mundo!". É isso aí! Você tem uma hook_menu()
implementação totalmente funcional . A seguir, são apresentados vários tópicos mais avançados hook_menu()
. Em particular, convém ler sobre permissões, pois a página acima poderá ser visualizada por qualquer pessoa.
Se você quiser passar mais dados para o retorno de chamada da página, poderá usar argumentos da página para conseguir isso. Os argumentos da página devem ser uma matriz de argumentos a serem transmitidos para o retorno de chamada da página. Se um número inteiro for usado como argumento, ele representará uma parte da URL, iniciando em 0, incrementada uma vez para cada barra (/). No exemplo a seguir, isso significa que o 0 será transformado em 'olá'.
function helloworld_menu() {
$items['hello'] = array(
'page callback' => 'helloworld_page',
'page arguments' => array(0),
);
return $items;
}
function helloworld_page($argument1) {
return $argument1;
}
As strings serão enviadas literalmente, para que array(0, 'world')
possam ser usadas hello world
novamente.
function helloworld_page($argument1, $argument2) {
return $argument1 . ' ' . $argument2;
}
"Curingas" podem ser usados para aceitar dados arbitrários do URL.
function helloworld_menu() {
$items['hello/%'] = array(
'page callback' => 'helloworld_page',
'page arguments' => array(1),
);
return $items;
}
function helloworld_page($argument1) {
return $argument1;
}
Visitar olá / mundo $argument1
será igual world
.
Geralmente, um argumento de URL será o número que identifica, por exemplo, uma entidade. Para evitar a duplicação do código que converte esse ID no objeto correspondente, o Drupal oferece suporte ao carregamento automático para curingas "nomeados". Quando um curinga nomeado é usado, o Drupal verifica se há uma função com o mesmo nome que o curinga, com o sufixo _load
. Se essa função for encontrada, ela será chamada com o valor do valor na URL e o que for retornado pela função loader será passado para o retorno de chamada da página no lugar do valor original. Como o Drupal já possui essa função para carregar nós node_load()
, podemos obter nós carregados automaticamente e passados para o retorno de chamada da página.
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));
}
Às vezes, será necessário carregar automaticamente mais com base em mais de um argumento. Como apenas o argumento nomeado é passado para o carregador por padrão, é necessário informar explicitamente ao Drupal quais argumentos de carga extra devem ser passados para o carregador. Por exemplo, para carregar uma revisão específica de um nó, é necessário passar para node_load()
um ID de nó e um ID de revisão. Isso pode ser realizado pelo seguinte 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,
é necessário tornar visível o exemplo simples acima, mas dificilmente é o ideal, pois não permite nenhum controle. Qualquer pessoa que tentar visitar / olá terá acesso concedido. A maneira mais fácil de fornecer alguma medida de controle é fornecer um retorno de chamada de acesso, semelhante ao retorno de página da página acima. O código a seguir ainda permite acesso a qualquer pessoa, mas mostra como mover a lógica para uma função chamada no momento do acesso, permitindo uma lógica mais complexa.
/**
* 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 não é necessariamente a melhor maneira, pois o uso de uma função personalizada geralmente duplicará desnecessariamente o código. Uma maneira melhor será, na maioria das vezes, usar user_access()
. Juntos, o retorno de chamada de acesso é possível definir argumentos de acesso. É possível exigir que a página seja visível pelos usuários com a permissão de acessar perfis de usuário com o código a seguir.
/**
* 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 o retorno de chamada de acesso, por padrão, é user_access, ele pode ser deixado de fora, como no código acima.
A hook_menu()
documentação oficial fornece muito mais informações sobre os casos de uso mais complexos do gancho.
title
propriedade é necessária para todos os itens devolvidos dehook_menu()