Desenvolvimento de módulos para o Drupal

Desenvolvimento de módulos para o Drupal.

Minhas atividades web receberam recentemente um adereço interessante: O Drupal. E uma das minhas tarefas recentes foi o estudo para uma apresentação sobre desenvolvimento de módulos para o mesmo. Embora apresentação não esteja tão boa quanto gostaria estou disponibilizando o conteúdo. Pretendia acertar algumas coisas antes, mas vou deixar isso para depois.

A apresentação tem duas partes, os slides e um documento que criei antes para me basear.

Você baixar o PDF da Apresentação sobre Desenvolvimento de Módulos para Drupal. Vou reproduzir o documento (rascunho) na integra abaixo.

O Drupal e desenvolvimento de módulos para Drupal

O que é o Drupal:

Drupal é um framework para gestão de conteúdo. É uma ferramenta livre, de código aberto e comunidade atuante.
Drupal fornece a base para construção de portais de internet e intranet para gestão de conteúdo (e conhecimento), permitindo e incentivando a atuação colaborativa, compartilhamento de recursos e publicação de conteúdo de uma forma geral.
É extensível através de módulos, que são como plugins ou add-ons para acrescentar ou alterar funcionalidades no sistema. Quase tudo no Drupal é um módulo.
É desenvolvido em PHP e roda sobre a plataforma Apache + MySql (ou PostgreSQL).
Praticamente todas as funcionalidade do Drupal são módulos, como o conteúdo, o controle de acesso e etc, e todo funcionamento do Drupal é padronizado através de suas interfaces de Hooks e API. 

Drupal: http://drupal.org/

Conteúdo (nodes):

O Conteúdo no Drupal tem sua base em alguns elementos:

  • Campos (Fields)
  • Tipos de conteúdo (Content type)
  • Conteúdo (nó ou node)

Os tipos de conteúdo possuem uma série de campos que podem ser de vários tipos (texto, mapa, data, arquivos, imagens, relacionamentos com outros tipos e etc) que definem o modelo de um conteúdo. Cada conteúdo (ou página) é um nó no drupal, e possui um URL, identificador e o conteúdo dos seus campos de acordo com o tipo de conteúdo ao qual pertence.

Hooks:

Hooks são as formas dos módulos se conectarem ao Drupal e aos outros módulos. O próprio núcleo (core) do Drupal implementa os Hooks que precisa.

Um hook é um gancho a uma chamada do sistema, são funções definidas em pontos chaves do sistema (como carregar um conteúdo, renderizar um bloco, listar itens de menu, salvar um conteúdo, enviar um formulário, etc), assim os módulos registram funções próprias para serem chamadas nesses pontos do sistema.

Quando o sistema vai executar uma ação que possua um gancho (hook), ele executa então todas as funções registradas para esse gancho, fazendo assim a integração do sistema.

Para se registrar um hook basta criar uma função com o nome sendo o o nome do módulo + “_” + o nome do hook. Assim para implementar o hook “menu” no módulo “meumodulo” basta criarmos a função “meumodulo_menu”. 

Exemplo:

A ação de visualizar uma página especifica de um conteúdo, no momento de carregar esse conteúdo existe um gancho chamado “nodeapi”. Então quando o sistema prepara esta página, ao carregar o conteúdo ele passa esse “node” a ser exibido para todas os módulos que registraram uma função no hook “nodeapi”, ele podem então executar ações e alterar esse node, que depois será exibido para o usuário, através da implementação da hook “nodeapi” do próprio módulo “node”.

Mesmo módulos podem criar hooks para que outros módulos possam usar. É assim que drupal integra suas próprias funcionalidades.

São mais de 80 Hooks no núcleo do drupal, mais o que cada módulo pode oferecer (cck, node, contentaccess, etc).

Alguns Hooks importantes são:
 
  • form – Formulários
  • nodeapi – Trabalhar com nodes
  • menu – Itens de menu e páginas (urls)
  • block – Blocos de conteúdo
  • user – Controle de usuário
  • cron – Ações agendadas
Para mais sobre hooks: http://api.drupal.org/api/group/hooks.

