Artículos etiquetados con:drupal
Exportar contenidos con Drupal

Drupal es una herramienta muy potente en el desarrollo de aplicaciones web, en pleno crecimiento y con una comunidad totalmente activa. Pero, como cualquier herramienta de desarrollo, tiene puntos débiles y carencias que los desarrolladores deben subsanar. Una de ellas, bastante significativa, es la ausencia de una herramienta en el Core que permita exportar contenidos.

Por suerte, un proyecto en Drupal también se puede nutrir de módulos contribuidos por la comunidad, aunque éstos no pertenezcan al núcleo del CMS.

Indagando en la nube de módulos y funcionalidades que nos ofrece Drupal.org, encontramos dos módulos que pueden subsanar nuestro problema: Structure Sync y Content Sync. Pero, ¿para qué sirve cada módulo? Y lo más importante, ¿en qué contexto podemos usarlos?

 

 

EXPORTAR CONTENIDOS CON CONTENT SYNC

Content Sync nos da la posibilidad de exportar contenido, archivos, bloques, taxonomías y menús desde la interfaz gráfica de Drupal. Desde la pestaña de configuración, el administrador del sistema puede exportar todas las estructuras y contenidos, o realizar las exportaciones de manera individual, en archivos comprimidos .tar.gz.

A priori, Content Sync es una herramienta muy potente y completa: puedes tener todo el contenido de tu web en un único archivo. Pero, ¿qué pasa si queremos realizar una integración continua del contenido de la web?

Content Sync no posee comandos para exportar o importar contenidos. Sólo se puede trabajar con el módulo mediante la interfaz gráfica. Si queremos integrar los contenidos en varios entornos, habría que realizar las exportaciones y las importaciones de forma manual. No es una tarea eficiente.

Content Sync Drupal - SDOS

 

 

STRUCTURE SYNC: INTEGRANDO CON DRUSH

Structure Sync es un módulo relativamente nuevo, ya que el proyecto apareció en Drupal en septiembre de 2017. Sin embargo, aporta muchas facilidades a la integración continua de proyectos en Drupal. De momento sólo es capaz de exportar e importar vocabularios y términos (taxonomías), elementos de menús y bloques personalizados, pero realiza dichas tareas tanto en la interfaz gráfica como mediante comandos.

El módulo en sí trabaja de manera independiente con cada una de las estructuras que maneja, y tiene la gran ventaja de que con tan sólo dos comandos (uno para exportar, otro para importar) podemos trasladar los contenido de un entorno a otro. Al trabajar con drush, podemos incluir el módulo en nuestro flujo de integración continua, y mantener el sitio actualizado en todo momento.

Una de las opciones que ofrece es la de la exportación e importación del contenido mediante la interfaz gráfica de Drupal. Trabaja de manera similar a Content Sync, pero permite elegir qué contenidos se quieren exportar de manera directa. La estructura es la siguiente:

Structure Sync Drupal - SDOS

 

Así que, además de la interfaz gráfica que nos ofrece en nuestra web de Drupal, tendremos las siguientes opciones en nuestro intérprete de comandos:

  • Taxonomías. Para trabajar únicamente con vocabularios y términos de taxonomía, los comandos son los siguientes:
    • drush et, para exportar.
    • drush it, para importar.
  • Bloques. Para trabajar únicamente con bloques (básicos y personalizados). Esta exportación puede llegar a dar error si el bloque posee una imagen como campo. Los comandos son los siguientes:
    • drush eb, para exportar.
    • drush ib, para importar.
  • Menús. Para trabajar únicamente con links de menús, respetando tanto los enlaces como las dependencias. Importante: Los contenidos que generan links a menús no se exportarán junto a dichos links. Los comandos son los siguientes:
    • drush em, para exportar.
    • drush im, para importar.

Estas son las opciones básicas que nos provee el módulo. Pero si queremos exportar todas las estructuras, ¿hay que hacer paso por paso todo lo anterior? La respuesta es no, ya que nos añade dos comandos extra que trabajan con las tres estructuras a la vez:

  • drush ea, para exportar los tres tipos de contenidos a la vez.
  • drush ia, para importar los tres tipos de contenidos a la vez.

Dados los comandos, pasamos al flujo que hay que seguir al realizar una exportación/importación de estructuras en un sitio web de Drupal.

 

 

FLUJO DE SINCRONIZACIÓN DE CONTENIDOS

Para explicar el flujo, vamos a utilizar los comandos más completos. Estos ofrecen más funcionalidades que los que afectan sólo a las entidades individuales. Cabe destacar que el módulo puede sufrir modificaciones que aporten más funcionalidades u ofrezcan un servicio más eficiente.

La exportación y la importación de contenido requieren que la configuración del mismo sea la correcta. Drush nos aporta comandos para ello. El comando drush cex es el encargado de exportar la configuración del sitio, y drush cim el que realiza la importación. El uso de dichos comandos de Drush es requisito indispensable para que la sincronización entre entornos sea completa.

Nos situamos en el entorno del cual queremos exportar nuestras estructuras. Accediendo al directorio raíz de nuestro proyecto, podemos empezar a usar nuestros comandos de Drush.

  • drush ea
  • drush cex

Con ello, se modifica el fichero structure_sync.data.ym (dentro del directorio de sincronización de la configuración) y los ficheros de configuración afectados por las estructuras exportadas.

