Slide 1

Slide 1 text

Migrando un Field Formatter a Drupal 8 DrupalCamp Perú 2013

Slide 2

Slide 2 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Introducción ¿Qué es Vine?, Importancia en móviles y redes sociales ¿Cómo se usa el módulo Vine para Drupal? Beneficios al utilizar Formatters Construcción del módulo para Drupal 7 Migración del módulo a Drupal 8 Enlaces para profundizar en Migración de módulos y Plugins en Drupal 8 Índice de temas

Slide 3

Slide 3 text

Powered by Drupal Mapa Visual de temas Vine Introducción Módulo Vine para Drupal ¿Qué es? Importancia ¿Cómo se usa? Construcción del módulo para Drupal 7 Migración del módulo a Drupal 8 Profundizar

Slide 4

Slide 4 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal ¿Por qué se ha elegido un módulo simple? Para abarcar aspectos puntuales, que son particulares a la funcionalidad de este módulo ¿Qué documentación es necesaria? Al ser simple, es suficiente con estas diapositivas Sin embargo, es recomendable entender los conceptos y las implementaciones Migrando un Módulo Simple a Drupal 8 •Field Formatter •Documentación acerca de Migración •Drupal 8 Plugins

Slide 5

Slide 5 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal ¿Qué es Vine? • Es la aplicación de video-microblogging de Twitter. • Tiene interacción social. • Está orientada a smartphones. • Los videos son de 7 segundos.

Slide 6

Slide 6 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Cuando se tuitea un Vine ... Se ve el video en la web de Twitter y en su aplicación para móviles.

Slide 7

Slide 7 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal ¿Qué realiza este módulo? A partir de la URL de un video en Vine, y una configuración de presentación, lo muestra en el contenido. Vine module https://drupal.org/project/vine Es un Field Formatter E implementa sus opciones de configuración. Módulo Vine para Drupal

Slide 8

Slide 8 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal 1. Utilizar un campo de Texto 2. Escoger el Formato “Embedded Vine” Configuración

Slide 9

Slide 9 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal En cualquier Tipo de Contenido utilizar o crear un Campo del tipo Texto I. Utilizar un campo de Texto

Slide 10

Slide 10 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal En el Display, escoger el Formato “Embedded Vine” para el campo utilizado 2. Escoger el Formato Embedded Vine

Slide 11

Slide 11 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Es sencillo de utilizar

Slide 12

Slide 12 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal 1. Copiar la URL de un video en Vine https://vine.co/v/hmpvn259tjt

Slide 13

Slide 13 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Pegar la URL

Slide 14

Slide 14 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Eso es todo Ejemplo en vivo

Slide 15

Slide 15 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Opciones del Embed

Slide 16

Slide 16 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal El módulo provee los tamaños y estilos que sugiere Vine. Podemos elegir entre dos etilos: Simple y Postcard; Customizando: Estilo

Slide 17

Slide 17 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal y entre tres tamaños: Large (600px), Medium (480px) y Small (320px) Customizando: Tamaño

Slide 18

Slide 18 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Para: • Tener una mejor estructura de datos • No copiar y pegar código HTML en nuestro contenido • Reutilizar el contenido con flexibilidad • Aplicar cambios rápidamente Aumentamos la productividad y seguridad Mejoramos la administración ¿Por qué utilizar Formatters?

Slide 19

Slide 19 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal https://drupal.org/project/vine drush dl vine drush en vine Descarga y activación

Slide 20

Slide 20 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Creación del Módulo para Drupal 7

Slide 21

Slide 21 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Estructura de archivos

Slide 22

Slide 22 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal El archivo .info tiene el siguiente contenido: vine.info name = Vine description = "Adds a Formatter for text fields to display embedded Vines" package = Fields core = 7.x files[] = vine.module

Slide 23

Slide 23 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal El módulo implementa cuatro hooks, que listamos a continuación: vine.module hook_field_formatter_info() function vine_field_formatter_info() hook_field_formatter_settings_form() function vine_field_formatter_settings_form($field, $instance, $view_mode, $form, & $form_state) hook_field_formatter_settings_summary() function vine_field_formatter_settings_summary($field, $instance, $view_mode) hook_field_formatter_view() function vine_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display)

