Agregar clases automáticamente a una etiqueta a través de un Filtro de CKEditor y WYSIWYG en Drupal 8.

Drupal 8 + Ckeditor

Hoy continuamos con la herramienta CKEditor, en la cual te traigo un tema que a muchos nos ha dado dolor de cabeza, y es

¿Cómo agregamos una clase específica a una etiqueta html en CKEditor con Drupal 8?

En este caso les mostraremos la forma de hacerlo.

Supongamos que creamos esta lista

Etiquetas de Ejemplo CKEditor

y elegimos el filtro "Basic HTML"  y guardamos este artículo e inspeccionamos el resultado HTML, observaremos lo siguiente: 

Después de guardar el contenido, se crean las etiquetas correctamente.

 

Entonces nosotros vamos ahora a crear un filtro para poder agregar automáticamente una clase llamada claseJhonatan.

Para realizar esta sección, iremos a la carpeta /module/custom y crearemos una carpeta llamada filtrosckeditor y luego crearemos el siguiente archivo:

filtrosckeditor.info.yml

Le pondremos el siguiente código:

name: Filtros CKEditor
description: Módulo para crear un filtro customizado para el CKEditor en Drupal 8 para agregar clases automáticas
type: module
package: custom
core: 8.x

Luego vamos a crear unas nuevas carpetas llamada src/Plugin/Filter y en este crearemos un nuevo archivo llamado filtrosckeditor.php y pondremos este código:

<?php

namespace Drupal\filtrosckeditor\Plugin\Filter;

use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;

/**
 * @Filter(
 *   id = "filtrosckeditor",
 *   title = @Translation("Filtros customizados"),
 *   description = @Translation("Filtros customizados CKeditor y WYSIWYG"),
 *   type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
 * )
 */
class filtrosckeditor extends FilterBase {

    public function process($text, $langcode) {
        $replace = '<ul class="claseJhonatan"';
        $new_text = str_replace('<ul', $replace, $text);
        return new FilterProcessResult($new_text);
      }

  
}

Este código está bastante sencillo, lo que hacemos es reemplazar el html

<ul 

por

<ul class="claseJhonatan" 

Hasta ahora ya tenemos todo correctamente, sin embargo para que funcione debemos hacer varios pasos:

1) Ir a la ruta: admin/modules e instalar este módulo.

2) Ir a la ruta /admin/config/content/formats/manage/basic_html 

y marcamos el filtro que creamos:

Filtros customizados

y guardamos. 

Si volvemos a ver el código HTML que inspeccionamos, observaremos lo siguiente:

Despues del filtro Codigo HTML

Esta clase, debe existir en el tema que se está usando actualmente o en un archivo libraries.yml de nuestro módulo.

En este sentido, vamos a crear un archivo llamado filtrosckeditor.libraries.yml en el mismo directorio donde está el archivo filtrosckeditor.info.yml

Nota: Aquí dejo el enlace donde está la documentación del archivo Libraries en Drupal 8.

En este archivo pondremos este código:

libreriafiltrosckeditor:
  css:
    theme:
      css/style.css: {}
  

Luego creamos el siguiente archivo css en la siguiente ruta: 

css/style.css

.claseJhonatan
 {
    color: red;
}

Luego vaciamos la caché en la ruta:

admin/config/development/performance

Una vez haya culminado el proceso anterior, entonces procederemos a modificar el archivo filtrosckeditor.php a fin de poder aplicar el css de lugar a la case claseJhonatan.

El archivo quedaría de la siguiente manera:

<?php

namespace Drupal\filtrosckeditor\Plugin\Filter;

use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;


/**
 * @Filter(
 *   id = "filtrosckeditor",
 *   title = @Translation("Filtros customizados"),
 *   description = @Translation("Filtros customizados CKeditor y WYSIWYG"),
 *   type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
 * )
 */
class filtrosckeditor extends FilterBase {

    public function process($text, $langcode) {
        $replace = '<ul class="claseJhonatan"';
        $new_text = str_replace('<ul', $replace, $text);
       // return new FilterProcessResult($new_text);
        
       $result = new FilterProcessResult($new_text);
        $result->setAttachments(array(
          'library' => array('filtrosckeditor/libreriafiltrosckeditor'),
        ));
    
        return $result;
        
      }
}

 

Si nos fijamos, hemos comentado la línea: 

return new FilterProcessResult($new_text);

y en su lugar, hemos agregado las siguientes: 

     $result = new FilterProcessResult($new_text);
        $result->setAttachments(array(
          'library' => array('filtrosckeditor/libreriafiltrosckeditor'),
        ));
    
        return $result;

De esta manera, aplicamos el css que declaramos en la librería llamada libreriafiltrosckeditor.

Si observamos el html del artículo que hicimos, veremos lo siguiente:

Libreria aplicada

 

 

Nota: si despues de realizar estos pasos no te funciona, te muestro como quedaría el directorio del módulo:

Carpeta del módulo

Otra forma de obtener el mismo resultado

y es la que recomiendo

es modificando el archivo filtrosckeditor.php de la siguiente manera:

<?php

namespace Drupal\filtrosckeditor\Plugin\Filter;

use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;

use Drupal\Component\Utility\Html;  //agregamos este namespace

/**
 * @Filter(
 *   id = "filtrosckeditor",
 *   title = @Translation("Filtros customizados"),
 *   description = @Translation("Filtros customizados CKeditor y WYSIWYG"),
 *   type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,
 * )
 */
class filtrosckeditor extends FilterBase {
    //forma anterior.
    /*public function process($text, $langcode) {
        $replace = '<ul class="claseJhonatan"';
        $new_text = str_replace('<ul', $replace, $text);
       // return new FilterProcessResult($new_text);
        
       $result = new FilterProcessResult($new_text);
        $result->setAttachments(array(
          'library' => array('filtrosckeditor/libreriafiltrosckeditor'),
        ));
    
        return $result;
        
      }
      
      */
      
      
    public function process($text, $langcode) {
    // Creamos un documento DOM.
    $dom = Html::load($text);

    //Obtenemos todas las etiquetas UL, pero podemos obtener la que deseemos.
    $lists_query = '//ul'; 

    // Obtener los nodos DOM de la consulta XPath.
    $xpath = new \DOMXPath($dom);
    $nodes = $xpath->query($lists_query);
    
    // Si tenemos resultados.
    if ($nodes->length > 0) {
      //Iteramos sobre los elementos de la lista y agregar nuestra clase.
      foreach ($nodes as $node) {
        $classes = explode(' ', $node->getAttribute('class'));
        $classes[] = 'claseJhonatan';
        $node->setAttribute('class', join(' ', array_unique($classes)));
      }
    }
    
       $result = new FilterProcessResult(Html::serialize($dom));
        $result->setAttachments(array(
          'library' => array('filtrosckeditor/libreriafiltrosckeditor'),
        ));
    
        return $result;   
  }  
      

Al final mostrará el mismo resultado, pero de esta manera nos aseguramos, que si existe ya una clase implementada en una etiqueta, no se pierdan, sino que se adiciona. Sin embargo, de la manera anterior a esta, es mejor usarla cuando sabemos que una etiqueta no tiene una clase definida.

 

Archivo a descargar

Comparte este artículo