Para realizar la importación, el orden de los comandos es alterno a la exportación. Es decir, primero importamos la configuración del sitio y después, las estructuras.

  • drush cim
  • drush ia

La importación de estructuras viene dividida por entidades. Es decir, para cada entidad te presenta una serie de opciones:

Flujo sincronización contenidos - import 2 rec - SDOS

 

Las opciones Full, Safe y Force sirven para insertar todas las estructuras de la entidad (menús, en nuestra imagen), y Cancel para finalizar el proceso de importación completo. Actualmente no existe una opción “skip”, que permita continuar con la importación aunque se ignore la actual, pero está en proceso de estudio. Las características son:

  • Full. Importa todas las estructuras, sobreescribiendo las anteriores, excepto las que presenten algún tipo de error o incompatibilidad.
  • Safe. Sólo importa las estructuras que se hayan añadido desde la última modificación.
  • Force. Importa todas las estructuras, ignorando los errores o incompatibilidades que puedan poseer.

Como se ha comentado, la opción Cancel detiene completamente la importación, pero no borra las importaciones realizadas en la ejecución. Esto quiere decir que si, por ejemplo, importas las taxonomías en modo Full, y al aparecer la opción de importar los bloques aplicas la opción Cancel, se detiene la ejecución. No te da la opción de importar los menús, pero las taxonomías sí han sido guardadas.

 

 

¿CON QUÉ OPCIÓN ME QUEDO?

La respuesta es simple vistas las características de ambos módulos (que no llegan a ser incompatibles entre sí): depende del flujo de trabajo y del tamaño del proyecto.

Para la realización de un proyecto pequeño, donde el número de desarrolladores es mínimo (incluso una persona), y no se requiere un flujo de integración continua en el desarrollo del proyecto, la opción de Content Sync es viable. Sin embargo, el hecho de que la exportación sea en ficheros comprimidos desde la interfaz gráfica de Drupal limita en exceso su uso.

Por ello, aunque la cantidad de entidades soportadas es menor, Structure Sync responde de manera más eficiente y lógica a un flujo de integración continua de proyectos. El hecho de que con dos comandos se puedan exportar e importar las estructuras, sin tener que pasar por la interfaz gráfica, es la clave para que su uso sea más extendido que el de Content Sync.

Ahora te toca a ti. ¿Qué herramienta te interesa más, Structure Sync o Content Sync?

 

 


Cómo funciona el sistema de Plugins en Drupal 8

A la hora de solucionar un problema de desarrollo tenemos dos caminos, uno corto y uno largo. ¿Cuál nos interesa? A priori, cualquiera diría que el corto. Y, si bien es cierto que en algunos casos sería así, la verdad es que en la mayoría de los casos lo que nos interesa es el largo.

No te dejes engañar por la situación; eso de “es solo para solucionar mi problema” luego se convierte en “qué bien funciona esto que hiciste, ¿podemos añadirle no sé qué?”. Cuando se te dé el caso, sabrás que el camino corto se habrá convertido en dos veces el camino largo.

Entonces, ¿qué soluciones tenemos para el camino largo? Y la respuesta es:

  • Una jerarquía de clases bien diseñada, flexible, con la especialización en su lugar y fruto de un buen montón de horas en la fase de diseño.
  • Un esquema de configuración con una plétora de opciones que prevea tantas situaciones como sea posible y, como la anterior, sea fruto de una buena fase de diseño.
  • Un modelo ampliable, simple, conciso, asumiendo que siempre faltará algo por hacer, añadir o contemplar.

Curiosamente, aplicando el modelo ampliable, el camino largo del primer proyecto se va acortando en el segundo y en los consecutivos. Esto que he llamado modelo ampliable tiene el nombre técnico de “Plug-in Pattern”. Haciendo el símil con los enchufes de corriente de las casas. Éstas están vacías y casi sin servicios cuando entramos a vivir, pero luego las llenamos con decenas de cosas enchufadas que mejoran sus funciones.

Hay muchísimos casos de éxito con este patrón. Sin salirnos de nuestro campo, tenemos por ejemplo, el PC de IBM y los sistemas operativos modernos; si nos salimos fuera, los coches, que tienen miles de piezas comunes entre distintos modelos, incluso marcas, y a los que podemos ir añadiendo extras, plugins, con el tiempo.

 

 

¿CÓMO APLICAR UN SISTEMA DE PLUGINS?

Para aplicar con éxito un sistema de plugins necesitamos resolver algunas cuestiones:

  • ¿Cómo sé que hay un plugin disponible?
  • De los plugins disponibles, ¿cuáles tengo que aplicar y dónde?
  • Si tengo que aplicar un plugin, ¿cómo lo hago?

Siguiendo el símil de la casa, pongamos que queremos encontrar una solución a una situación de frío en el comedor. Las respuestas a las preguntas anteriores serían:

  • ¿Cómo sé que hay un plugin disponible? Me voy a un centro comercial o ecommerce y miro su oferta.
  • De los plugins disponibles, ¿cuáles tengo que aplicar y dónde? De las estufas que tengan miro una que me valga para aplicarla en el comedor, el donde.
  • ¿Cómo lo hago? Me compro una, y la enchufo en el comedor.

