Nesse tutorial iremos criar um módulo para o Drupal, o foco aqui será entendermos a estrutura do módulo em si, e não em criarmos algo super complexo.
O que é Drupal?
Drupal é um CMS (Content management system) de código aberto fantástico através do qual você pode construir sites modernos. Sejam eles blogs pessoais ou um e-commerce.
O que são módulos?
Um módulo é um código que altera ou adiciona uma funcionalidade ao Drupal. Você pode usar módulos criados pela comunidade ou criar os seus próprios.
Drupal Vs. WordPress
É impossível citar um CMS sem mencionar também o WordPress, o processo de escolha do CMS certo é um passo extremamente importante. Escolher a plataforma errada e você terá uma batalha difícil logo no início do seu projeto. No geral, o Drupal é um CMS bastante sólido, possui muitos recursos e é otimizado para desempenho e segurança de alto nível desde o primeiro dia. é muito flexível, mas tem uma curva de aprendizado maior. Se você não tem tempo para aprender a programar e quer construir um site o mais rápido possível, considere usar o WordPress.
Iniciando o projeto
Para esse Projeto iremos utilizar vamos precisar do Lando e do Composer.
Vamos Iniciar um novo projeto Drupal com o composer:
composer create-project drupal/recommended-project drupal_project
Abrimos o diretório do projeto:
cd drupal_project
E criamos a configuração do Lando:
lando init
Nas telas a seguir selecionamos as opções:
# From where should we get your app's codebase?
❯ current working directory
# From where should we get your app's codebase? current working directory
# What recipe do you want to use?
❯ drupal9
# Where is your webroot relative to the init destination?
web
# What do you want to call this app?
drupal_project
E podemos iniciar o projeto com:
lando start
Tenha calma, esse processo pode demorar um pouco dependo das imagens docker que serão baixadas e sua conexão com a internet.
Assim que finalizado você verá as informações do projeto na tela, mas pode ver à qualquer momento com:
lando info
Para agilizar o processo de instalação iremos utilizar o drush, que é uma ferramenta de linha de comando para o Drupal.
Primeiro, instalamos o drush:
lando composer require drush/drush
E com ele instalamos o Drupal:
lando drush site:install --db-url=mysql://drupal9:drupal9@database/drupal9 -y
A senha do administrador aparacerá na tela, não se esqueça de anotar.
Com isso, como mágica temos o Drupal instalado, você pode acessá-lo em https://drupal_project.lndo.site.
E com isso temos um ambiente de desenvolvimento para o Drupal configurado.
Criando o módulo
Antes de tudo
Antes de começar aqui fica uma dica importante, o Drupal cria caches das páginas e com isso as vezes nossas alterações parecem não terem efeito, é muito importante limpar-mos esse cache para ter certeza, basta utilizarmos o comando:
lando drush cr
A ideia do módulo
Lembrando que o foco aqui é você ter uma noção de como a estrutura de um módulo funciona, não iremos criar nada complexo por enquanto, mas será um ótimo começo.
Com isso vamos criar um módulo para adicionar uma política de uso no formulário cadastro de usuário.
A estrutura do módulo
Essa será a estrutura do nosso módulo:
Vamos passar por cada um destes arquivos.
Iniciando o módulo
module.info.yml
Para o Drupal entender um diretório como módulo precisamos criar o .info.yml
.
Vamos criar a pasta do modulo em web/modules/custom/policy
e, importante saber, o nome do diretório e arquivos .yml deverão seguir o mesmo padrão, no nosso caso a pasta policy
conterá o arquivo policy.info.yml
.
Com essa informação vamos criar o arquivo web/modules/custom/policy/policy.info.yml
com o seguinte conteúdo:
name: Policy
description: "Custom module to manage the Policy terms"
package: Custom
core_version_requirement: ^8 || ^9
type: module
Só com isso se formos em https://drupal_project.lndo.site/admin/modules já veremos o módulo Policy
aparecendo.
Salvando as configurações de nossa politica no banco de dados
module.schema.yml
Vamos criar um local onde iremos utilizar para armazenar nossos termos, onde fique mais fácil alterarmos no futuro, para isso vamos criar um schema de configuração, onde será possível alterar sempre que necessário.
Vamos criar o arquivo web/modules/custom/policy/config/schema/policy.schema.yml
com o seguinte conteúdo:
policy.settings:
type: config_object
label: "Policy Content Type Settings"
mapping:
title:
type: text
label: "Title"
message:
type: text
label: "Policy terms"
module.settings.yml
O arquivo .settings.yml
será o valor padrão dessas configurações, criado no momento que o módulo é instalado, então criamos o arquivo web/modules/custom/policy/config/install/policy.settings.yml
com o seguinte conteúdo:
title: "Policy terms"
message:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam a facilisis dolor, aliquam ullamcorper odio. Ut sollicitudin imperdiet ante, quis placerat sapien. Fusce sed vestibulum nisi. Morbi vel rhoncus dui, eu semper dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Sed pulvinar lorem eros, et fringilla arcu blandit nec. Praesent sem nunc, hendrerit vitae arcu at, rhoncus sagittis est. Fusce ultrices venenatis rhoncus.
Duis euismod, elit semper ultrices molestie, eros elit cursus diam, eu cursus justo urna vel lacus. Donec ornare efficitur pulvinar. Suspendisse pulvinar ipsum ipsum. Vestibulum eu fermentum felis, ut accumsan nibh. Proin blandit urna arcu, at posuere nunc hendrerit at. Sed finibus diam vel vulputate mollis. Quisque feugiat iaculis aliquet. Duis auctor enim a risus tincidunt bibendum. Proin augue tellus, finibus quis lorem interdum, mattis condimentum nunc. Nam et condimentum nibh. Sed eleifend sapien a massa sollicitudin vestibulum. Donec fringilla elit nisi, et pretium dolor dapibus in.
Aliquam ac est vestibulum, tempus odio quis, tempor leo. Quisque dui eros, laoreet id diam ac, consectetur ultrices lorem. Duis augue ante, venenatis ac mollis sed, posuere in purus. Vivamus magna tortor, fringilla eget felis sed, mattis finibus magna. Proin mauris dui, tempor ut ante id, aliquam ultrices nisi. Aenean pulvinar sapien at enim sagittis vehicula. Donec tristique sapien eget felis tincidunt, ut commodo magna pulvinar. Quisque vel tempor dui.
Phasellus luctus dolor sed odio pharetra, et interdum libero sollicitudin. Proin facilisis justo ac felis bibendum, ut commodo tellus lacinia. Fusce viverra eget augue nec aliquam. Quisque leo tortor, volutpat a facilisis tincidunt, molestie ut ante. Maecenas ornare commodo lacus, nec lobortis eros finibus eget. Nulla at nulla nec orci vehicula egestas semper viverra tellus. In scelerisque neque ac urna vulputate aliquet. Maecenas ultrices imperdiet ligula, eu commodo nisi. Praesent sodales felis metus, sed ultrices ipsum sodales ut. Pellentesque faucibus ligula risus, at ornare metus varius sit amet. Donec mollis non urna ut auctor. In imperdiet arcu ex, non vulputate tortor bibendum rutrum. Phasellus convallis metus in imperdiet finibus. Aenean maximus eget nibh quis interdum.
Fusce dictum, metus at tempus tincidunt, tortor tortor porta leo, non aliquam metus arcu in sem. Pellentesque vel nulla orci. Aliquam dolor elit, accumsan vel libero et, viverra auctor augue. Sed vulputate volutpat leo, nec euismod mauris congue ullamcorper. Curabitur quis diam vestibulum, aliquam nisi nec, vehicula lacus. Sed id luctus lorem. Praesent et ante vel arcu hendrerit efficitur vitae eu augue. Phasellus vulputate metus ac sapien cursus mattis. Donec nisl enim, ornare id tortor vitae, fermentum sodales sem. Nam et ligula nec purus bibendum scelerisque. Aliquam quis enim ut nibh placerat facilisis vestibulum sed arcu. Nunc eu orci eu nunc ultricies blandit eget a lorem."
Criando nossa página de Politica
Para exibir exibir esse conteúdo em uma página vamos precisar criar um controller e uma rota pra que seja exibido em /policy
do nosso site.
Criando o controller
Criamos o arquivo web/modules/custom/policy/src/Controler/PolicyController.php
com:
<?php
namespace Drupal\policy\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Config\ConfigFactoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Controller for display a Policy terms.
*/
class PolicyController extends ControllerBase {
/**
* Config object for PolicyController configuration.
*
* @var \Drupal\Core\Config\Config
*/
protected $config;
/**
* PolicyController constructor.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* Configuration object factory.
*/
public function __construct(ConfigFactoryInterface $config_factory) {
$this->config = $config_factory->get('policy.settings');
}
/**
* {@inheritdoc}
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The Drupal service container.
*
* @return static
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('config.factory')
);
}
/**
* {@inheritDoc}
*/
public function content() {
$message = $this->config->get('message');
return [
'#type' => 'markup',
'#markup' => $message,
];
}
}
Criando a rota
Vamos criar também um arquvio de rota onde chamará nosso controller exibindo as políticas em web/modules/custom/policy/policy.routing.yml
com:
policy.content:
path: "/policy"
defaults:
_controller: '\Drupal\policy\Controller\PolicyController::content'
_title: "Policy terms"
requirements:
_permission: "access content"
E acessando o /policy
já podemos ver nossa página de politicas.
Conheça as Hooks
Hooks, ou ganchos, em uma tradução livre, são métodos que conseguem alterar um comportamento padrão do Drupal, assim como os nomes dos arquivos eles devem seguir um padrão de nome para funcionarem corretamente.
No nosso caso criaremos uma hook para alterar o funcionamento da página de registro de novo usuário, localizado em /user/register
para adicionarmos um checkbox contendo um link para as políticas do site.
module.module
O arquivo .module
é onde criaremos nossos hooks, ele é tratado como um arquivo .php
mas devemos manter o padrão do nome, para isso vamos criar o aquivoweb/modules/custom/policy/policy.module
com:
<?php
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface;
/**
* Implements hook_form_user_register_form_alter().
*/
function policy_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['policy_terms'] = [
'#type' => 'checkbox',
'#default_value' => FALSE,
'#title' => t('I have read and accept <a href="@policy_terms" target="_blank" }" >the policy terms</a>.', ['@policy_terms' => Url::fromRoute('policy.content')->toString()]),
'#required' => TRUE,
];
}
Reparem que não estamos exatamente utilizando um HTML puro, estamos usando a API do Drupal para adicionarmos um elemento e ele se encarrega de gerar um o código na página, se formos em nossa página de cadastro veremos a checkbox já está aparecendo.
Abrindo a política em um modal
Por mais que nosso checkbox já esteja funcionando não vejo necessidade de abrir uma nova página ao clicar no link the policy terms
, mas ainda assim acho importante termos a página /policy
para usarmos em outro local, e é aqui que a o Drupal brilha mais uma vez, vamos modificar nosso arquivo policy.module
para que a página seja aberta em um modal, e bastar fazermos a seguinte alteração:
- '#title' => t('I have read and accept <a href="@policy_terms" target="_blank" }" >the policy terms</a>.', ['@policy_terms' => Url::fromRoute('policy.content')->toString()]),
+ '#title' => t('I have read and accept <a href="@policy_terms" target="_blank" class="use-ajax" data-dialog-options="{"width":"60vw" }" data-toggle="modal" data-dialog-type="modal">the policy terms</a>.', ['@policy_terms' => Url::fromRoute('policy.content')->toString()]),
Lembre-se de limpar o cache antes de testar.
E assim, como mágica, o Drupal abre a página em um modal, e ainda mantém a nossa rota, demais né?
Alterando nossas configurações
Com tudo criado e funcionando ainda nos resta criarmos uma forma de alteramos nossas políticas quando necessário, para isso criamos um arquivo web/modules/custom/policy/src/Form/PolicySettingsForm.php
com:
<?php
namespace Drupal\policy\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Defines a form to update the Policy message config.
*/
class PolicySettingsForm extends ConfigFormBase {
/**
* {@inheritDoc}
*/
public function getFormId() {
return 'policy_form_update';
}
/**
* {@inheritDoc}
*/
protected function getEditableConfigNames() {
return [
'policy.settings',
];
}
/**
* {@inheritDoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
// Form Constructor.
$form = parent::buildForm($form, $form_state);
$config = $this->config('policy.settings');
$form['message'] = [
'#type' => 'textarea',
'#title' => $this->t('Update Policy Terms'),
'#default_value' => $config->get('message'),
'#description' => $this->t('Write policy terms'),
];
return $form;
}
/**
* {@inheritDoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('policy.settings');
$config->set('message', $form_state->getValue('message'));
$config->save();
return parent::submitForm($form, $form_state);
}
}
E voltamos no aqrquivo web/modules/custom/policy/policy.routing.yml
e no final dele adicionamos:
...
policy.form_update:
path: "/admin/config/content/policy"
defaults:
_form: '\Drupal\policy\Form\PolicySettingsForm'
_title: "Update Policy Terms"
requirements:
_role: "administrator"
Então ao acessarmos o endereço /admin/config/content/policy
com um usuário adminsitrador veremos a seguinte página:
Adicionando o link ao painel administrativo
Para facilitar mais um pouco vamos criar um link dentro do painel de administrativo para podermos acessar essas configuraçoões, assim não precisamos lembra sempre desse endereço quando formos alterar.
E como tudo até o momento basta criarmos o arquivo web/modules/custom/policy/policy.link.menu.yml
com:
policy.form_update:
title: "Policy Terms Settings"
description: "Update policy terms"
route_name: policy.form_update
parent: system.admin_config_content
weight: 10
Então se clicarmos em Configuration
no menu administrativo veremos o link Policy Terms Settings
.
Com isso temos nosso módulo finalizado.
O código deste tutorial está neste repositório do GitHub .