APIs:

Outra parte essencial do Drupal são as APIs. APIs são conjuntos de funções relacionadas a alguma utilidade ou parte do sistema. Diferentes dos hooks elas são para serem chamadas livremente aonde quer que os módulos precisem de suas funcionalidades. As APIs são basicamente todas as funções fornecidas pelo core e por todos os módulos do Drupal.

Toda função de todo módulo é disponível para todo outro módulo, tornando o sistema extremamente padronizado através do reuso de recursos.

Então as APIs do drupal são funções fornecidas pelo sistema, como:

  • db_query – Para consultas ao banco de dados
  • t – Para recuperar string traduzidas (internacionalização)
  • drupal_set_message – Mensagens para o usuário
  • node_load – Carregar módulos
  • user_load – Buscar dados de um usuário
  • form_set_error – Mensagens de erro

São milhares de funções disponíveis: Cache API, File API, Field API, Database API, RDF API, Schema API, etc. Mais o que cada módulo pode disponibilizar, e existem muitos módulos que lançam extensas APIs: CCK, Openlayers e etc oferecem APIs.

Para mais sobre API: http://drupal.org/node/326 .

Desenvolvendo seu módulo:

Você não precisa desenvolver um módulo.

O sistema de conteúdo do Drupal é muito flexível, ele pode por si só atender uma grande demanda. E também existem milhares de módulos prontos para as mais variadas funções, alguns extremamente flexíveis como o CCK (que estende o sistema de conteúdo do Drupal). Ainda assim alguém já pode estar trabalhando em um módulo parecido com o que você acha que precisa, e é preferível que se unam os esforços em um só módulo, ou até se já existe um módulo com funcionalidade próxima é mais aconselhável que se unam num módulo só.

A comunidade drupal preza muito por padronização e qualidade, e sempre recomenda (e efetua) a fusão de módulos semelhantes por um módulo mais completo e de maior qualidade.

Mais ainda assim não existe tudo pronto, e em casos de necessidades especificas pode-se precisar de um novo módulo.

O primeiro passo é o http://drupal.org/project/modules aonde você pode conferir os módulos já existentes e ver tem algum que vale a pena usar ou adaptar. A comunidade Drupal é realmente muito forte em integração e união. 

O segundo lugar a visitar é http://groups.drupal.org/contributed-module-ideas , é um grupo de ideias e pedidos para módulos, da mesma forma que pode achar o que precisa  já pronto, pode-se achar ainda em planejamento e até inserir sua ideia e conseguir colaboradores (ou alguém que indique aonde isso já foi feito).

Se for então começar a colocar a mão na massa, a principal referência é http://drupal.org/contributors-guide .

Desenvolvendo seu módulo, mão na massa:

Decidido o módulo que quer, as funcionalidade e etc é hora de começar a programar mesmo. Existe uma padronização importante no código do drupal, que facilita manutenção e colaboração, e está definido no http://drupal.org/coding-standards , de fácil e rápida leitura. A parte de SQL (http://drupal.org/node/2497) também é importante e simples.

A estrutura mais básica de um módulo consiste em três arquivos:

  • nome_do_modulo.info
  • nome_do_modulo.module
  • nome_do_modulo.install

O arquivo de INFO contêm a descrição e informações básicas do módulo, como um arquivo de propriedades, as principais informações são:

  • name: O nome do módulo
  • description: A descrição
  • core: Versão do drupal ao qual se destina
  • version: Versão da instalação [opcional se hospedado no drupal.org]
  • dependencies: Módulos do qual depende [opcional]
  • package: O “pacote” de módulos ao qual pertence, ex: “content”, “views”,”others” [opcional]

Segue um exemplo de arquivo .info:

name = Meu Primeiro Módulo
description = Testa o sistema de módulos do Drupal
version = 0.1
core = 6.x
dependencies[] = cck
O arquivos INSTALL contêm as instruções de instalação (se houver alguma), e é escrito em PHP seguindo o esquema de “hooks”. O arquivo pode implementar dois hooks: “install” e “uninstall”, então se o o módulo se chama “meumodulo”, basta implementar esses dois hooks criando as funções “meumodulo_install” e “meumodulo_uninstall”:
<?php
function meumodulo_install() {
}
function meumodulo_uninstall() {
}