Trasladándonos al desarrollo de aplicaciones, veamos el ejemplo de cómo solucionar la limpieza de una cadena de texto de cosas indeseadas:

  • ¿Cómo sé que hay un plugin disponible? Nuestra aplicación debe tener un sitio donde consultar los plugins instalados y su tipo. Como más adelante veremos.
  • De los plugins disponibles, ¿cuáles tengo que aplicar y dónde? Escogemos aquellos que estén activos y que sean para la limpieza de textos, y los aplicamos al texto que estemos tratando en ese momento.
  • ¿Cómo lo hago? Recorro la lista de plugins resultante de la pregunta anterior y les voy diciendo uno a uno que limpien el texto.

El concepto es simple, ¿verdad? Pues quedémonos con eso, puesto que realmente lo es. Y, como veremos más adelante, en Drupal 8 es más de lo mismo.

 

 

PATRONES DE DISEÑO

Antes de seguir, aclarar que aunque vamos a hablar de plugins en Drupal 8 como algo concreto, realmente es una forma de trabajar abstracta. Es lo que se conoce como un patrón de diseño. Además se necesita comprender otros patrones complementarios para entender todo en su conjunto. Por eso, empecemos explicando qué es un patrón de diseño.

Un patrón de diseño es una solución repetible para un problema recurrente. No pretende dar una solución completa, traducible a código, solo es una plantilla sobre cómo resolver el problema que pueda ser usada en distintas situaciones.

Para el caso concreto que nos reúne aquí creo que debemos ver los patrones que vamos a necesitar, por ser los usados en el sistema de plugins de Drupal 8.

 

PATRÓN PLUG-IN (enchufable)

Este patrón de diseño extiende la funcionalidad de una clase existente para usarla en situaciones más concretas que para la que fue diseñada inicialmente, pero sin alterar la funcionalidad original.

En contraste, tenemos la herencia típica de la orientación a objetos, que modifica o sobrescribe la funcionalidad original, o la configuración, donde las modificaciones están limitadas a las opciones de configuración disponibles, y que hayan sido previstas durante la fase de diseño inicial.

 

PATRÓN DEPENDENCY INJECTION (inyección de dependencias)

Permite integrar instancias en una clase en lugar de confiar en la propia clase a la hora de crear esos objetos. De ahí su segundo nombre: inversión de control de contenedores (Inversion of Control Containers). Es muy útil a la hora de desacoplar los detalles de implementación o desarrollo de tu aplicación, mejorando la reusabilidad del código implicado.

La responsabilidad de manejar las interdependencias de código, incluidas la instanciación de objetos y el enlazado, queda excluida de la clase en sí y es transferida a otro ente, indeterminado, que se determinará cuando sea necesario.

Esto permite compartir contenedores (containers) en multitud de situaciones, cosa que no se puede hacer con el patrón de factorías (factory pattern), por ejemplo.

 

PATRÓN DE FACTORÍAS (fabricadores)

Este patrón usa una entidad abstracta para crear otra. Sí, a mí me genera tantas preguntas como a ti.

En otras palabras, define una interfaz para la creación de objetos, pero deja a las subclases decidir qué clase instanciar. Esto hace al operador ‘new’ totalmente inútil.

El patrón define cómo crear instancias, pero la responsabilidad de creación se dispersa dentro de la jerarquía. Es decir, no se sabe de principio dónde se creará la instancia, lo que lo dota de una gran flexibilidad haciendo un uso extensivo del polimorfismo.

 

 

PLUG-IN API

Drupal contiene muchos plugins diferentes, de diferentes tipos. Este sistema provee un set de guías y componentes de código reutilizable que permite a los desarrolladores exponer componentes extensibles dentro de su código y soporte para manejar estos componentes a través de la interfaz, cuando es necesario.

Los plugins son definidos por los módulos. Estos pueden ofrecer plugins de distintos tipos y módulos diferentes puede disponer de sus propios plugins de un tipo en particular.

 

SERVICIO DE PLUG-INS / PLUG-IN MANAGER

Es la clase controladora central que define cómo se descubren los plugins y cómo instanciarlos. Ésta se llama directamente en cualquier módulo que desee invocar un tipo de plugin.

Aunque existen otros generadores, usaremos el de descubrimiento por anotaciones por ser el más extendido.

