La semana pasada, durante la fase de test de un proyecto que estamos desarrollando, un cliente nos dijo que estaba teniendo problemas para introducir contenidos porque estaba fallando el editor WYSIWYG que estábamos usando, el CKEDITOR integrado en Symfony. Como siempre, los desarrolladores dijimos que «a nosotros nos funcionaba«, y es que era cierto… hasta que dejó de serlo. De forma aparentemente aleatoria, a veces se permitía la introducción de contenidos con normalidad y otras el proceso no se llegaba a realizar por completo: desaparecía el TEXTAREA asociado pero el editor no llegaba a aparecer en su lugar.

El ordenador del desarrollador como centro del universo

En este punto hay que decir que nuestras necesidades iban un poco más allá de las de por defecto, ya que teníamos que limitar la cantidad de encabezados que podía introducir el usuario y al código HTML al que equivalían unas vez renderizados. Además, en la carga inicial de Symfony no conseguíamos que apareciese la configuración deseada (botones de la barra de herramientas y skin), así que terminamos llegando a este código:


var WYSIWYG = {
	init : function() {
		CKEDITOR.config.format_tags = 'p;h1;h2;h3';
		CKEDITOR.config.format_h1 = { element: 'h3' };
		CKEDITOR.config.format_h2 = { element: 'h4' };
		CKEDITOR.config.format_h3 = { element: 'h5' };
		editors = CKEDITOR.instances;
		if (editors) {
			for (var editor in editors) {
				config = editors[editor].config;
				editors[editor].destroy(true);
				if ($('#' + editor).length > 0) {
					CKEDITOR.inline(editor, config);
				}
			}
		}
	}
};

En donde lo que hacíamos era:

Este método, según vimos en las sagradas escrituras de Stackoverflow, es muy común cuando se quiere modificar de forma dinámica la configuración del CKEDITOR. Provocaba un efecto de parpadeo algo extraño, ya que primero se invocaba desde el Symfony, y una vez creado se volvía a hacer lo mismo desde el JavaScript, por lo que había unos breves instantes en que el el TEXTAREA se quedaba sin CKEDITOR asociado, pero nos pareció una consecuencia aceptable si lográbamos hacerlo funcionar como queríamos.

Pero entonces ocurrió que esos breves instantes se convirtieron en eternidades, y por más que esperásemos, había veces en que esa segunda creación del CKEDITOR nunca llegaba, y resultaba imposible por tanto introducir contenidos en ese campo. Intuíamos que, al carecer de patrón de aparición aparente, se debía a desajustes en los procesos de carga del JavaScript de Symfony y el nuestro, así que nos pusimos a indagar hasta que finalmente dimos con la solución:

Al añadir el campo en el formulario de Symfony, hacerlo añadiendo un auto_inline a false:


->add('text', CKEditorType::class,
    array(
        'required' => false,
        'auto_inline' => false,
        'inline' => true,
    )
)

Y en el config.yml, cargar la configuración que antes metíamos por JavaScript


page_manual:
            entities: false
            allowedContent: true
            format_tags: "p;h1;h2;h3"
            format_h1: { element: 'h3' }
            format_h2: { element: 'h4' }
            format_h3: { element: 'h5' }
            toolbar: [ ['WidgetTemplateMenu', 'BootstrapTabs'],['Bold', 'Italic', 'Underline', 'Strike'],['Format'],['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],['NumberedList', 'BulletedList'],['Link', 'Unlink', 'Anchor'],['Image', 'PageBreak'],['PasteText', 'PasteFromWord', '-', 'Undo', 'Redo'],['Find', 'Replace', '-', 'SelectAll'],['ShowBlocks'] ]
            uiColor: "#ffffff"

El resultado es que ahora la configuración correcta se carga inicialmente desde el componente de Symfony, y el JavaScript se utiliza… para nada, ya no nos hace falta: un código más simple, eficaz y fiable.

Esperamos que esta solución le pueda servir a alguien y le ahorre un rato del camino que tuvimos que recorrer hasta llegar a esta concusión 🙂