?>

Dentro das funções programa-se os passos da instalação.

Parte comum da instalação de um módulo é a criação de tabelas no banco de dados, para isso usa-se o hook de schema do drupal, implementa o hook como “meumodulo_schema”, no mesmo arquivo:

function meumodulo_schema() {
    $schema[‘meumodulo’] = array(
    ‘description’=>’descrição’,
    ‘fields’=>array(
        ‘id’=>array(‘type’=>’int’,’not null’=>true),
        ‘name’=>array(‘type’=>’text’,’default’=>”)
    ) ,
    ‘primary key’=> array(‘id’)
    );
    return $schema;    
}

Nesse caso precisamos ainda definir que queremos instalar um schema nos hooks install e uninstall:

function meumodulo_install() {
    drupal_install_schema(‘meumodulo’);
}
function meumodulo_uninstall() {
    drupal_uninstall_schema(‘meumodulo’);
}

Finalmente o arquivo MODULE contém os códigos do modulo em si, implementando os hooks e as funcionalidades que o módulo vai oferecer, também é um arquivo PHP comum. Supondo que o módulo adicione uma página simples que exibe alguns dados salvos no banco de dados. Primeiro para criar uma página implementamos o hook “menu” para essa url:

<?php
function meumodulo_menu() {
    $menu = array();
    $menu[‘meumodulo/lista’] = array(
        ‘title’ => ‘Lista de itens do meu modulo’,
        ‘description’ => ”,
        ‘page callback’ => ‘meumodulo_lista’,
        ‘type’ => MENU_NORMAL_ITEM
    ) ;
    return $menu;
}

Agora implementamos o “meumodulo_lista” para montar a página:

function meumodulo_lista() {
    $query = db_query(‘SELECT nome FROM {meumodulo}’);
    $rows= array();
    while($row = db_fectch_array($query)) {
        $rows[] = array($row[‘nome’]);        
    }   
    $header = array(‘Nomes’);
    return theme(‘table’,$header,$rows);        
}

Nessa função usamos 2 APIS importante: A de banco de dados (db_*) e de temas.

A de banco de dados, db_query monta uma consulta SQL e realiza essa no banco de dados usado no Drupal, enquanto db_fetch_array transforma o resultado da consulta em um array e avança o cursor nesse resultado.

A função theme recebe o tipo de thema a ser usado, e os parâmetros de acordo com esse tema, e então monta o html de acordo com o tema atual do drupal. No caso usamos o template de table e passamos a lista de cabeçalhos e as linhas da tabela. Combinações mais complexas são possíveis.

Agora vamos adicionar uma página que permitiria inserir esses dados no banco de dados, primeiro acrescentariamos na nossa implementação do “menu” a nova página:

function meumodulo_menu() {
(…)
    $menu[‘admin/settings/meumodulos’] = array(
        ‘title’ => ‘Admin da lista de items do meu modulo’,
        ‘description’ => ”,
       ‘page callback’ => ‘drupal_get_form’,
        ‘page arguments’ => array(‘meumodulo_admin’),
        ‘access arguments’ => array(‘access administration pages’),

        ‘type’ => MENU_NORMAL_ITEM
    ) ;
(…)
}

Dessa vez adicionamos a restrição de apenas quem tenha acesso a páginas administrativas, e ao invés de montarmos a página vamos usar a api de formulário drupal_get_form, implementamos então o meumodulo_admin:

function meumodulo_admin {
    $form = array();
    $form[‘meucampo’] = array(
        ‘#type’=>’text’,
        ‘#title’=>’Nome’,
        ‘#default_value’=>’Insira um nome’
    );
    $form[‘submit’] = array(
        ‘#type’=>’submit’,
        ‘#value’=>’Save’,
        ‘#submit’=>array(‘meumodulo_admin_submit’)
    );
    return $form;
}
function meumodulo_admin_submit($form,$state) {
    $novo_nome = $state[‘meucampo’];
    db_query(‘insert into {meumodulo}  (nome) values (‘%s’);’,$novo_nome);
}