A continuación, vamos a ver un ejemplo de crear el esqueleto de un plugin manager con la consola de Drupal: generate:plugin:type:annotation

    1. Generamos un módulo donde definir el tipo de plugin:

      drupal generate:module \
      module="SDOS Plugin API Example"  \
      machine-name="sdos_papi_example"  \
      module-path="modules/custom"  \
      description="Un ejemplo de modulo ampliable."  \
      core="8.x"  \
      package="S-DOS"  \
      module-file  \
      composer  \
      test  \
      twigtemplate
      

      Nota: el generador añade unas comillas de más en el archivo info.yml. Esto genera un error irrecuperable en Drupal, por lo que siempre conviene revisar cada archivo generado.

    2. Se generarán los siguientes archivos:

      /modules/custom/sdos_papi_example/sdos_papi_example.info.yml
      /modules/custom/sdos_papi_example/sdos_papi_example.module
      /modules/custom/sdos_papi_example/composer.json
      /modules/custom/sdos_papi_example/tests/src/Functional/LoadTest.php
      /modules/custom/sdos_papi_example/sdos_papi_example.module
      /modules/custom/sdos_papi_example/templates/sdos-papi-example.html.twig
      
    3. Generamos el plugin manager (a través de la creación de un tipo de plugin, ya que la definición del tipo se hace en el propio manager):

      drupal generate:plugin:type:annotation \
      module="sdos_papi_example"  \
      class="PapiExamplePlugin"  \
      machine-name="papi_example_plugin"  \
      label="Plugin API example plugin"
    4. Se generarán los siguientes archivos:

      modules/custom/sdos_papi_example/src/Annotation/PapiExamplePlugin.php
      modules/custom/sdos_papi_example/src/Plugin/PapiExamplePluginBase.php
      modules/custom/sdos_papi_example/src/Plugin/PapiExamplePluginInterface.php
      modules/custom/sdos_papi_example/src/Plugin/PapiExamplePluginManager.php
      modules/custom/sdos_papi_example/sdos_papi_example.services.yml
      
    5. Generamos también una ruta donde ver los ejemplos:

      drupal generate:controller \
      module="sdos_papi_example"  \
      class="PapiDemoController"  \
      routes='"title":"PapiDemo", "name":"sdos_papi_example.papi_demo", "method":"papiDemo", "path":"/sdos_papi_example/papiDemo/{name}"'  \
      test
      
    6. Esto genera los siguientes archivos:

      modules/custom/sdos_papi_example/src/Controller/PapiDemoController.php
      modules/custom/sdos_papi_example/sdos_papi_example.routing.yml
    7. Modificamos el método papiDemo del archivo sdos_papi_example/src/Controller/PapiDemoController.php, generado en el paso anterior, como sigue:

      <?php
       
      namespace Drupal\sdos_papi_example\Controller;
       
      use Drupal\Core\Controller\ControllerBase;
       
      /**
       * Class PapiDemoController.
       */
      class PapiDemoController extends ControllerBase {
        /**
         * Papidemo.
         *
         * @return array
         *   Return Hello string.
         */
        public function papiDemo($name) {
      	// Default message.
      	$msg = $this->t('This is the @name page.', ['@name' => $name]);
      	$renderArray = [
        	'#type' => 'markup',
        	'#markup' => $msg,
        	'#prefix' => '<p>',
        	'#suffix' => '</p>',
      	];
      	// Page render array.
      	return $renderArray;
        }
      }
    8. Una vez generado, y modificado, activamos nuestro módulo con Drush:

      drush en sdos_papi_example

 

Y al visitar la URL http://localhost/sdos_papi_example/papiDemo/Pedro veremos algo así:

Plugins Drupal - Salida Módulo sin Plugins - SDOS

 

 

DESCUBRIMIENTO DE PLUGINS

Una de las principales responsabilidades del plugin manager es descubrir cualquier implementación del tipo de plugin (plugin type) que maneja. Para cumplir con esta responsabilidad dispone de varias opciones: Anotaciones, Hooks, YAML ó Statics.

Las anotaciones es la opción más extendida. Por eso, es la que utilizaremos para el ejemplo.

    1. Para continuar vamos a generar un nuevo módulo donde hacer uso del nuevo tipo de plugin implementando un plugin nuevo:

      drupal generate:module \
      module="SDOS Plugin Example"  \
      machine-name="sdos_plugin_example"  \
      module-path="modules/custom"  \
      description="Un ejemplo de  plugin para nuestro modulo ampliable."  \
      core="8.x"  \
      package="S-DOS"  \
      module-file  \
      composer  \
      test  \
      twigtemplate
    2. Esto genera los siguientes archivos:

      /modules/custom/sdos_plugin_example/sdos_plugin_example.info.yml
      /modules/custom/sdos_plugin_example/sdos_plugin_example.module
      /modules/custom/sdos_plugin_example/composer.json
      /modules/custom/sdos_plugin_example/tests/src/Functional/LoadTest.php
      /modules/custom/sdos_plugin_example/sdos_plugin_example.module
      /modules/custom/sdos_plugin_example/templates/sdos-plugin-example.html.twig
    3. Y ahora generamos un plugin para nuestro modelo:

      drupal generate:plugin:skeleton \
      module="sdos_plugin_example"  \
      plugin-id="papi_example_plugin"  \
      class="GlassesPapiExamplePlugin"
    4. Esto nos genera:

      modules/custom/sdos_plugin_example/src/Plugin/PapiExamplePlugin/GlassesPapiExamplePlugin.php
    5. El código generado, ya modificado, quedaría así:

      <?php
       
      namespace Drupal\sdos_plugin_example\Plugin\PapiExamplePlugin;
       
      use Drupal\sdos_papi_example\Plugin\PapiExamplePluginInterface;
       
      /**
       * @PapiExamplePlugin(
       *  id = "papi_example_plugin",
       *  label = @Translation("Add glasses."),
       * )
       */
      class GlassesPapiExamplePlugin implements PapiExamplePluginInterface {
        /**
         * The plugin ID of the mapper.
         *
         * @var string
         */
        protected $pluginId;
        /**
         * The name.
         *
         * @var string
         */
        protected $name;
        /**
         * The renderable array.
         *
         * @var array
         */
        protected $renderable;
        /**
         * Constructs the glasses plugin.
         *
         * @param array $parameters
         *   The instance parameters.
         * @param string $plugin_id
         *   The ID of the plugin to use by default.
         */
        public function __construct($parameters, $plugin_id) {
      	$this->pluginId = $plugin_id . '_' . time();
      	$this->name = $parameters['name'];
      	$this->renderable = $parameters['render'];
        }
        /**
         * {@inheritdoc}
         */
        public function build() {
      	$build = ['first_element' => $this->renderable];
      	// Implement your logic.
      	$build['glasses_element'] = [
        	'#type' => 'markup',
        	'#markup' => t('@name has glasses.', ['@name' => $this->name]),
        	'#prefix' => '<p>',
        	'#suffix' => '</p>',
      	];
      	return $build;
        }
        /**
         * {@inheritdoc}
         */
        public function getPluginId() {
      	// Gets the plugin_id of the plugin instance.
      	return $this->pluginId;
        }
        /**
         * {@inheritdoc}
         */
        public function getPluginDefinition() {
      	// Gets the definition of the plugin implementation.
        }
      }

      Nota: Lo importante aquí es el constructor, __construct, que nos da los parámetros de contexto, y el método build que nos permite hacer el trabajo.

    6. Una vez modificado, activamos el módulo con:

      drush en sdos_plugin_example
    7. Ahora nos falta modificar el módulo inicial para que aplique los plugins a la respuesta original. Para ello, en nuestro controlador buscaremos los plugins existentes y los ejecutaremos para que hagan sus cambios.
    8. El código quedará como sigue para /sdos_papi_example/src/Controller/PapiDemoController.php:

      <?php
      namespace Drupal\sdos_papi_example\Controller;
      use Drupal\Core\Controller\ControllerBase;
      /**
       * Class PapiDemoController.
       */
      class PapiDemoController extends ControllerBase {
        /**
         * Papidemo.
         *
         * @return array
         *   Return Hello string.
         */
        public function papiDemo($name) {
      	// Default message.
      	$msg = $this->t('This is the @name page.', ['@name' => $name]);
      	$renderArray = [
        	'#type' => 'markup',
        	'#markup' => $msg,
        	'#prefix' => '<p>',
        	'#suffix' => '</p>',
      	];
      	// Invoque the plugin class.
      	$type = \Drupal::service('plugin.manager.papi_example_plugin');
      	// Get a list of plugins available.
      	$plugin_definitions = $type->getDefinitions();
      	// Call each plugin to get the magic.
      	foreach ($plugin_definitions as $plugin_definition) {
        	$plugin = $type->createInstance(
          	$plugin_definition['id'],
          	[
            	'render' => $renderArray,
            	'name' => $name,
          	]
        	);
        	$renderArray = $plugin->build();
      	}
      	// Page render array.
      	return $renderArray;
        }
      }
    9. Ahora nuestro método de controlador papiDemo elabora la respuesta inicial, busca los plugins disponibles y hace pasar la respuesta por cada uno de ellos para que hagan su trabajo.

