SlideShare a Scribd company logo
1 of 37
Download to read offline
INTRODUCCIÓN
AL BACKEND
DE DRUPAL
(WORKSHOP)
Zaragoza
Drupal Day Spain 2019
David Rodríguez
@davidjguru
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
BIENVENIDA
David Rodríguez Vicente
(Drupal) Center Leader Specialist en Everis Sevilla
Responsable técnico de Proyectos basados en Drupal
Director técnico del equipo Drupal de Everis Center Sevilla
Profile
https://www.linkedin.com/in/davidjguru
https://www.drupal.org/u/davidjguru
Blogs
https://medium.com/@davidjguru (esp)
https://davidjguru.github.io (en)
Repos
https://gitlab.com/davidjguru
https://github.com/davidjguru
Contacto
https://twitter.com/davidjguru
davidjguru@gmail.com
https://twitter.com/DrupalSevilla
HELLO MY NAME IS.
1, HOLA QUE TAL
2
Ver Drupal por dentro
Introducción a tu nuevo backend favorito
Progresivo, iterativo e incremental
Asentemos conceptos básicos
Observa las posibilidades
Experiencia Inicial Motivadora
Cogiendo cariño a Drupal
PRESENTACIÓN
2, dE QUÉ VA ESTO
picture from Unsplash, user Konstantin Aal - @kostic86
Practicaremos creando nuevos módulos Custom de Drupal.
Expondremos los fundamentos del sistema de rutas y
controladores de Drupal con la idea de construir accesos a
nuestros formularios. Conoceremos los fundamentos de la
creación de formularios con Drupal, crearemos varios tanto a
mano como con su versión rápida usando Drupal Console.
Dotaremos a los campos de formulario con valores ya cargados
previamente, y para ese pre-filling de campo usaremos algunos
servicios proporcionados por Drupal. Usaremos servicios web para
realizar peticiones externas vía REST y cargar información en
nuestros formularios. Realizaremos consultas a la base de datos y
cargaremos valores dinámicamente en nuestro formulario.
PRESENTACIÓN
2, qUÉ VAMOS A HACER
MÓDULOS CUSTOM EN DRUPAL 3 4 RUTAS Y CONTROLADORES EN DRUPAL
PERMISOS Y MENÚS EN DRUPAL 5 6 FORMULARIOS EN DRUPAL
COMANDOS ÚTILES EN DRUPAL 7 8 INYECCIÓN DE DEPENDENCIAS EN DRUPAL
PREFILLING DE VALORES EN CAMPOS 9
BIENVENIDA 1 2 PRESENTACIÓN
LECTURAS RECOMENDADAS 11 12 DESPEDIDA Y CIERRE
PRESENTACIÓN
10 CONSULTAS DINÁMICAS A LA BASE DE DATOS
2, QUÉ VA A PASAR
5
MÓDULOS CUSTOM EN DRUPAL
3, QUÉ ES UN MÓDULO
6
1- Elegir un nombre.
2- Elegir un nombre corto,
“machine_name”.
3- Será usado en la creación de diversos
ficheros internos.
4- Servirá para identificar el módulo por
parte del sistema Drupal.
5- Debe empezar con una letra.
6- Debe contener solo letras en minúscula y guiones
bajos.
7- Debe ser único y no puede coincidir con otro módulo,
theme o profile.
8- No debe contener palabras reservadas: lib, js, src, css,
vendor, files, assets, images, templates, includes, Drupal.
MÓDULOS CUSTOM EN DRUPAL
3, CREAR UN MÓDULO
/MODULES/CUSTOM/WORKSHOP_FORMS/
WORKSHOP_FORMS.INFO.YML
name: 'Workshop Forms'
type: module
description: 'My Custom Module for Forms.'
core: 8.x
package: 'Workshop'
7
RUTAS Y CONTROLADORES EN DRUPAL
4, ESO DE ROUTING
RUTA CONTROLADOR
Esquema de definición de una ruta:
Nombre de sistema (machine_name)
Ruta física (path)
Controladores: clase y método responsables
Título
Especificación de permisos
Nos referimos en realidad a una clase que
se hace responsable de gestionar el
procesamiento de una ruta.
Forma Class::method
_controller:
Drupal[module_name]Controller[ClassName]::[method]
Forma Service:method
_controller: ‘[name_service].controller:[method]’
Forma ClassFormulario
_form: ‘Drupal[module_name]Form[FormClassName]’
Una ruta es (conceptualmente) el camino a
seguir para alcanzar un destino a partir de
un punto de partida.
En Drupal se sigue el modelo de Symfony
para gestionar rutas, basado en MVC, donde
se definen rutas en un fichero descriptivo y
se les asigna una clase responsable
(Controlador, Formulario, Servicio).
8
RUTAS Y CONTROLADORES EN DRUPAL
4, CREAR EL ROUTING
/MODULES/CUSTOM/WORKSHOP_FORMS/
WORKSHOP_FORMS.ROUTING.YML
workshop_forms.form:
path: '/workshop/forms/form'
defaults:
_form:
'Drupalworkshop_formsFormCustomForm’
_title: 'Workshop Forms Custom Form'
requirements:
_permission: 'workshop forms access'
9
workshop_forms.routing.yml
workshop_forms.page:
path: '/workshop/forms/page'
defaults:
_controller: 'Drupalworkshop_formsControllerWorkshopFormsPageController::hello'
_title: 'Workshop Forms Page'
requirements:
_permission: 'access content'
RUTAS Y CONTROLADORES EN DRUPAL
10
4, si qUIERES JUGAR
Puedes añadir más rutas al fichero
Pero recuerda construir un controlador y un método en /src/Controller/
PERMISOS Y MENÚS EN DRUPAL
5, DEFINIR PERMISOS
/MODULES/CUSTOM/WORKSHOP_FORMS/
WORKSHOP_FORMS.PERMISSIONS.YML
Workshop forms access:
title: 'Workshop forms access'
description: 'Access to Workshop form'
11
En Drupal el acceso se puede
gestionar a través de permisos,
establecidos en un fichero
declarativo y luego vinculados a
un rol o a un usuario específico.
PERMISOS Y MENÚS EN DRUPAL
12
5, CONSTRUIR MENÚ
/MODULES/CUSTOM/WORKSHOP_FORMS/
WORKSHOP_FORMS.LINKS.MENU.YML
workshop_forms.admin_workshop:
title: ‘Workshop’
parent: system.admin
route_name: workshop_forms.admin_workshop
description: ‘Links to resources from Workshop’
weight: -11
En Drupal 8 la especificación
de una ruta se mantiene
desacoplada de la definición
de un enlace de menú.
Los gestionamos como
configuración en un fichero
propio.
PERMISOS Y MENÚS EN DRUPAL
5, ELEMENTOS HIJOS
workshop_forms.forms_view:
title: 'Workshop Form'
parent: workshop_forms.admin_workshop
route_name: workshop_forms.form
description: 'Showing Workshop Form'
weight: 1
workshop_forms.forms_page:
title: 'Workshop Page'
parent: workshop_forms.admin_workshop
route_name: workshop_forms.page
description: 'Showing Workshop Page'
weight: 2
SI QUIERES AMPLIAR CON OTRO ENLACE HIJO
PERO RECUERDA DEFINIR RUTA Y CONTROLADOR
13
PERMISOS Y MENÚS EN DRUPAL
4, AMPLIAMOS ROUTING
DEFINIMOS UNA RUTA MADRE
WORKSHOP_FORMS.ROUTING.YML
workshop_forms.admin_workshop
path: '/admin/workshop'
defaults:
_controller:
'DrupalsystemControllerSystemController::systemAdminMenuBlockPage'
_title: 'Workshop First Link'
requirements:
_access: 'TRUE'
14
FORMULARIOS EN DRUPAL
6, FORM API DE DRUPAL
CONCEPTOS BÁSICOS DE FORMULARIOS
TIPOS DE FORMULARIOS EN DRUPAL
1- Basic Form: a normal form of general purpose, adaptable.
Created from the FormBase Class in Drupal API and maybe the
most basic kind of form. Class FormBase.php
2- Config Form: a form of specific use to establish an object
and configuration values. Created from the ConfigFormBase in
Drupal API. Class ConfigFormBase.php
3- Confirm Form: a form to request confirmation from the user
before executing an irreversible action. Created from the
ConfigFormBase in Drupal API. Class ConfirmFormBase.php 15
FORMULARIOS EN DRUPAL
16
6, OBJETIVO
FORMULARIOS EN DRUPAL
6, ELEMENTOS DE FORM
textarea, radiobuttons, date, range, number,
button, colorpicker, checkbox, range, select..
17
$form['name'] = [
'#type' => 'textfield',
'#title' => $this->t('Name'),
'#description' => $this->t('User Name'),
'#maxlength' => 64,
'#weight' => 0,
];
https://api.drupal.org/api/drupal/elements/8.8.x
https://www.drupal.org/docs/8/api/form-api/form-render-elements
https://www.drupal.org/docs/develop/user-interface-standards/form-elements
FORMULARIOS EN DRUPALFORMULARIOS EN DRUPAL
6, BASIC FORM DRUPAL
/src/Form/CustomForm.php
<?php
namespace Drupalworkshop_formsForm;
use DrupalCoreFormFormBase;
use DrupalCoreFormFormStateInterface;
class CustomForm extends FormBase {
}
picture from Unsplash, user Mitil - @gigantfotos
18
FORMULARIOS EN DRUPAL
6, MÉTODOS BÁSICOS
RESPONSABILIDADES CLAVE
public function getFormId() {
return 'workshop_form';
}
public function buildForm(array $form,
FormStateInterface $form_state) {
return $form;
}
public function validateForm(array &$form,
FormStateInterface $form_state) {
}
public function submitForm(array &$form,
FormStateInterface $form_state) {
}
Devolver el nombre del formulario ->
Construir el formulario y devolverlo ->
Validar los valores del formulario ->
Enviar y procesar valores del formulario ->
$form -> Formulario, $form_state -> Valores
19
FORMULARIOS EN DRUPAL
6, CONSTRUCCIÓN
20
$form['name'] = [
'#type' => 'textfield',
'#title' => $this->t('Name'),
'#description' => $this->t('User Name'),
'#maxlength' => 64,
'#weight' => 0,
];
$form['id_user'] = [
'#type' => 'number',
'#title' => $this->t('User ID'),
'#description' => $this->t('User ID'),
'#weight' => 1,
];
$form['email'] = [
'#type' => 'email',
'#title' => $this->t('Email'),
'#description' => $this->t('User email'),
'#weight' => 2,
];
$form['number_comments'] = [
'#type' => 'number',
'#title' => $this->t('Number of Comments'),
'#description' => $this->t('Number of Comments'),
'#weight' => 3,
];
$form['types'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Content Types'),
'#description' => $this->t('Select Content Types'),
'#options' => [1 => '1'],
'#default_value' => 1,
'#weight' => 4,
];
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
'#weight' => 5,
];
return $form;
public function buildForm(array $form, FormStateInterface $form_state) { }
COMANDOS ÚTILES EN DRUPAL
21
7, ENABLE / DISABLE
INSTALAR / DESINSTALAR / LIMPIAR CACHÉ
USANDO DRUSH O DRUPAL CONSOLE
drush en workshop_forms
drush cr
drush pmu workshop_forms
drupal moi workshop_forms
drupal mou workshop_forms
INYECCIÓN DE DEPENDENCIAS EN DRUPAL
8, QUÉ ES UN SERVICIO
Dependency Injection (DI) es un patrón de diseño orientado a objetos, en el que se suministran objetos a
una clase en lugar de ser la propia clase la que cree dichos objetos. Nuestras clases no crean los objetos, sino
que se los suministra otra clase ‘contenedora’ que inyectará la implementación deseada. (Wikipedia).
Un Service Container (o Dependency Injection container) es un objeto PHP que administra instancias de
servicios (otros objetos).
Un Servicio, es en sí mismo una clase que cumple una única responsabilidad, generada de manera única para
un contexto concreto (Singleton).
// Antes:
$servicio = new FooMehBah;
$servicio = FooMehBah::getInstance();
22
https://www.drupal.org/docs/8/api/services-and-dependency-injection
https://symfony.com/doc/current/components/dependency_injection.html
https://www.drupal.org/docs/8/api/services-and-dependency-injection/dependency-injection-for-a-form
// Ahora:
$container = $this->getContainer();
$servicio= $container->get('foo.meh.bah');
INYECCIÓN DE DEPENDENCIAS EN DRUPAL
8, USO DE SERVICIOS
DECLARANDO SERVICIOS
services:
ban.ip_manager:
class: DrupalbanBanIpManager
arguments: ['@database']
tags:
- { name: backend_overridable }
ban.middleware:
class: DrupalbanBanMiddleware
arguments: ['@ban.ip_manager']
tags:
- { name: http_middleware, priority: 250 }
USANDO SERVICIOS DINÁMICAMENTE
private $database;
private $current_user;
public function __construct( Connection $database,
AccountProxyInterface $current_user ) {
$this->database = $database;
$this->current_user = $current_user;
}
public static function create(ContainerInterface $container) {
return new static(
$container->get('database'),
$container->get('current_user'),
);
}
USANDO SERVICIOS ESTÁTICAMENTE
Drupal::service('module_installer')->uninstall(['action']);
Drupal::messenger()->addMessage(‘Message to print’);
$user = Drupal::currentUser(); 23
SERVICIOS DISPONIBLE EN CORE
CORE.SERVICES.YML
$form['name'] = [
'#type' => 'textfield',
'#value' => $this->current_user->getDisplayName(),
'#title' => $this->t('Name'),
'#description' => $this->t('User Name'),
'#maxlength' => 64,
'#weight' => 0,
];
$form['id_user'] = [
'#type' => 'number',
'#value' => $this->current_user->id(),
'#title' => $this->t('User ID'),
'#description' => $this->t('User ID'),
'#maxlength' => 64,
'#weight' => '1',
];
$form['email'] = [
'#type' => 'email',
'#value' => $this->current_user->getEmail(),
'#title' => $this->t('Email'),
'#description' => $this->t('User email'),
'#weight' => '2',
];
PREFILLING DE VALORES EN CAMPOS
24
9, PRECARGA EN CAMPO
USAMOS LOS SERVICIOS INYECTADOS
PARA COMPLETAR #VALUE
public function validateForm(array &$form, FormStateInterface $form_state) {
// Get the email value from the field.
$mail = $form_state->getValue('email');
// Test the format of the email.
if(!$this->email_validator->isValid($mail)) {
$form_state->setErrorByName('email', $this->t('The %email is not valid email.', ['%email' => $mail]));
}
}
PREFILLING DE VALORES EN CAMPOS
25
9, USOS DE SERVICIOS
ADEMÁS DE CAMPOS DE FORMULARIO
PODEMOS USARLOS EN TODA LA CLASE
composer require drupal/devel
exec drush en devel devel_generate
exec drush genc 10 5 --types=article
CONSULTAS DINÁMICAS A LA BASE DE DATOS
26
10, PREPARANDO NODOS
INSTALAMOS Y HABILITAMOS DEVEL
GENERAMOS CONTENIDO
// Build the base query.
$query = $this->database->select('comment_field_data', 'c')
->fields('c')
->condition('c.uid', $this->currentUser->id(), '=');
// Get the number of registers.
$query_counter = $query->countQuery();
$result = $query_counter->execute();
$count = $result->fetchField();
// Using the count value for prefilling the value.
$form['number_comments'] = [
'#type' => 'number',
'#value' => $count,
'#title' => $this->t('Number of Comments'),
'#description' => $this->t('Number of Coments'),
'#weight' => 3,
];
CONSULTAS DINÁMICAS A BASE DE DATOS
27
10, CONSULTA Y CARGA
EN DRUPAL PODEMOS USAR
CONSULTAS ESTÁTICAS O DINÁMICAS
// Consultas estáticas.
$database = Drupal::database();
$query = $database->query("SELECT id,
example FROM {mytable}");
$result = $query->fetchAll();
https://www.drupal.org/docs/8/api/datab
ase-api/static-queries
$options = node_type_get_names();
$defaults = array_keys($options);
$form['types'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Content Types'),
'#description' => $this->t('Select Content
Types'),
'#options' => $options,
'#default_value' => $defaults,
'#weight' => '4',
];
PREFILLING DE VALORES EN CAMPOS
28
9, OTROS ORÍGENES
Hemos visto cómo precargar valores en
campos a lo largo de diversos ejemplos
para nuestros campos de formulario
basado en la Form API de Drupal:
hemos usado servicios bajo el modelo de
Inyección de Dependencias (DI) de
Symfony y también hemos realizado
consultas directas a la base de datos
través de la Database API de Drupal.
Ahora veremos otro origen de datos más a
partir del que podemos extraer
información: simples funciones
pre-existentes.
FORMULARIOS EN DRUPAL
29
6, ALTERANDO EL FORM
if(!$this->current_user->isAuthenticated()) {
$form['help'] = [
'#type' => 'item',
'#title' => $this->t('Please, read the conditions.'),
'#markup' => $this->t('<strong>Only for registered users.</strong>'),
];
}else {
$form['email'] = [
'#type' => 'email',
'#value' =>
$this->current_user->getEmail(),
'#title' => $this->t('Email'),
'#description' => $this->t('User email'),
'#weight' => '2',
];
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
'#weight' => 5,
];
}
No debemos perder de vista que en realidad, nunca nos hemos movido del contexto propio de
una Clase PHP y un método buildForm(). Así que vamos a jugar con algunas cláusulas if - else.
FORMULARIOS EN DRUPAL
30
6, RESULTADOS
INYECCIÓN DE DEPENDENCIAS EN DRUPAL
31
public function validateForm(array &$form, FormStateInterface $form_state) {
// Get the email value from the field.
$mail = $form_state->getValue('email');
// Test the format of the email.
if(!$this->email_validator->isValid($mail)) {
$form_state->setErrorByName('email', $this->t('The %email is not a valid email.', ['%email' => $mail]));
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
// Display result in submit.
foreach ($form_state->getValues() as $key => $value) {
Drupal::messenger()->addMessage($key . ': ' . ($key === 'text_format'?$value['value']:$value));
}
}
INYECCIÓN DE DEPENDENCIAS EN DRUPAL
8, VALIDACIÓN GLOBAL
USAR SERVICIOS PARA VALIDACIONES
EN MÉTODOS VALIDATEFORM O SUBMIT
$form['titulo'] = [
'#type' => 'textfield',
'#title' => $this->t('Título'),
'#description' => $this->t('Titulo en el formulario.'),
'#required' => TRUE,
'#weight' => '0',
'#element_validate' => ['::titleCustomValidation'],
];
public function titleCustomValidation($element, FormStateInterface $form_state) {
// Insert new custom conditions for valitions in the ‘titulo’ field.
$form_state->setErrorByName('titulo', $this->t($error_message));
}
PREFILLING DE VALORES EN CAMPOS
32
INYECCIÓN DE DEPENDENCIAS EN DRUPALINYECCIÓN DE DEPENDENCIAS EN DRUPAL
8, VALIDACIÓN CUSTOM
ES POSIBLE USAR VALIDACIONES CUSTOM
ESPECÍFICAS PARA CADA CAMPO DE FORM
Modo interactivo
drupal generate:module
drupal gm
COMANDOS ÚTILES EN DRUPAL
33
7, CREAR MÓDULOS
CREACIÓN AUTOMÁTICA
USANDO DRUPAL CONSOLE
Modo no interactivo
drupal generate:module 
--module="My Random module" 
--machine-name="my_random_module" 
--module-path="modules/custom" 
--description="Random generated custom module" 
--core="8.x" 
--package="Custom" 
--module-file 
--no-interaction
Modo interactivo
drupal generate:form
drupal gf
Modo no interactivo
drupal generate:form 
--module="my_random_module" 
--class="RandomClassForm" 
--form-id="default_random_form" 
--config-file 
--inputs='"name":"name", "type":"textfield", "label":"Name", "options":"", "description":"User Name", "maxlength":"64", "size":"",
"default_value":"", "weight":"0", "fieldset":""' 
--inputs='"name":"id_user", "type":"number", "label":"User ID", "options":"", "description":"User ID", "maxlength":"64", "size":"",
"default_value":"", "weight":"1", "fieldset":""' 
--inputs='"name":"email", "type":"email", "label":"Email", "options":"", "description":"User email", "maxlength":"", "size":"", "default_value":"",
"weight":"2", "fieldset":""' 
--inputs='"name":"number_comments", "type":"number", "label":"Number of Comments", "options":"", "description":"Number of Coments",
"maxlength":"", "size":"", "default_value":"", "weight":"3", "fieldset":""' 
--inputs='"name":"types", "type":"checkboxes", "label":"Content Types", "options":"['1' => '1']", "description":"Select Content Types",
"maxlength":"", "size":"", "default_value":"1", "weight":"4", "fieldset":""' 
--path="/my_random_module/forms/random_form" 
--no-interaction
COMANDOS ÚTILES EN DRUPAL
34
7, CREAR FORMULARIOS
drupal generate:form 
--module="my_random_module" 
--class="RandomClassForm" 
--form-id="default_random_form" 
--config-file 
--inputs='"name":"name", "type":"textfield", "label":"Name", "options":"", "description":"User Name", "maxlength":"64", "size":"",
"default_value":"", "weight":"0", "fieldset":""' 
--inputs='"name":"id_user", "type":"number", "label":"User ID", "options":"", "description":"User ID", "maxlength":"64", "size":"",
"default_value":"", "weight":"1", "fieldset":""' 
--inputs='"name":"email", "type":"email", "label":"Email", "options":"", "description":"User email", "maxlength":"", "size":"",
"default_value":"", "weight":"2", "fieldset":""' 
--inputs='"name":"number_comments", "type":"number", "label":"Number of Comments", "options":"", "description":"Number
of Coments", "maxlength":"", "size":"", "default_value":"", "weight":"3", "fieldset":""' 
--inputs='"name":"types", "type":"checkboxes", "label":"Content Types", "options":"['1' => '1']", "description":"Select Content
Types", "maxlength":"", "size":"", "default_value":"1", "weight":"4", "fieldset":""' 
--path="/my_random_module/forms/random_form" 
--services="database" 
--services="current_user" 
--services="email.validator" 
--no-interaction
COMANDOS ÚTILES EN DRUPAL
35
7, FORMS + SERVICIOS
“Hacia rutas salvajes” (Routing en Drupal 8) by @jansete
https://docs.google.com/presentation/d/17KVjfmgMtIIIDl0N40Vm1iyaUBg27mGE1hV2byIR4OM/edit
“Structure of routes” (Drupal 8 documentation)
https://www.drupal.org/docs/8/api/routing-system/structure-of-routes
Let’s take the best route - Exploring Drupal 8 routing system
https://www.srijan.net/blog/exploring-drupal-8-routing-system
Using Links in Drupal 8
https://davidjguru.github.io/blog/drupal-fast-tips-using-links-in-drupal-8
Formularios en Drupal 8 (Crear formularios, modificar formularios, ejemplos con Hooks)
https://medium.com/drupal-y-yo/form-api-i-comprender-crear-y-modificar-formularios-en-drupal-8-22c0cf4d72d3
https://medium.com/drupal-y-yo/form-api-ii-modificando-formularios-en-drupal-8-mediante-form-alter-78fa949b43d0
https://medium.com/drupal-y-yo/form-api-iii-caso-pr%C3%A1ctico-de-modificaci%C3%B3n-de-formulario-en-drupal-8-f8ab4dd40a5c
Prefilling fields in forms (Precargando campos en formularios)
https://davidjguru.github.io/blog/drupal-fast-tips-prefilling-fields-in-forms
LECTURAS RECOMENDADAS
36
11, AMPLIA INFORMACIÓN
https://gitlab.com/davidjguru/drupal-custom-modules-examples/tree/master/my_random_module
DESPEDIDA Y CIERRE
37
12, EVERY TIME WE SAY GOODBYE
Recuerda que puedes escribirme a davidjguru@gmail.com y aquí tienes el código disponible:
In memory of
En recuerdo de

More Related Content

What's hot

What is the difference between struts 1 vs struts 2
What is the difference between struts 1 vs struts 2What is the difference between struts 1 vs struts 2
What is the difference between struts 1 vs struts 2
Santosh Singh Paliwal
 
Unmanned air vehicle(quadrotor)
Unmanned air vehicle(quadrotor)Unmanned air vehicle(quadrotor)
Unmanned air vehicle(quadrotor)
PRADEEP Cheekatla
 
Uav presentation
Uav presentationUav presentation
Uav presentation
Meshut
 

What's hot (20)

Introduction to Django Rest Framework
Introduction to Django Rest FrameworkIntroduction to Django Rest Framework
Introduction to Django Rest Framework
 
Mission planning and control for UAV's
Mission planning and control for UAV'sMission planning and control for UAV's
Mission planning and control for UAV's
 
Introduction To Dotnet
Introduction To DotnetIntroduction To Dotnet
Introduction To Dotnet
 
Ornithopter project
Ornithopter projectOrnithopter project
Ornithopter project
 
Permission in Android Security: Threats and solution
Permission in Android Security: Threats and solutionPermission in Android Security: Threats and solution
Permission in Android Security: Threats and solution
 
4+1 View Model of Software Architecture
4+1 View Model of Software Architecture4+1 View Model of Software Architecture
4+1 View Model of Software Architecture
 
Introduction to Android development - Presentation
Introduction to Android development - PresentationIntroduction to Android development - Presentation
Introduction to Android development - Presentation
 
Introduction to Django REST Framework, an easy way to build REST framework in...
Introduction to Django REST Framework, an easy way to build REST framework in...Introduction to Django REST Framework, an easy way to build REST framework in...
Introduction to Django REST Framework, an easy way to build REST framework in...
 
Advanced Structural Modeling
Advanced Structural ModelingAdvanced Structural Modeling
Advanced Structural Modeling
 
Tejas the light combat aircraft of india
Tejas the light combat aircraft of indiaTejas the light combat aircraft of india
Tejas the light combat aircraft of india
 
Airline reservation project using JAVA in NetBeans IDE
Airline reservation project using JAVA in NetBeans IDEAirline reservation project using JAVA in NetBeans IDE
Airline reservation project using JAVA in NetBeans IDE
 
What is the difference between struts 1 vs struts 2
What is the difference between struts 1 vs struts 2What is the difference between struts 1 vs struts 2
What is the difference between struts 1 vs struts 2
 
Подозрение ГПУ Борису Ложкину
Подозрение ГПУ Борису ЛожкинуПодозрение ГПУ Борису Ложкину
Подозрение ГПУ Борису Ложкину
 
Unmanned air vehicle(quadrotor)
Unmanned air vehicle(quadrotor)Unmanned air vehicle(quadrotor)
Unmanned air vehicle(quadrotor)
 
Android Jetpack
Android Jetpack Android Jetpack
Android Jetpack
 
PX4 Setup Workshop
PX4 Setup WorkshopPX4 Setup Workshop
PX4 Setup Workshop
 
Mobile application development
Mobile application developmentMobile application development
Mobile application development
 
Uav presentation
Uav presentationUav presentation
Uav presentation
 
Android framework design and development
Android framework design and developmentAndroid framework design and development
Android framework design and development
 
Android seminar-report-body.doc
Android seminar-report-body.docAndroid seminar-report-body.doc
Android seminar-report-body.doc
 

Similar to Drupal Workshop: Introducción al Backend de Drupal

Drupal 8: Theming
Drupal 8: ThemingDrupal 8: Theming
Drupal 8: Theming
drubb
 
Drupal module development training delhi
Drupal module development training delhiDrupal module development training delhi
Drupal module development training delhi
unitedwebsoft
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHP
Dan Jesus
 

Similar to Drupal Workshop: Introducción al Backend de Drupal (20)

Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010
 
Drupal Module Development
Drupal Module DevelopmentDrupal Module Development
Drupal Module Development
 
Learning the basics of the Drupal API
Learning the basics of the Drupal APILearning the basics of the Drupal API
Learning the basics of the Drupal API
 
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
 
Routing in Drupal 8
Routing in Drupal 8Routing in Drupal 8
Routing in Drupal 8
 
Drupal 8 simple page: Mi primer proyecto en Drupal 8.
Drupal 8 simple page: Mi primer proyecto en Drupal 8.Drupal 8 simple page: Mi primer proyecto en Drupal 8.
Drupal 8 simple page: Mi primer proyecto en Drupal 8.
 
Drupal as a framework
Drupal as a frameworkDrupal as a framework
Drupal as a framework
 
Drupal 8: Theming
Drupal 8: ThemingDrupal 8: Theming
Drupal 8: Theming
 
Vancouver League of Drupallers - Remembering the User (August 2008)
Vancouver League of Drupallers - Remembering the User (August 2008)Vancouver League of Drupallers - Remembering the User (August 2008)
Vancouver League of Drupallers - Remembering the User (August 2008)
 
Fapi
FapiFapi
Fapi
 
Drupal vs WordPress
Drupal vs WordPressDrupal vs WordPress
Drupal vs WordPress
 
Migrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindMigrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mind
 
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
 
Routing in Drupal 8
Routing in Drupal 8Routing in Drupal 8
Routing in Drupal 8
 
Convert modules from 6.x to 7.x
Convert modules from 6.x to 7.xConvert modules from 6.x to 7.x
Convert modules from 6.x to 7.x
 
Drupal module development training delhi
Drupal module development training delhiDrupal module development training delhi
Drupal module development training delhi
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHP
 
Layout discovery. Drupal Summer Barcelona 2017
Layout discovery. Drupal Summer Barcelona 2017Layout discovery. Drupal Summer Barcelona 2017
Layout discovery. Drupal Summer Barcelona 2017
 
Puppet Design Patterns - PuppetConf
Puppet Design Patterns - PuppetConfPuppet Design Patterns - PuppetConf
Puppet Design Patterns - PuppetConf
 
8. vederea inregistrarilor
8. vederea inregistrarilor8. vederea inregistrarilor
8. vederea inregistrarilor
 

More from David (davidjguru) Rodríguez

More from David (davidjguru) Rodríguez (20)

David Rodriguez - davidjguru CV 2024 updated
David Rodriguez - davidjguru CV 2024 updatedDavid Rodriguez - davidjguru CV 2024 updated
David Rodriguez - davidjguru CV 2024 updated
 
Drupal Developer Days Seville 2017: Network report (post-mortem)
Drupal Developer Days Seville 2017: Network report (post-mortem)Drupal Developer Days Seville 2017: Network report (post-mortem)
Drupal Developer Days Seville 2017: Network report (post-mortem)
 
Less NIH, More PFE: Demolishing myths about Drupal
Less NIH, More PFE: Demolishing myths about DrupalLess NIH, More PFE: Demolishing myths about Drupal
Less NIH, More PFE: Demolishing myths about Drupal
 
Drupal summer Barcelona 2016: How to be a Drupal dealer aka sin hype estamos...
Drupal summer Barcelona 2016:  How to be a Drupal dealer aka sin hype estamos...Drupal summer Barcelona 2016:  How to be a Drupal dealer aka sin hype estamos...
Drupal summer Barcelona 2016: How to be a Drupal dealer aka sin hype estamos...
 
Sesion sunrise blog club: como hacerse multimillonario con un blog. El caso C...
Sesion sunrise blog club: como hacerse multimillonario con un blog. El caso C...Sesion sunrise blog club: como hacerse multimillonario con un blog. El caso C...
Sesion sunrise blog club: como hacerse multimillonario con un blog. El caso C...
 
Guía de estilo #CIBASS
Guía de estilo #CIBASSGuía de estilo #CIBASS
Guía de estilo #CIBASS
 
¿Crees que mi idea será viable?
¿Crees que mi idea será viable?¿Crees que mi idea será viable?
¿Crees que mi idea será viable?
 
Programación Campabase 2014 versión 02
Programación Campabase 2014 versión 02Programación Campabase 2014 versión 02
Programación Campabase 2014 versión 02
 
Ecosistemas de marketing online
Ecosistemas de marketing onlineEcosistemas de marketing online
Ecosistemas de marketing online
 
Dossier de patrocinios de Campabase 2014
Dossier de patrocinios de Campabase 2014Dossier de patrocinios de Campabase 2014
Dossier de patrocinios de Campabase 2014
 
Gestión de proyectos bajo paradigmas ágiles
Gestión de proyectos bajo paradigmas ágilesGestión de proyectos bajo paradigmas ágiles
Gestión de proyectos bajo paradigmas ágiles
 
Informe de impacto Campabase 2013 #campabase013
Informe de impacto Campabase 2013 #campabase013Informe de impacto Campabase 2013 #campabase013
Informe de impacto Campabase 2013 #campabase013
 
Presentación de campabase en ebe 2013
Presentación de campabase en ebe 2013Presentación de campabase en ebe 2013
Presentación de campabase en ebe 2013
 
Gestión de la fase de feedback en el final de ciclo de Campabase 2013
Gestión de la fase de feedback en el final de ciclo de Campabase 2013Gestión de la fase de feedback en el final de ciclo de Campabase 2013
Gestión de la fase de feedback en el final de ciclo de Campabase 2013
 
Informe Campabase 2013
Informe Campabase 2013Informe Campabase 2013
Informe Campabase 2013
 
Ciclo los lunes ágiles
Ciclo los lunes ágilesCiclo los lunes ágiles
Ciclo los lunes ágiles
 
Agilidad desde las profundidades del averno
Agilidad desde las profundidades del avernoAgilidad desde las profundidades del averno
Agilidad desde las profundidades del averno
 
El cliente, el valor y otras cosas del montón
El cliente, el valor y otras cosas del montónEl cliente, el valor y otras cosas del montón
El cliente, el valor y otras cosas del montón
 
Si solo tienes ideas, estás perdido
Si solo tienes ideas, estás perdidoSi solo tienes ideas, estás perdido
Si solo tienes ideas, estás perdido
 
Campabase en Reiniciando Sevilla.
Campabase en Reiniciando Sevilla.Campabase en Reiniciando Sevilla.
Campabase en Reiniciando Sevilla.
 

Recently uploaded

AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
VictorSzoltysek
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Recently uploaded (20)

Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 

Drupal Workshop: Introducción al Backend de Drupal

  • 1. INTRODUCCIÓN AL BACKEND DE DRUPAL (WORKSHOP) Zaragoza Drupal Day Spain 2019 David Rodríguez @davidjguru 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
  • 2. BIENVENIDA David Rodríguez Vicente (Drupal) Center Leader Specialist en Everis Sevilla Responsable técnico de Proyectos basados en Drupal Director técnico del equipo Drupal de Everis Center Sevilla Profile https://www.linkedin.com/in/davidjguru https://www.drupal.org/u/davidjguru Blogs https://medium.com/@davidjguru (esp) https://davidjguru.github.io (en) Repos https://gitlab.com/davidjguru https://github.com/davidjguru Contacto https://twitter.com/davidjguru davidjguru@gmail.com https://twitter.com/DrupalSevilla HELLO MY NAME IS. 1, HOLA QUE TAL 2
  • 3. Ver Drupal por dentro Introducción a tu nuevo backend favorito Progresivo, iterativo e incremental Asentemos conceptos básicos Observa las posibilidades Experiencia Inicial Motivadora Cogiendo cariño a Drupal PRESENTACIÓN 2, dE QUÉ VA ESTO picture from Unsplash, user Konstantin Aal - @kostic86
  • 4. Practicaremos creando nuevos módulos Custom de Drupal. Expondremos los fundamentos del sistema de rutas y controladores de Drupal con la idea de construir accesos a nuestros formularios. Conoceremos los fundamentos de la creación de formularios con Drupal, crearemos varios tanto a mano como con su versión rápida usando Drupal Console. Dotaremos a los campos de formulario con valores ya cargados previamente, y para ese pre-filling de campo usaremos algunos servicios proporcionados por Drupal. Usaremos servicios web para realizar peticiones externas vía REST y cargar información en nuestros formularios. Realizaremos consultas a la base de datos y cargaremos valores dinámicamente en nuestro formulario. PRESENTACIÓN 2, qUÉ VAMOS A HACER
  • 5. MÓDULOS CUSTOM EN DRUPAL 3 4 RUTAS Y CONTROLADORES EN DRUPAL PERMISOS Y MENÚS EN DRUPAL 5 6 FORMULARIOS EN DRUPAL COMANDOS ÚTILES EN DRUPAL 7 8 INYECCIÓN DE DEPENDENCIAS EN DRUPAL PREFILLING DE VALORES EN CAMPOS 9 BIENVENIDA 1 2 PRESENTACIÓN LECTURAS RECOMENDADAS 11 12 DESPEDIDA Y CIERRE PRESENTACIÓN 10 CONSULTAS DINÁMICAS A LA BASE DE DATOS 2, QUÉ VA A PASAR 5
  • 6. MÓDULOS CUSTOM EN DRUPAL 3, QUÉ ES UN MÓDULO 6 1- Elegir un nombre. 2- Elegir un nombre corto, “machine_name”. 3- Será usado en la creación de diversos ficheros internos. 4- Servirá para identificar el módulo por parte del sistema Drupal. 5- Debe empezar con una letra. 6- Debe contener solo letras en minúscula y guiones bajos. 7- Debe ser único y no puede coincidir con otro módulo, theme o profile. 8- No debe contener palabras reservadas: lib, js, src, css, vendor, files, assets, images, templates, includes, Drupal.
  • 7. MÓDULOS CUSTOM EN DRUPAL 3, CREAR UN MÓDULO /MODULES/CUSTOM/WORKSHOP_FORMS/ WORKSHOP_FORMS.INFO.YML name: 'Workshop Forms' type: module description: 'My Custom Module for Forms.' core: 8.x package: 'Workshop' 7
  • 8. RUTAS Y CONTROLADORES EN DRUPAL 4, ESO DE ROUTING RUTA CONTROLADOR Esquema de definición de una ruta: Nombre de sistema (machine_name) Ruta física (path) Controladores: clase y método responsables Título Especificación de permisos Nos referimos en realidad a una clase que se hace responsable de gestionar el procesamiento de una ruta. Forma Class::method _controller: Drupal[module_name]Controller[ClassName]::[method] Forma Service:method _controller: ‘[name_service].controller:[method]’ Forma ClassFormulario _form: ‘Drupal[module_name]Form[FormClassName]’ Una ruta es (conceptualmente) el camino a seguir para alcanzar un destino a partir de un punto de partida. En Drupal se sigue el modelo de Symfony para gestionar rutas, basado en MVC, donde se definen rutas en un fichero descriptivo y se les asigna una clase responsable (Controlador, Formulario, Servicio). 8
  • 9. RUTAS Y CONTROLADORES EN DRUPAL 4, CREAR EL ROUTING /MODULES/CUSTOM/WORKSHOP_FORMS/ WORKSHOP_FORMS.ROUTING.YML workshop_forms.form: path: '/workshop/forms/form' defaults: _form: 'Drupalworkshop_formsFormCustomForm’ _title: 'Workshop Forms Custom Form' requirements: _permission: 'workshop forms access' 9
  • 10. workshop_forms.routing.yml workshop_forms.page: path: '/workshop/forms/page' defaults: _controller: 'Drupalworkshop_formsControllerWorkshopFormsPageController::hello' _title: 'Workshop Forms Page' requirements: _permission: 'access content' RUTAS Y CONTROLADORES EN DRUPAL 10 4, si qUIERES JUGAR Puedes añadir más rutas al fichero Pero recuerda construir un controlador y un método en /src/Controller/
  • 11. PERMISOS Y MENÚS EN DRUPAL 5, DEFINIR PERMISOS /MODULES/CUSTOM/WORKSHOP_FORMS/ WORKSHOP_FORMS.PERMISSIONS.YML Workshop forms access: title: 'Workshop forms access' description: 'Access to Workshop form' 11 En Drupal el acceso se puede gestionar a través de permisos, establecidos en un fichero declarativo y luego vinculados a un rol o a un usuario específico.
  • 12. PERMISOS Y MENÚS EN DRUPAL 12 5, CONSTRUIR MENÚ /MODULES/CUSTOM/WORKSHOP_FORMS/ WORKSHOP_FORMS.LINKS.MENU.YML workshop_forms.admin_workshop: title: ‘Workshop’ parent: system.admin route_name: workshop_forms.admin_workshop description: ‘Links to resources from Workshop’ weight: -11 En Drupal 8 la especificación de una ruta se mantiene desacoplada de la definición de un enlace de menú. Los gestionamos como configuración en un fichero propio.
  • 13. PERMISOS Y MENÚS EN DRUPAL 5, ELEMENTOS HIJOS workshop_forms.forms_view: title: 'Workshop Form' parent: workshop_forms.admin_workshop route_name: workshop_forms.form description: 'Showing Workshop Form' weight: 1 workshop_forms.forms_page: title: 'Workshop Page' parent: workshop_forms.admin_workshop route_name: workshop_forms.page description: 'Showing Workshop Page' weight: 2 SI QUIERES AMPLIAR CON OTRO ENLACE HIJO PERO RECUERDA DEFINIR RUTA Y CONTROLADOR 13
  • 14. PERMISOS Y MENÚS EN DRUPAL 4, AMPLIAMOS ROUTING DEFINIMOS UNA RUTA MADRE WORKSHOP_FORMS.ROUTING.YML workshop_forms.admin_workshop path: '/admin/workshop' defaults: _controller: 'DrupalsystemControllerSystemController::systemAdminMenuBlockPage' _title: 'Workshop First Link' requirements: _access: 'TRUE' 14
  • 15. FORMULARIOS EN DRUPAL 6, FORM API DE DRUPAL CONCEPTOS BÁSICOS DE FORMULARIOS TIPOS DE FORMULARIOS EN DRUPAL 1- Basic Form: a normal form of general purpose, adaptable. Created from the FormBase Class in Drupal API and maybe the most basic kind of form. Class FormBase.php 2- Config Form: a form of specific use to establish an object and configuration values. Created from the ConfigFormBase in Drupal API. Class ConfigFormBase.php 3- Confirm Form: a form to request confirmation from the user before executing an irreversible action. Created from the ConfigFormBase in Drupal API. Class ConfirmFormBase.php 15
  • 17. FORMULARIOS EN DRUPAL 6, ELEMENTOS DE FORM textarea, radiobuttons, date, range, number, button, colorpicker, checkbox, range, select.. 17 $form['name'] = [ '#type' => 'textfield', '#title' => $this->t('Name'), '#description' => $this->t('User Name'), '#maxlength' => 64, '#weight' => 0, ]; https://api.drupal.org/api/drupal/elements/8.8.x https://www.drupal.org/docs/8/api/form-api/form-render-elements https://www.drupal.org/docs/develop/user-interface-standards/form-elements
  • 18. FORMULARIOS EN DRUPALFORMULARIOS EN DRUPAL 6, BASIC FORM DRUPAL /src/Form/CustomForm.php <?php namespace Drupalworkshop_formsForm; use DrupalCoreFormFormBase; use DrupalCoreFormFormStateInterface; class CustomForm extends FormBase { } picture from Unsplash, user Mitil - @gigantfotos 18
  • 19. FORMULARIOS EN DRUPAL 6, MÉTODOS BÁSICOS RESPONSABILIDADES CLAVE public function getFormId() { return 'workshop_form'; } public function buildForm(array $form, FormStateInterface $form_state) { return $form; } public function validateForm(array &$form, FormStateInterface $form_state) { } public function submitForm(array &$form, FormStateInterface $form_state) { } Devolver el nombre del formulario -> Construir el formulario y devolverlo -> Validar los valores del formulario -> Enviar y procesar valores del formulario -> $form -> Formulario, $form_state -> Valores 19
  • 20. FORMULARIOS EN DRUPAL 6, CONSTRUCCIÓN 20 $form['name'] = [ '#type' => 'textfield', '#title' => $this->t('Name'), '#description' => $this->t('User Name'), '#maxlength' => 64, '#weight' => 0, ]; $form['id_user'] = [ '#type' => 'number', '#title' => $this->t('User ID'), '#description' => $this->t('User ID'), '#weight' => 1, ]; $form['email'] = [ '#type' => 'email', '#title' => $this->t('Email'), '#description' => $this->t('User email'), '#weight' => 2, ]; $form['number_comments'] = [ '#type' => 'number', '#title' => $this->t('Number of Comments'), '#description' => $this->t('Number of Comments'), '#weight' => 3, ]; $form['types'] = [ '#type' => 'checkboxes', '#title' => $this->t('Content Types'), '#description' => $this->t('Select Content Types'), '#options' => [1 => '1'], '#default_value' => 1, '#weight' => 4, ]; $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Submit'), '#weight' => 5, ]; return $form; public function buildForm(array $form, FormStateInterface $form_state) { }
  • 21. COMANDOS ÚTILES EN DRUPAL 21 7, ENABLE / DISABLE INSTALAR / DESINSTALAR / LIMPIAR CACHÉ USANDO DRUSH O DRUPAL CONSOLE drush en workshop_forms drush cr drush pmu workshop_forms drupal moi workshop_forms drupal mou workshop_forms
  • 22. INYECCIÓN DE DEPENDENCIAS EN DRUPAL 8, QUÉ ES UN SERVICIO Dependency Injection (DI) es un patrón de diseño orientado a objetos, en el que se suministran objetos a una clase en lugar de ser la propia clase la que cree dichos objetos. Nuestras clases no crean los objetos, sino que se los suministra otra clase ‘contenedora’ que inyectará la implementación deseada. (Wikipedia). Un Service Container (o Dependency Injection container) es un objeto PHP que administra instancias de servicios (otros objetos). Un Servicio, es en sí mismo una clase que cumple una única responsabilidad, generada de manera única para un contexto concreto (Singleton). // Antes: $servicio = new FooMehBah; $servicio = FooMehBah::getInstance(); 22 https://www.drupal.org/docs/8/api/services-and-dependency-injection https://symfony.com/doc/current/components/dependency_injection.html https://www.drupal.org/docs/8/api/services-and-dependency-injection/dependency-injection-for-a-form // Ahora: $container = $this->getContainer(); $servicio= $container->get('foo.meh.bah');
  • 23. INYECCIÓN DE DEPENDENCIAS EN DRUPAL 8, USO DE SERVICIOS DECLARANDO SERVICIOS services: ban.ip_manager: class: DrupalbanBanIpManager arguments: ['@database'] tags: - { name: backend_overridable } ban.middleware: class: DrupalbanBanMiddleware arguments: ['@ban.ip_manager'] tags: - { name: http_middleware, priority: 250 } USANDO SERVICIOS DINÁMICAMENTE private $database; private $current_user; public function __construct( Connection $database, AccountProxyInterface $current_user ) { $this->database = $database; $this->current_user = $current_user; } public static function create(ContainerInterface $container) { return new static( $container->get('database'), $container->get('current_user'), ); } USANDO SERVICIOS ESTÁTICAMENTE Drupal::service('module_installer')->uninstall(['action']); Drupal::messenger()->addMessage(‘Message to print’); $user = Drupal::currentUser(); 23 SERVICIOS DISPONIBLE EN CORE CORE.SERVICES.YML
  • 24. $form['name'] = [ '#type' => 'textfield', '#value' => $this->current_user->getDisplayName(), '#title' => $this->t('Name'), '#description' => $this->t('User Name'), '#maxlength' => 64, '#weight' => 0, ]; $form['id_user'] = [ '#type' => 'number', '#value' => $this->current_user->id(), '#title' => $this->t('User ID'), '#description' => $this->t('User ID'), '#maxlength' => 64, '#weight' => '1', ]; $form['email'] = [ '#type' => 'email', '#value' => $this->current_user->getEmail(), '#title' => $this->t('Email'), '#description' => $this->t('User email'), '#weight' => '2', ]; PREFILLING DE VALORES EN CAMPOS 24 9, PRECARGA EN CAMPO USAMOS LOS SERVICIOS INYECTADOS PARA COMPLETAR #VALUE
  • 25. public function validateForm(array &$form, FormStateInterface $form_state) { // Get the email value from the field. $mail = $form_state->getValue('email'); // Test the format of the email. if(!$this->email_validator->isValid($mail)) { $form_state->setErrorByName('email', $this->t('The %email is not valid email.', ['%email' => $mail])); } } PREFILLING DE VALORES EN CAMPOS 25 9, USOS DE SERVICIOS ADEMÁS DE CAMPOS DE FORMULARIO PODEMOS USARLOS EN TODA LA CLASE
  • 26. composer require drupal/devel exec drush en devel devel_generate exec drush genc 10 5 --types=article CONSULTAS DINÁMICAS A LA BASE DE DATOS 26 10, PREPARANDO NODOS INSTALAMOS Y HABILITAMOS DEVEL GENERAMOS CONTENIDO
  • 27. // Build the base query. $query = $this->database->select('comment_field_data', 'c') ->fields('c') ->condition('c.uid', $this->currentUser->id(), '='); // Get the number of registers. $query_counter = $query->countQuery(); $result = $query_counter->execute(); $count = $result->fetchField(); // Using the count value for prefilling the value. $form['number_comments'] = [ '#type' => 'number', '#value' => $count, '#title' => $this->t('Number of Comments'), '#description' => $this->t('Number of Coments'), '#weight' => 3, ]; CONSULTAS DINÁMICAS A BASE DE DATOS 27 10, CONSULTA Y CARGA EN DRUPAL PODEMOS USAR CONSULTAS ESTÁTICAS O DINÁMICAS // Consultas estáticas. $database = Drupal::database(); $query = $database->query("SELECT id, example FROM {mytable}"); $result = $query->fetchAll(); https://www.drupal.org/docs/8/api/datab ase-api/static-queries
  • 28. $options = node_type_get_names(); $defaults = array_keys($options); $form['types'] = [ '#type' => 'checkboxes', '#title' => $this->t('Content Types'), '#description' => $this->t('Select Content Types'), '#options' => $options, '#default_value' => $defaults, '#weight' => '4', ]; PREFILLING DE VALORES EN CAMPOS 28 9, OTROS ORÍGENES Hemos visto cómo precargar valores en campos a lo largo de diversos ejemplos para nuestros campos de formulario basado en la Form API de Drupal: hemos usado servicios bajo el modelo de Inyección de Dependencias (DI) de Symfony y también hemos realizado consultas directas a la base de datos través de la Database API de Drupal. Ahora veremos otro origen de datos más a partir del que podemos extraer información: simples funciones pre-existentes.
  • 29. FORMULARIOS EN DRUPAL 29 6, ALTERANDO EL FORM if(!$this->current_user->isAuthenticated()) { $form['help'] = [ '#type' => 'item', '#title' => $this->t('Please, read the conditions.'), '#markup' => $this->t('<strong>Only for registered users.</strong>'), ]; }else { $form['email'] = [ '#type' => 'email', '#value' => $this->current_user->getEmail(), '#title' => $this->t('Email'), '#description' => $this->t('User email'), '#weight' => '2', ]; $form['submit'] = [ '#type' => 'submit', '#value' => $this->t('Submit'), '#weight' => 5, ]; } No debemos perder de vista que en realidad, nunca nos hemos movido del contexto propio de una Clase PHP y un método buildForm(). Así que vamos a jugar con algunas cláusulas if - else.
  • 31. INYECCIÓN DE DEPENDENCIAS EN DRUPAL 31 public function validateForm(array &$form, FormStateInterface $form_state) { // Get the email value from the field. $mail = $form_state->getValue('email'); // Test the format of the email. if(!$this->email_validator->isValid($mail)) { $form_state->setErrorByName('email', $this->t('The %email is not a valid email.', ['%email' => $mail])); } } public function submitForm(array &$form, FormStateInterface $form_state) { // Display result in submit. foreach ($form_state->getValues() as $key => $value) { Drupal::messenger()->addMessage($key . ': ' . ($key === 'text_format'?$value['value']:$value)); } } INYECCIÓN DE DEPENDENCIAS EN DRUPAL 8, VALIDACIÓN GLOBAL USAR SERVICIOS PARA VALIDACIONES EN MÉTODOS VALIDATEFORM O SUBMIT
  • 32. $form['titulo'] = [ '#type' => 'textfield', '#title' => $this->t('Título'), '#description' => $this->t('Titulo en el formulario.'), '#required' => TRUE, '#weight' => '0', '#element_validate' => ['::titleCustomValidation'], ]; public function titleCustomValidation($element, FormStateInterface $form_state) { // Insert new custom conditions for valitions in the ‘titulo’ field. $form_state->setErrorByName('titulo', $this->t($error_message)); } PREFILLING DE VALORES EN CAMPOS 32 INYECCIÓN DE DEPENDENCIAS EN DRUPALINYECCIÓN DE DEPENDENCIAS EN DRUPAL 8, VALIDACIÓN CUSTOM ES POSIBLE USAR VALIDACIONES CUSTOM ESPECÍFICAS PARA CADA CAMPO DE FORM
  • 33. Modo interactivo drupal generate:module drupal gm COMANDOS ÚTILES EN DRUPAL 33 7, CREAR MÓDULOS CREACIÓN AUTOMÁTICA USANDO DRUPAL CONSOLE Modo no interactivo drupal generate:module --module="My Random module" --machine-name="my_random_module" --module-path="modules/custom" --description="Random generated custom module" --core="8.x" --package="Custom" --module-file --no-interaction
  • 34. Modo interactivo drupal generate:form drupal gf Modo no interactivo drupal generate:form --module="my_random_module" --class="RandomClassForm" --form-id="default_random_form" --config-file --inputs='"name":"name", "type":"textfield", "label":"Name", "options":"", "description":"User Name", "maxlength":"64", "size":"", "default_value":"", "weight":"0", "fieldset":""' --inputs='"name":"id_user", "type":"number", "label":"User ID", "options":"", "description":"User ID", "maxlength":"64", "size":"", "default_value":"", "weight":"1", "fieldset":""' --inputs='"name":"email", "type":"email", "label":"Email", "options":"", "description":"User email", "maxlength":"", "size":"", "default_value":"", "weight":"2", "fieldset":""' --inputs='"name":"number_comments", "type":"number", "label":"Number of Comments", "options":"", "description":"Number of Coments", "maxlength":"", "size":"", "default_value":"", "weight":"3", "fieldset":""' --inputs='"name":"types", "type":"checkboxes", "label":"Content Types", "options":"['1' => '1']", "description":"Select Content Types", "maxlength":"", "size":"", "default_value":"1", "weight":"4", "fieldset":""' --path="/my_random_module/forms/random_form" --no-interaction COMANDOS ÚTILES EN DRUPAL 34 7, CREAR FORMULARIOS
  • 35. drupal generate:form --module="my_random_module" --class="RandomClassForm" --form-id="default_random_form" --config-file --inputs='"name":"name", "type":"textfield", "label":"Name", "options":"", "description":"User Name", "maxlength":"64", "size":"", "default_value":"", "weight":"0", "fieldset":""' --inputs='"name":"id_user", "type":"number", "label":"User ID", "options":"", "description":"User ID", "maxlength":"64", "size":"", "default_value":"", "weight":"1", "fieldset":""' --inputs='"name":"email", "type":"email", "label":"Email", "options":"", "description":"User email", "maxlength":"", "size":"", "default_value":"", "weight":"2", "fieldset":""' --inputs='"name":"number_comments", "type":"number", "label":"Number of Comments", "options":"", "description":"Number of Coments", "maxlength":"", "size":"", "default_value":"", "weight":"3", "fieldset":""' --inputs='"name":"types", "type":"checkboxes", "label":"Content Types", "options":"['1' => '1']", "description":"Select Content Types", "maxlength":"", "size":"", "default_value":"1", "weight":"4", "fieldset":""' --path="/my_random_module/forms/random_form" --services="database" --services="current_user" --services="email.validator" --no-interaction COMANDOS ÚTILES EN DRUPAL 35 7, FORMS + SERVICIOS
  • 36. “Hacia rutas salvajes” (Routing en Drupal 8) by @jansete https://docs.google.com/presentation/d/17KVjfmgMtIIIDl0N40Vm1iyaUBg27mGE1hV2byIR4OM/edit “Structure of routes” (Drupal 8 documentation) https://www.drupal.org/docs/8/api/routing-system/structure-of-routes Let’s take the best route - Exploring Drupal 8 routing system https://www.srijan.net/blog/exploring-drupal-8-routing-system Using Links in Drupal 8 https://davidjguru.github.io/blog/drupal-fast-tips-using-links-in-drupal-8 Formularios en Drupal 8 (Crear formularios, modificar formularios, ejemplos con Hooks) https://medium.com/drupal-y-yo/form-api-i-comprender-crear-y-modificar-formularios-en-drupal-8-22c0cf4d72d3 https://medium.com/drupal-y-yo/form-api-ii-modificando-formularios-en-drupal-8-mediante-form-alter-78fa949b43d0 https://medium.com/drupal-y-yo/form-api-iii-caso-pr%C3%A1ctico-de-modificaci%C3%B3n-de-formulario-en-drupal-8-f8ab4dd40a5c Prefilling fields in forms (Precargando campos en formularios) https://davidjguru.github.io/blog/drupal-fast-tips-prefilling-fields-in-forms LECTURAS RECOMENDADAS 36 11, AMPLIA INFORMACIÓN
  • 37. https://gitlab.com/davidjguru/drupal-custom-modules-examples/tree/master/my_random_module DESPEDIDA Y CIERRE 37 12, EVERY TIME WE SAY GOODBYE Recuerda que puedes escribirme a davidjguru@gmail.com y aquí tienes el código disponible: In memory of En recuerdo de