Slide 24

Slide 24 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Aquí se definen datos del módulo e información puntual: El nombre con el que el sistema de Drupal reconocerá a este formatter. La etiqueta (Label) con la que se identificará a este formatter en la interfaz (ej. configuración de tipos de contenido). El tipo de campo para el que está disponible este Formatter. Las configuraciones iniciales. vine_field_formatter_info() Documentación: hook_field_formatter_info en Drupal 7 API function vine_field_formatter_info() { return array( 'vine_formatter' => array( 'label' => t('Embedded Vine'), 'field types' => array('text'), 'settings' => array( 'size' => '480px', 'style' => 'simple', ), ), ); } 2 1 3 4 2 1 3 4

Slide 25

Slide 25 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Aquí se crea el formulario de configuración: Obtiene el view_mode (ej: default, teaser) en el que se almacenan nuestras configuraciones Obtiene las configuraciones propiamente dichas Inicializa la variable element Prepara las listas de selección con las opciones disponibles vine_field_formatter_settings_form() function vine_field_formatter_settings_form($field, $instance, $view_mode, $form, & $form_state) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; $element = array(); $element['size'] = array( ... ); $element['style'] = array( ... ); return $element; } 2 1 3 4 2 1 3 4 4 Documentación: hook_field_formatter_settings_form en Drupal 7 API

Slide 26