Al cargar la URL que definimos al principio, http://localhost/sdos_papi_example/papiDemo/Pedro, veremos algo como esto:

Plugins Drupal - Salida Módulo con Plugins - SDOS

 

 

MÁS SOBRE PLUGINS

En este post sólo hemos visto lo más básico del sistema de plugins de Drupal, que no es poco. En el tintero se nos quedan muchos más conceptos que quizás veamos otro día:

  • Discovery decorators
  • Plug-in Factories
  • Default Factory
  • Container Factory
  • Reflection Factory
  • Factorías personalizadas
  • Plug-in mappers

Cómo contribuir a la comunidad un módulo en Drupal 8

El objetivo de este post es explicar, desde un punto de vista práctico, el procedimiento que debemos seguir si queremos contribuir con la comunidad de Drupal con una funcionalidad específica que hayamos desarrollado previamente. O dicho de otra forma, cómo podemos contribuir con nuestro módulo a la comunidad.

Para ello, y aunque tengamos ciertas prisas en ver nuestro flamante módulo subido a Drupal.org y disponible para su descarga por parte de otros usuarios, debemos ser conocedores de las políticas y procedimientos de publicación, especialmente desde la publicación de la versión 8 de Drupal, que ha acarreado cambios importantes en los procesos involucrados en la aceptación y publicación de un módulo.

 

SECURITY ADVISORY OPT-IN

En versiones anteriores de Drupal, para la publicación directa de un módulo necesitábamos previamente la revisión y valoración por parte de miembros de la comunidad de nuestro código, de forma que existieran ciertas garantías provenientes del criterio de usuarios experimentados y evitar así que el repositorio de módulos contribuidos se convirtiera en un peligroso cajón de código poco eficiente.

Esto tenía un inconveniente importante: a veces este proceso se demoraba en el tiempo, penalizando el incremento de módulos contribuidos por parte de usuarios. Además, en ocasiones, ocurría que durante este proceso de revisión se creaban módulos con funcionalidades similares, ya que en el momento de su escritura por parte de otros usuarios no existían módulos disponibles por estar aún en la cola de espera. Para evitar esto, se creó la Security Advisory Opt-in.

Básicamente, este nuevo sistema consiste en un proceso más permisivo de publicación. Se permite la difusión y descarga de forma directa por parte de los usuarios desarrolladores. Aunque a priori parezca que se evita el sistema de revisión pertinente que garantizaba la calidad y eficiencia de los desarrollos, queda reflejado en la ficha de cada módulo publicado si este ha sido revisado por parte de usuarios experimentados en la comunidad. En caso no ser así, aparece este mensaje:

 

En el momento de publicación de este post, podemos ver varios ejemplos:

