Este documento resume las principales novedades del universo JavaScript en Drupal 8. Introduce las nuevas APIs como Drupal.behaviors y Drupal.theme, y explica cómo añadir JavaScript a módulos y temas mediante librerías declaradas en ficheros YAML. También ofrece consejos sobre buenas prácticas de desarrollo como usar el modo estricto y crear plugins y bibliotecas propias.
4. Índice
01. D8 y JavaScript
02. El objeto JS global Drupal
03. Otras APIs del core
04. Añadir JS a nuestros módulos y temas
05. Buenas prácticas en desarrollo JS
06. Conclusiones
6. Drupal 8 y JavaScript
● En esta nueva versión, la importáncia de JS ha crecido y
mucho.
● Inclusión de librerías muy importantes y que cambian la forma
de trabajar con JS
– Ckeditor en el núcleo
– Backbone, underscore, ...
● Librerías ya existentes a nuevas versiones:
– jQuery 2.0.3, jQuery.UI 1.10.2, jQuery Once 1.2.3, ...
7. Estrictos con la calidad de código
“use strict” - http://ves.cat/kMMq
Nueva característica de ECMAScript 5 para pasar a ejecutar código
en modo estricto. Se debe añadir la cadena cómo primera línia
dentro en el contexto de la función.
JSHint – http://jshint.com
Herramienta de control de calidad del código JS que escribimos.
Integrado para revisar todo el código del núcleo. Ver .jshintrc y
.jshintignore
8. Ayuda a aplicaciones livianas
domReady
● Cada petición a Drupal, carga drupal.js, fichero dónde
carga toda la funcionalidad JS de Drupal.
● Este fichero sólo usaba jQuery para hacer:
$(window).ready(function() {...});
● Para hacer esto no hace falta cargar jQuery entero (90kb) y
podemos usar domReady (740 bytes).
domready(function () {...});
9. Backbone & Underscore
● La complejidad de las aplicaciones JS hace que se requiera un
framework MVC para poder arquitecturizarla
● Hoy en día existen múltiples que estan de moda: Backbone,
Angular.js o Ember.js
● La comunidad se ha decidido por Backbone porque es la que
tiene la mayor comunidad de usuarios y la más estable.
● Podeis ver ejemplos de uso en los módulos del core Edit,
Toolbar o Contextual
● Underscore se incluye porque es requisito de Backbone, però
también podemos aprovecharnos de ellos.
10. HTML5 y RWD
● Drupal 8 está desarrollado en HTML5 y es mobile friendly
● Para ello usa algunas librerías de apoyo, cómo son
Picturefill, classList o HTML5Shiv (*)
● Usa otras librerías interesantes cómo Modernizr que
podemos usar en nuestros desarrollos.
(*) HTML5Shiv va a desaparecer en breve porque el core no da
soporte a IE8 http://ves.cat/kOor
12. El objeto JS global Drupal
● La gente sigue sin conocer un objeto clave en el
desarrollo Drupal: Drupal
/core/misc/drupal.js
● A tener en cuenta:
– Drupal.behaviors
– Drupal.theme
– Drupal.t
– ...
13. Drupal.behaviors
● Es la forma de añadir comportamiento a una
página o a un elemento:
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
$('.select').addClass('foo');
}
};
● Nos aporta funciones de attach y detach. Se llama en
cada petición de la página (ajax)
● Si nos interesa que sólo se llame una vez: once().
14. Drupal.theme
● El theming también llegó al JS.
● Ha cambiado un poco en D8 (no usamos prototype)
● Todo HTML añadido a la página se debería hacer
mediante una función de theming
Drupal.theme.placeholder = function (str) {
return '<em class="placeholder">' +
Drupal.checkPlain(str) + '</em>';
};
// Calling a theme function.
Drupal.theme('placeholder', bar);
15. Drupal.t
● Drupal.t() funciona exactamente igual que el método
$this->t() (en D8 es un servicio y no una función
procedural)
Drupal.t(“Path: !uri”, {'!uri', uri});
● Las variables se pueden pasar con @, ! y %; con el mismo
significado que en PHP.
Drupal.checkPlain
17. Otras nuevas APIs (I)
Drupal.announce
Envia notificaciones al usuario para informar de cambios en la
página que no se pueden describir con estados ARIA.
Drupal.debounce
Limita la invocación de una función en un periodo de tiempo.
Drupal.tabbingManager
También ligado a la accesibilidad del sitio. Controla el orden y las
acciones a ejecutar en el tabbing de elementos.
18. Otras nuevas APIs (y II)
Drupal.displace
Calcula distancias de offset de viewport. Resuelve el problema de
posicionamiento entre Overlay y el Toolbar
Drupal.dialog
API que simula el elemento dialog de HTML5.
Drupal.history
Gestiona el historial de navegación
20. Añadir JS a nuestro módulo
● En Drupal 7 podíamos usar, entre otros:
drupal_add_js('js/mymodule.js');
scripts[] = 'js/mymodule.js';
● Esto en Drupal 8 no se puede usar.
● Ahora se nos obliga a definir todos nuestros ficheros JS cómo
librerías.
hook_library_info()
22. Añadir JS a nuestro módulo (III)
● En el módulo, lo añadiremos al render array de nuestro elemento:
$my_render['#attached']['library'][] =
'mymodule/foo';
● Si queremos añadirlo en todas las páginas, podremos usar
hook_page_build()
function edit_page_build(&$page) {
if(!Drupal::currentUser()->hasPermission('...')) {
return;
}
// some code
$page['#attached']['library'][] = 'edit/edit';
}
23. Añadir JS a nuestro tema
● Ahora todos los scripts tienen que declarar sus dependencias
en ficheros de librerías mytheme.libraries.yml
● Para añadirlos a nuestros temas:
…
core: 8.x
libraries:
- bartik/base
ckeditor_stylesheets:
- css/ckeditor-iframe.css
…
24. Pasar datos de PHP a JS
● Tampoco podemos usar drupal_add_js()
$form['#attached']['js'][] = array(
'type' => 'setting',
'data' => array('blockPlacement' =>
$placement),
);
● Para usar ese dato en nuestro JS:
Drupal.settings.blockPlacement
drupalSettings.blockPlacement
● drupalSettings es una variable global
intencionada.
26. Buenas prácticas en desarrollo JS (I)
● Usar siempre el modo estricto: “use strict”;
● JSHint está ahí para ayudarnos. Usémoslo!
● Usa Firebug o alguno de sus primos!
● Sobretodo, acordaos de declarar “todas” las variables! Es
buena práctica hacerlo siempre al inicio de la función
● Funciones anónimas para evitar problemas de scope de
variables y funciones.
● Perdamos el miedo a crear nuestras própias librerías o plugins.
27. Buenas práctica en desarrollo JS (y II)
● Hay que ir con cuidado con los selectores JS que
se escriben. Puede ser un foco de problemas de
performance http://ves.cat/kRFb
● Si nuestro JS toma cierta notoriedad, no tengamos
miedo de crear nuestro própio plugin jQuery,
nuestro componente en Backbone o nuestra
própia librería JS.
28. Desarrollo de plugins jQuery
● Si un componente jQuery asociado tiende a ser
reutilizable o tiene cierta notoriedad, escribamos un
plugin jQuery.
$.fn.myPlugin = function() {
// My code.
return this;
};
$(“input”).myPlugin();
● http://learn.jquery.com/plugins/
29. Desarrollo de bibliotecas JS
● Si nuestra lógica se vuelve extensa y compleja, sería bueno crear nuestra
própia biblioteca JS, encapsulando lo que nos interesa (¡podemos usar
Backbone que para eso está!).
var MyModule = {
init: function(options) {
// do my stuff.
},
_myprivatefunction(): function {
// other stuff.
}
};
MyModule.init(current_options);
30. Conclusiones
● Muchas novedades en D8 en materia de JS. Ahora es
tiempo de ponerlas en práctica!
● Muchas nuevas APIs que nos pueden ayudar
● Cuidado con las librerías JS que añadimos a nuestros
proyectos. A veces es mejor picar algo a mano que
empezar a añadir cosas descargadas de Internet.
● Debemos perder el miedo a hacer nuestras librerías y
plugins. Es buena práctica!