Slide 26 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Este arreglo provee lo necesario para construir el widget de selección de tamaño del Vine. $element[‘size’] $element['size'] = array( '#type' => 'select', // Utiliza una lista de selección '#title' => t('Vine Size'), // Etiqueta del widget '#description' => t('Select the size for embedded Vine'), // Texto de ayuda '#default_value' => $settings['size'], // Obtiene el valor actualmente establecido '#options' => array( // Ofrece las opciones disponibles '320px' => 'Small (320px)', '480px' => 'Medium (480px)', '600px' => 'Large (600px)', ), );

Slide 27

Slide 27 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Este arreglo provee lo necesario para construir el widget de selección del estilo del Vine. $element[‘style’] $element['style'] = array( '#type' => 'select', // Utiliza una lista de selección '#title' => t('Vine Style'), // Etiqueta del widget '#description' => t('Select the style for embedded Vine'), // Texto de ayuda '#default_value' => $settings['style'], // Obtiene el valor actualmente establecido '#options' => array( // Ofrece las opciones disponibles 'simple' => 'Simple', 'postcard' => 'Postcard', ), );

Slide 28

Slide 28 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Esta función provee el resumen de la configuración establecida para el formatter. Obtiene el view_mode (default, teaser) en el que se almacenan nuestras configuraciones. Obtiene las configuraciones propiamente dichas. Muestra un texto claro. Ejemplos: "Utiliza un tamaño Mediano y estilo Postal", "Utiliza un tamaño Grande y estilo Simple". vine_field_formatter_settings_summary() function vine_field_formatter_settings_summary($field, $instance, $view_mode) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; $summary = t('Use a @size embedded Vine with "@style" style', array( '@size' => $settings['size'], '@style' => $settings['style'], )); return $summary; } 2 1 3 2 1 3 Documentación: hook_field_formatter_settings_summary en Drupal 7 API

Slide 29

Slide 29 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Esta función se encarga de proveer el código HTML que logre la visualización deseada, y considera las configuraciones establecidas para el formatter. vine_field_formatter_view() function vine_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $element = array(); $settings = $display['settings']; // Obtenemos las configuraciones $size = $settings['size']; // Obtenemos el tamaño establecido $style = $settings['style']; // Obtenemos el estilo establecido foreach ($items as $delta => $item) { // Obtenemos una URL de Vine en el contenido $safe_value = $item['safe_value']; } if (isset($safe_value) ) { // Construimos el HTML del embed $element[0]['#markup'] = ''; } return $element; } Documentación: hook_field_formatter_view en Drupal 7 API

Slide 30

Slide 30 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Así como en un editor de textos le damos formato a una palabra, por ejemplo, a letras cursivas y en negrita. De la misma manera a un texto ingresado en un campo de un contenido podemos aplicarle un formato, sencillo o complejo. A continuación un par de ejemplos: Campo “color” Ingresamos el valor “rojo” Mostramos un recuadro de color rojo Campo “tipo de mascota" Seleccionamos “gato” Mostramos imagen referencial de un gato Field Formatter

Slide 31

Slide 31 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Módulo en Drupal 7 Migración del módulo a Drupal 8 Módulo en Drupal 8

Slide 32

Slide 32 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal La estructura en Drupal 8 es otra Estructura de archivos en D8 Nos es familiar la estructura en Drupal 7

Slide 33

Slide 33 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal El archivo .info.yml contiene: vine.info.yml name: Vine type: module description: 'Adds a formatter for text fields for display embedded Vines.' package: Fields version: 8.x-1.0 core: 8.x dependencies: - field hidden: false name = Vine description = "Adds a formatter for text fields for display embedded Vines" package = Fields core = 7.x files[] = vine.module El archivo .info en D7 contenía: Documentación: .info files are now .info.yml files, Writing module .info.yml files (Drupal 8.x)

Slide 34

Slide 34 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Crear una clase. En una ruta como... /lib/Drupal//Plugin/field/formatter/.php vine /lib/Drupal/ vine /Plugin/field/formatter/VineFormatter.php VineFormatter.php

Slide 35

Slide 35 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal • namespace • use Clase Formatter - Encabezado /** * @file * Contains \Drupal\vine\Plugin\field\formatter\VineFormatter */ namespace Drupal\vine\Plugin\field\formatter; // Field formatter annotation class use Drupal\field\Annotation\FieldFormatter; // Annotation translation class use Drupal\Core\Annotation\Translation; // FormatterBase class use Drupal\field\Plugin\Type\Formatter\FormatterBase; // EntityInterface use Drupal\Core\Entity\EntityInterface; // FieldInterface use Drupal\Core\Entity\Field\FieldInterface;

Slide 36

Slide 36 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal En la mayoría de casos querremos extender Drupal/field/Plugin/Type/Formatter/FormatterBase Clase VineFormatter Extends FormatterBase class VineFormatter extends FormatterBase { .... }

Slide 37

Slide 37 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Se ha removido los hooks: •hook_field_formatter_info Es reemplazado por Plugin Discovery basado en anotaciones, utilizando la clase de anotación Drupal/field/Annotation/FieldFormatter Las propiedades están documentadas en las anotaciones de la clase •hook_field_formatter_settings_form FormatterInterface::settingForm() •hook_field_formatter_settings_summary FormatterInterface::settingsSummary() •hook_field_formatter_prepare_view FormatterInterface::prepareView() •hook_field_formatter_view FormatterInterface::viewElements() ¿Y los hooks de Drupal 7?

Slide 38

Slide 38 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal En Drupal 8, se realiza en una anotación (bloque comentado) Drupal/field/Annotation/FieldFormatter Bloque de Anotaciones 1 /* * * * Plugin implementation of the 'vine_formatter' formatter * * @FieldFormatter( * id = "vine_formatter", * module = "vine", * label = @Translation("Embedded Vine"), * field_types = { * "text", * }, * settings = { * "size" = "480px", * "style" = "simple" * } * ) * * */ class VineFormatter extends FormatterBase { .... 1 2 3 function vine_field_formatter_info() { return array( 'vine_formatter' => array( 'label' => t('Embedded Vine'), 'field types' => array('text'), 'settings' => array( 'size' => '480px', 'style' => 'simple', ), ), ); } En Drupal 7 declarábamos propiedades y configuraciones iniciales en hook_field_formatter_info 2 3

Slide 39

Slide 39 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal En Drupal 8, lo realiza FormatterInterface::settingForm() FormatterInterface::settingForm() /** * {@inheritdoc} */ public function settingsForm(array $form, array &$form_state) { $element = array(); $element['size'] = array( ... ); $element['style'] = array( ... ); return $element; } 1 2 function vine_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) { $display = $instance['display'][$view_mode]; $settings = $display['settings']; $element = array(); $element['size'] = array( ... ); $element['style'] = array( ... ); return $element; } En Drupal 7 hook_field_formatter_settings_form creaba el formulario de configuración 1 2

Slide 40

Slide 40 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Este arreglo provee lo necesario para construir el widget de selección de tamaño del Vine. $element[‘size’] $element['size'] = array( '#type' => 'select', '#title' => t('Vine Size'), '#description' => t('Select the size for embedded Vine'), '#default_value' => $this->getSetting('size'), '#options' => array( '320px' => 'Small (320px)', '480px' => 'Medium (480px)', '600px' => 'Large (600px)', ), ); D8 $element['size'] = array( '#type' => 'select', '#title' => t('Vine Size'), '#description' => t('Select the size for embedded Vine'), '#default_value' => $settings['size'], '#options' => array( '320px' => 'Small (320px)', '480px' => 'Medium (480px)', '600px' => 'Large (600px)', ), ); D7

Slide 41

Slide 41 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Este arreglo provee lo necesario para construir el widget de selección del estilo del Vine. $element[‘style’] Análogamente

Slide 42

Slide 42 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal FormatterInterface::settingsSummary() public function settingsSummary() { $summary = array(); $summary[] = t('Use a @size embedded Vine with "@style" style', array( '@size' => $this->getSetting('size'), '@style' => $this->getSetting('style'), )); return $summary; } En Drupal 8, lo realiza FormatterInterface::settingsSummary() function vine_field_formatter_settings_summary($field , $instance, $view_mode) { $display = $instance['display'] [$view_mode]; $settings = $display['settings']; $summary = t('Use a @size embedded Vine with "@style" style', array( '@size' => $settings['size'], '@style' => $settings['style'], )); return $summary; } En Drupal 7 hook_field_formatter_settings_form provee el resumen de la configuración establecida para el formatter

Slide 43

Slide 43 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Provee el código HTML que logre la visualización deseada, y considera las configuraciones establecidas para el formatter. FormatterInterface::viewElements() function vine_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) { $element = array(); $settings = $display['settings']; $size = $settings['size']; $style = $settings['style']; foreach ($items as $delta => $item) { $safe_value = $item['safe_value']; } if (isset($safe_value) ) { $element[0]['#markup'] = ... } return $element; } public function viewElements(EntityInterface $entity, $langcode, FieldInterface $items) { $elements = array(); $size = $this->getSetting('size'); $style = $this->getSetting('style'); foreach ($items as $delta => $item) { $elements[$delta] = array( '#type' => 'markup', '#markup' => ... } } return $elements; } En Drupal 8, lo realiza FormatterInterface::settingsSummary() En Drupal 7, lo realiza hook_field_formatter_view