Sin embargo, si accedemos a la ficha de descarga de módulos que sí han pasado este proceso de revisión, o su creador ya había pasado previamente por este proceso en otro módulo anterior, lo vemos reflejado con el siguiente símbolo:

 

Algunos ejemplos de módulos sobradamente conocidos son:

Más adelante ampliaremos información sobre los procesos necesarios a seguir para superar este proceso y que nuestro módulo cuente con nuestro sello de calidad. Ahora, suponiendo que ya tenemos nuestro código fuente listo para su publicación, ¡entremos en materia!

 

BECOME A ‘CONFIRMED’ USER

En primer lugar, como no podía ser de otra forma, tenemos que crearnos un perfil en Drupal.org.

Al igual que existe una política de publicación de módulos, para evitar el uso indiscriminado de spam por parte de robots en Drupal.org, existe una política de validación del perfil de los usuarios. De esta forma, tenemos que conseguir el rol “Usuario confirmado” antes de seguir con nuestro proceso de publicación.

No es un proceso complejo, simplemente basta con postear algún contenido en Drupal.org y los robots de Drupal se encargarán de asignarnos el rol directamente. Tienes más información aquí.

 

OBTAINING GIT ACCESS

Antes de subir código fuente al repositorio de Drupal, necesitamos acceso al propio Git. Para ello, basta con seguir estas instrucciones.

 

PUBLICANDO NUESTRO CÓDIGO FUENTE

Es importante hacer un ejercicio de reflexión antes de publicar nuestro primer módulo:

  • ¿Existe un módulo parecido que haga algo similar a lo que voy a publicar?
  • ¿He comprobado si más que un módulo, estoy desarrollando una funcionalidad adicional a un módulo ya existente? De ser así, a lo mejor es más interesante hacerme co-maintainer de un módulo ya existente. Aquí puedes encontrar más información al respecto.

 

SANDBOX

Para la publicación de nuestro módulo, tenemos dos caminos diferentes:

  1. Creación de un Sandbox que nos permite testear nuestro código sin necesidad de que éste se publique directamente en la comunidad. Este es el camino recomendado antes de convertir nuestro módulo en Full Project.
  2. Full Project. De esta forma, nuestro módulo quedaría expuesto directamente a la comunidad para su descarga de forma inmediata. Si no estamos completamente seguros de que nuestro módulo haya pasado todos los criterios de validación necesarios, evitaría este camino.

Una vez que tenemos claro que nuestro camino pasa por crear previamente un Sandbox, accedemos directamente a la URL de publicación del mismo.

En este formulario nos solicitarán información sobre el módulo: nombre, descripción, tipo de proyecto (es importante que, de momento, indiquemos que se trata de un Sandbox), categoría, tipo de mantenimiento, etc.

 

Una vez hayamos completado el formulario de creación de nuestro Sandbox, estamos listos para subir nuestro código. Para ello, sin entrar en profundidad, hacemos clic en la pestaña ‘Version Control’ de nuestro Sandbox, donde encontraremos información detallada sobre los comandos necesarios para pushear nuestro código al repositorio de Drupal:

Si no tienes claro el sistema de convenciones utilizado por Drupal.org para el versionado de tu módulo, puedes ampliar más información aquí.

 

 

FULL PROJECT

Durante el proceso de conversión de Sandbox a Full Project, debemos asegurarnos, entre otras cuestiones, que la calidad de nuestro código cumpla con el coding standard de Drupal. Además debe cumplir otro tipo de requisitos como las instrucciones de instalación, la descripción detallada de la funcionalidad que lleva a cabo nuestro módulo, etc.

Para ello, podemos hacer uso de varias herramientas.

La herramienta pareview.sh se encargará de revisar el coding standard y las buenas prácticas de Drupal, simplemente con indicar el repositorio Git de nuestro Sandbox, mostrando los posibles errores encontrados mediante un informe. Esta herramienta utiliza Code Sniffer para analizar el código PHP, haciendo uso de las métricas de Drupal incluidas en la herramienta Coder.

Si estamos seguros de que hemos cumplido con todos los requisitos indicados anteriormente y estamos listos para publicar nuestro módulo, es hora de convertir nuestro Sandbox en Full Project. Para ello, editamos nuestro Sandbox:

 

Y hacemos clic en la pestaña ‘Promote’:

 

Completamos el formulario asegurándonos de ingresar un nombre corto para nuestro módulo. Este nombre se usará para construir la URL: drupal.org/project/[short name]. En los módulos de sandbox, el nombre abreviado será el ID del proyecto. Así que es importante que este nombre sea descriptivo de la funcionalidad que cumple nuestro proyecto.

Una vez que nuestro Sandbox ha sido promocionado, el repositorio de código pasa de /sandbox/username/123456.git a project/project_name.git. Esto implica que tengamos que hacer de nuevo un clone de nuestro proyecto en nuestro entorno local si queremos seguir haciendo modificaciones del código.

Es hora de ver con qué tipo de release queremos salir a “producción”. Para ello, en Drupal podemos distinguir tres tipos de releases oficiales (las releases de desarrollo quedan para las versiones inestables que están actualmente en evolución por parte de los mantenedores):

  • Versión recomendada. En este caso, el mantenedor del proyecto (o sea, nosotros) considera que esta es la versión más estable para su descarga.
  • Release soportada. Para aquellos casos en los que el desarrollador piensa que es posible que no sea la mejor opción, ya sea porque la release es o muy nueva o muy antigua.
  • Versión no soportada. Por alguna razón, el mantenedor del módulo ha considerado que no es la versión más apropiada.