E assim a primeira funcionalidade do módulo estaria pronta, e pronto para ser instalado.

A instalação de um módulo no Drupal se dá apenas copiando sua pasta para a pasta “modules” do drupal e ativando o módulo através da interface administrativa do drupal.

E depois?

Acontece que geralmente um módulo não é tão simples, e precisa de várias funcionalidades, e como não é possível saber todas ou cobrir todas aqui, segue um roteiro para facilitar o desenvolvimento:

  1. Pense bem no que o módulo vai fornecer e no esquema de banco de dados
  2. Separe as funções do módulo em partes funcionais:
    1. Páginas
    2. Formulários
    3. Listas
    4. Integrações com outros módulos (cck, biblio, openlayer)
    5. Interfaces (blocos/views/temas)
    6. Interações com conteúdo (nodes)
    7. Etc
  3. Para cada função do módulo consulte a lista de hooks para ver qual pode ser usado.
  4. Escolhido o(s) hook(s) a implementar veja se há uma API que ajude na tarefa
  5. Implemente conforme imaginado
  6. Teste
  7. Publique

Outros links importantes:

10 ideias sobre “Desenvolvimento de módulos para o Drupal

  1. Cara, pessoas como você fazem do mundo um lugar menos tenso e mais flexível.
    Parabéns.

    Na Paz,
    André

  2. Olá!

    Fiz exatamente os passos que demonstrou aqui, mas na hora de habilitar o meu módulo, ele exibe um ícone avisando que:

    “Esta versão é incompatível com a versão 6.16 do Drupal.”

    O que eu fiz de errado, ou, o que eu posso fazer para resolver isso?
    Poderia me ajudar?

    Grande abraço!

  3. Corrigindo o erro: “Esta versão é incompatível com a versão 6.16 do Drupal.”

    Na linha “dependencies” é necessário transformá-la em ARRAY. Ou seja:

    DE: dependencies = cck
    PARA: dependencies[] = cck

    Verifique também se o módulo no qual está sendo referenciado na dependência, existe de fato no seu sistema. No meu caso, não existia e a seguinte mensagem apareceu: “Depende de: Cck (faltando)”. Portanto, para solucionar este caso, basta adicionar o módulo CCK e o seu módulo estará OK.

    Tudo resolvido!

  4. Nossa muito bom. Me ajudo bastante esse artigo.

    Porem ainda estou tomando um baile. Pra mim ainda é tudo novo.. comecei praticamente ontem.. em modo de se dizer. :P

    Eu só descobri o que era drupal quando instalei ele através do plano de hospedagem que contratei na http://inter.net.br/.

  5. Que bom que ajudou Carlos, na verdade esse artigo me ajudou também quando escrevi (e ainda consulto :P) hehehe

    Drupal vale totalmente a pena aprender mais profundamente.

    Abraços

  6. Diogo,

    parabéns pelo tuto, cara! Comecei a conhecer o Drupal faz uma semana e esse foi um dos primeiros tutoriais realmente práticos e funcionais que consegui encontrar (principalmente porque já comecei com o D7).

    Gostaria apenas de fazer uma correção quanto à criação do formulário que você demoonstrou. Só consegui fazer o campo de texto aparecer quando alterei a linha ‘#type’=>’text’ para ‘#type’=>’textfield’.

    Outra coisa foi que, no Drupal 7, precisei remover a implementação da função meumodulo_install(), pois a função meumodulo_schema() já cria a estruturas no banco, aí dava pau nessa função porque ele tentava criar de novo. No Drupal 6, esse problema não aconteceu.

    Fora isso, depois de apanhar um pouquinho, consegui fazer o módulo aparecer redondinho.

    Abraços!

  7. Valeu Andrews, que bom que serviu o tutorial e obrigado pelas correções!

    Comecei a usar o D7 agora mas ainda não precisei desenvolver nenhum módulo para ele.

    Abraços.

Comentários encerrados.