Slide 44

Slide 44 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal #markup ''; ''; En Drupal 7 En Drupal 8

Slide 45

Slide 45 text

Powered by Drupal Agregando un campo de texto en Drupal 8

Slide 46

Slide 46 text

Powered by Drupal Configurando el Display Format

Slide 47

Slide 47 text

Powered by Drupal Así se ve en el Nodo

Slide 48

Slide 48 text

Powered by Drupal Configurando los settings para el Teaser

Slide 49

Slide 49 text

Powered by Drupal Así se ve en el Home

Slide 50

Slide 50 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal D7 to D8 upgrade: fields, widgets and formatters • Converting 7.x modules to 8.x (Índice) • Upgrade your module to Drupal 8 - Drupalcon Prague 2013 más información http://webchick.net/upgrade-modules-d8 • D7 to D8 upgrade tutorial: Pants module Un Google Doc con estilo aceptable • D7 to D8 tutorial: pathinfo module Documentación acerca de Migración

Slide 51

Slide 51 text

Introducción Vine Módulo Vine Uso Construcción en D7 •Archivos •vine.info vine.module vine 8.x-1.0 •Archivos •vine.info.yml vineFormatter.php Powered by Drupal Field formatters are now Plugins https://drupal.org/node/1805846 Drupal 8 Field API series part 1: field formatters http://realize.be/drupal-8-field-api-series-part-1-field-formatters Drupal 8 Field API series part 2: field widgets http://realize.be/drupal-8-field-api-series-part-2-field-widgets Why Plugins? https://drupal.org/node/1637614 Understanding Drupal 8's plugin system http://previousnext.com.au/blog/understanding-drupal-8s-plugin-system D8 Plugins

Slide 52

Slide 52 text

Powered by Drupal Gracias A todos