Aquí tienes más información sobre los tipos de release.

Así que vamos a crear nuestra primera release. Una vez la completemos, podremos decidir si pasarla a una release oficial o bien seguimos en la versión de desarrollo porque queramos seguir evolucionando el módulo. En cualquier caso, primero es necesario que creemos un tag con la release adecuada y la pusheemos a nuestro repositorio de Git de Drupal.org.

 

CREANDO NUESTRA RELEASE OFICIAL

En la ficha de nuestro Full Project, hacemos clic en la pestaña ‘Version control’ y seguimos las instrucciones indicadas en ‘Tag for a stable release’.

Una vez que hemos realizado el push de nuestra release, volvemos a la página principal de nuestro proyecto y hacemos clic en ‘Add new release’ (abajo del todo):

 

Si el nombre del tag creado ha seguido las convenciones comentadas anteriormente, el sistema nos pedirá la naturaleza de la release (New Feature, Bug, etc.). Damos a guardar y tendremos listo nuestro primer archivo descargable para su uso (ten en cuenta que el sistema puede tardar hasta 12 horas en disponer del archivo y, por lo tanto, del enlace para su descarga, así que no hay que impacientarse en este punto).

Además, recientemente se ha cambiado la política de publicación de releases, y ahora únicamente aparecen para su descarga directa las releases estables (y no las de desarrollo). Si quieres que aparezcan también las release de desarrollo, haz click en ‘Show in project’s download table when branch is supported’.

Desde este momento, ya tenemos nuestro primer módulo publicado y listo para su descarga por parte de terceros. Sin embargo, y para nuestra desgracia, vemos que nuestro módulo no está cubierto por la Security Advisory Policy. ¿Recordáis la política de publicación con la que hemos empezado este artículo? Pues bien, es hora de intentar conseguir nuestro sello.

 

SECURITY ADVISORY POLICY

Hay que tener en cuenta que esta marca solo afecta a versiones estables (ni alpha, ni beta, ni RC). Para aplicar el sello de “seguridad”, en la edición del proyecto hay que activar la opción ‘opt-in’, sin embargo no vamos a poder si no tenemos el rol adecuado (git vetted role).

Para obtener los permisos y poder acceder a esta opción, un administrador de Git de Drupal debe concedérnoslo. Para ello, debemos crear una issue de revisión que servirá para que otros usuarios puedan revisar nuestro módulo y marcarlo como apto. Aquí puedes seguir las instrucciones precisas para hacerlo.

Cuando un miembro de la comunidad nos marque el proyecto como RTBC. nuestro proyecto entrará en una lista de revisión para que un administrador nos conceda el rol vetted user y así poder marcar nosotros mismos nuestros proyectos como ‘opt-in’.

Existen dos listas de revisión de módulos:

  • Lista normal. Tarda muchísimo en ser evaluada por la comunidad (meses o años)
  • Lista prioritaria. Para acceder a esta lista tenemos que acceder al programa Review Bonus.

 

REVIEW BONUS

Si queremos priorizar nuestro post de revisión y garantizar que nuestro módulo obtiene el sello de calidad lo antes posible, tenemos que empezar a contribuir en la comunidad, y qué mejor que hacerlo a través del programa Review Bonus de Drupal.org.

Este programa consiste básicamente en ayudar a la comunidad de voluntarios de Drupal.org a revisar módulos de otros contribuidores que se encuentran en una situación similar a la nuestra. De esta forma, el sistema de Review bonus nos invita a revisar, al menos, hasta 3 módulos de otras personas que están en un proceso similar. De esta forma podemos encontrar los mismos fallos de seguridad en el código que podrían encontrar en nuestro módulo.

Debido a que el proceso de solicitud es completamente voluntario, muchos de los revisores más activos usan el programa Review Bonus para priorizar qué módulos revisan. Este programa le da prioridad a aquellos que también están ayudando a revisar otras aplicaciones.

Para comenzar el proceso de revisión de un módulo, accedemos a la ‘Lista normal’ mencionada anteriormente. Existe una plantilla que podemos tener como referencia para saber qué tenemos que revisar. Cada vez que encontramos algún error en alguno de los módulos de esta lista, realizamos un post en el hilo, copiamos la URL de nuestro post y lo referenciamos en el body del post de revisión que hemos creado para que nos validen nuestro propio módulo.

Una vez que hayamos revisado y referenciado tres incidencias en nuestro post de revisión del módulo, editamos nuestro propio post y le añadimos el tag ‘PAReview: review bonus’ en el campo ‘Issue Tags’ en el formulario de comentarios de nuestro post. Desde este momento, nuestro post de revisión estará en la lista prioritaria.

Aquí tenemos un post de ejemplo de un desarrollador que ha revisado a su misma vez otros tres posts. De esta forma podemos ver la estructura que debería tener nuestro post de revisión.

Finalmente, algún administrador de la comunidad de Drupal revisará nuestro módulo y nos concederá el rol necesario para que podamos conceder nosotros mismos los sellos de seguridad a los módulos que desarrollemos a partir de ahora sin tener que volver a pasar por este proceso.

 

DRUPAL EN SDOS

Desde SDOS impulsamos el desarrollo y la contribución a la comunidad a través de nuestros equipos multidisciplinares, estableciendo metodologías ágiles de desarrollo y siendo fieles tanto al coding standard establecido a través de la comunidad de Drupal como a sus buenas prácticas de desarrollo. Así mismo, en SDOS estamos comprometidos con la comunidad, colaborando con la Drupal Association y apostando por los diferentes eventos desarrollados a nivel nacional.


Aprende con nosotros: Curso Drupal 8

SDOS colabora con EOI en la organización de un curso de Drupal 8 destinado a jóvenes de entre 18 y 29 años en situación de desempleo. El objetivo es formar profesionales del desarrollo web, en un mercado laboral marcado por la transformación digital de la sociedad.

El curso se impartirá las instalaciones de EOI en Sevilla. Con una duración de 175 horas (lectivas, tutorías y trabajo de alumno), el temario está orientado a convertir a los alumnos en expertos en Drupal 8, site building y backend.

La materia estará impartida por Forcontu, empresa especializada en formación y consultoría en Drupal. Las cifras de más de 8.000 personas y 131 países, avalan la calidad y el reconocimiento de su trayectoria.

La formación es gratuita para los seleccionados, 100% cofinanciada por el Fondo Social Europeo.

 

REQUISITOS

  • Tener entre 18 y 29 años, estar en situación de desempleo e inscritos, en el momento de inscripción, en el Sistema Nacional de Garantía Juvenil.
  • Formación mínima: FP de grado superior y/o Titulación universitaria
  • Conocimientos de inglés
  • Ordenador portátil con:
    • Netbeans 8.x (PHP y HTML)
    • PuTTY o similar (conexión SSH)
    • Filezilla o similar (conexión SFTP)
    • Navegador Chrome o Firefox (actualizado)

 

CONTENIDOS DEL CURSO

1. MÓDULO SITE BUILDING

  • Introducción a Drupal 8
  • Instalación de Drupal 8
  • El Área de administración
  • Gestión de contenidos
  • Tipos de contenido I: Introducción a tipos de contenido y campos
  • Tipos de comentario
  • Gestión de menús
  • Gestión de bloques
  • Temas I: Instalación y configuración de temas
  • Ampliación de funcionalidades con módulos contribuidos
  • Gestión de usuarios, roles y permisos
  • Taxonomía
  • Formatos de texto y editores Wysiwyg
  • Tipos de contenido II: Campos adicionales
  • Gestión de archivos e imágenes
  • Tipos de contenido III: Presentación de contenidos
  • Búsquedas
  • Idiomas, traducción y sitios multilingües I
  • Idiomas, traducción y sitios multilingües II
  • Vistas I: Creación y configuración de vistas
  • Vistas II: Campos, filtros y ordenación
  • Vistas III: Configuración avanzada
  • Temas II: Modificación de temas
  • Otros módulos: Foros y Books
  • Agregar y generar contenido sindicado (RSS)
  • Gestión, mantenimiento y actualización del portal
  • Instalación de Drupal 8 en servidor local
  • Introducción a la Gestión de la configuración
  • Edición de contenidos con Paragraphs
  • Formularios
  • Panels
  • Display Suite
  • Vistas IV: Ampliación de vistas
  • Flujo de trabajo y control de acceso
  • Práctica Final Site Building

2. MÓDULO DE LENGUAJES DE PROGRAMACIÓN

  • PHP I: Introducción a PHP
  • PHP II: Funciones de la API de PHP
  • PHP III: Programación orientada a objetos
  • PHP IV: Patrones de diseño
  • MySQL I: Introducción a SQL y MySQL
  • MySQL II: Herramientas de gestión de la base de datos
  • Symfony2 I: Introducción a Symfony
  • Práctica Final Lenguajes de Programación

3. MÓDULO BACK-END

  • Drush I: Comandos de Drush
  • Drupal Console I: Comandos de Drupal Console
  • Arquitectura de Drupal 8
  • Buenas prácticas de desarrollo con Drupal
  • Introducción a la creación de módulos
  • Enrutamiento y menús
  • Introducción a la API de Configuración
  • Bases de datos I: Creación de tablas
  • Bases de datos II: Sentencias select, insert, update y delete
  • Formularios I: Creación de formularios
  • Formularios II: Elementos de formulario
  • Formularios III: Ampliación de formularios
  • Plugins I: Introducción a plugins y bloques
  • Usuarios y permisos
  • Theming I: Creación de temas y plantillas
  • Theming II: Theming en módulos
  • Plugins II: Tipos de plugins y servicios
  • Entidades I: Entidades de configuración
  • Entidades II: Entidades de contenido
  • Práctica Final Back-End

4. EMPLEABILIDAD

  • Cómo redactar un CV
  • Entidad digital de la persona
  • Principales canales de búsqueda de empleo
  • El proceso de selección
  • Entrevistas de trabajo
  • Incorporación a la empresa

 

INSCRIPCIÓN

¡No te quedes sin tu plaza! Es tan sencillo como completar este formulario de inscripción. Si tienes cualquier duda o necesitas más información, puedes consultar todos los detalles en la web de EOI, contactar en el teléfono 954 46 3377, o a través de la dirección elenamartinez@eoi.es.

 

¡Te esperamos!

 


Uso de cookies

Este sitio web utiliza cookies para que tengas la mejor experiencia de usuario. Si continúas navegando estas dando tu consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pincha el enlace para obtener más información.

ACEPTAR
Aviso de cookies