Usando Backbone dentro del administrador de WordPress El extremo delantero

Bienvenido a la segunda parte de Uso de Backbone dentro del administrador de WordPress. En la primera parte, configuramos el 'back-end' de nuestro complemento y ahora en la segunda parte terminaremos agregando nuestra funcionalidad 'del lado del cliente' o 'front-end'. Para obtener una descripción general de lo que estamos construyendo en este tutorial junto con nuestra estructura de carpetas y archivos, revise la primera parte.


1. Crea el archivo de plantilla

Dentro de src carpeta, crea otra llamada Plantillas y un archivo dentro de ese llamado metabox.templ.php. Aquí es donde colocaremos el HTML necesario para nuestra meta box. También es una gran oportunidad para generar los datos JSON necesarios para nuestras respuestas.

Tus carpetas y archivos ahora deberían verse así.

Crear la plantilla para una sola respuesta

Echemos otro vistazo a lo que estamos creando. Puedes pensar en cada Respuesta como una Modelo de datos y porque usaremos plantillas del lado del cliente para generar una ver para cada uno, esa vista puede reaccionar a los cambios dentro del modelo. Esto nos permite ser muy específicos al vincular eventos con la interfaz de usuario y, naturalmente, nos lleva a un flujo de trabajo más sencillo..

Dentro de nuestro recién creado metabox.templ.php, Esta es la plantilla que usaremos para cada uno de nuestros modelos. Puedes ver que básicamente estamos envolviendo algo de HTML en una etiqueta de script. Le damos a la etiqueta del script el atributo type = "texto / plantilla" para que el navegador no lo muestre a la página. Esta pequeña porción de HTML se usará más adelante para generar el marcado necesario para cada vista. Utilizaremos las capacidades de la plantilla incorporada de Underscore para que los valores se envuelvan así. Será reemplazado por los datos en nuestros modelos más adelante..

    

Base HTML

Todavía dentro de src / templates / metabox.templ.php - Aquí solo estamos colocando los contenedores que se rellenarán con las entradas de la plantilla anterior. Esto sucede después de que Backbone haya analizado los datos JSON necesarios para el modelo, así que por ahora esto es todo lo que necesitamos hacer aquí..

  

Introduzca las respuestas a continuación

Respuesta correcta:

Salida el JSON

Lo último necesario dentro de la src / templates / metabox.templ.php archivo, son los datos JSON que representan cada respuesta. Aquí estamos creando un objeto en el espacio de nombres global y luego asignando los valores que enviamos con el $ viewData formación. También me gusta guardar referencias a los contenedores que usaremos más adelante para que no tenga ID en dos archivos separados.

  

2. El JavaScript

De acuerdo, si ha llegado tan lejos, ha configurado con éxito su complemento para permitir el uso de Backbone.js y su meta box está generando el marcado requerido y los datos JSON. Ahora es el momento de reunirlo todo y usar Backbone.js para organizar nuestro código del lado del cliente. Es hora de cubrir:

  1. Creando una colección de modelos a partir de los datos JSON
  2. Usando plantillas del lado del cliente para construir una vista para cada
  3. Viendo los eventos de clic, clave y desenfoque dentro de cada vista
  4. Guardando un modelo en la base de datos

Crear el archivo admin.js y colocarlo en el js Carpeta

La estructura y los archivos finales de su directorio deberían verse así..

En primer lugar, envolveremos todo lo que hacemos en una función llamada de inmediato y pasaremos jQuery para que se use con el PS señal, no mostraré este envoltorio en más fragmentos, así que asegúrese de poner todo lo que se encuentra debajo.

 / * js / admin.js * / (function ($) / ** Nuestro código aquí ** / (jQuery));

A continuación, debemos acceder a nuestros datos almacenados en el espacio de nombres global y también crear un nuevo objeto que almacenará nuestros objetos Backbone.

 / * js / admin.js * / var Quiz = Views: ; var wpq = window.wpQuiz;

El modelo

El modelo representa una sola respuesta. Dentro de su constructor estamos haciendo un par de cosas..

  1. Establecer un valor predeterminado para corregir como falso
  2. Configuración de la URL que Backbone requiere para guardar el modelo en la base de datos. Podemos acceder a la URL correcta gracias a WordPress demostrando la ajaxurl Variable que está disponible en cada página de administración. También adjuntamos el nombre de nuestro método que maneja la solicitud ajax
  3. A continuación estamos sobreescribiendo el aJSON Método para anexar el ID de la publicación actual a cada modelo. Esto podría haberse hecho en el lado del servidor, pero lo he puesto aquí como un ejemplo de cómo se puede anular lo que se guarda en el servidor (Esto puede venir en muy práctico por eso lo he incluido aquí)
  4. Finalmente, en el método de inicialización, estamos comprobando si el modelo actual es la respuesta correcta comparando su ID con la ID de la respuesta correcta. Hacemos esto para que luego sepamos qué respuesta debería seleccionarse por defecto.
 / * js / admin.js * / Quiz.Model = Backbone.Model.extend (defaults: 'correct': false, url: ajaxurl + '? action = save_answer', toJSON: function () var attrs = _ .clone (this.attributes); attrs.post_id = wpq.post_id; return attrs;, initialize: function () if (this.get ('answer_id') === wpq.answers.correct) this.set ('correcto', verdadero););

La colección

Una colección es esencialmente una envoltura para un montón de modelos y hace que trabajar con esos modelos sea muy fácil. Para nuestro pequeño ejemplo, no modificaremos la colección, aparte de especificar qué modelo debería usar.

 / * js / admin.js * / Quiz.Collection = Backbone.Collection.extend (model: Quiz.Model);

La envoltura de entradas

Nuestra primera vista se puede considerar una envoltura para los campos de entrada individuales. No necesitamos declarar una plantilla o qué elemento HTML queremos que Backbone cree para nosotros en este caso, porque más adelante, cuando ejemplifiquemos esta vista, le pasaremos el ID de una div que creamos en el archivo meta box. Backbone simplemente usará ese elemento como su contenedor. Esta vista tomará una colección y para cada modelo en esa colección, creará una nueva entrada Elemento y anexarlo a sí mismo..

 / * js / admin.js * / Quiz.Views.Inputs = Backbone.View.extend (initialize: function () this.collection.each (this.addInput, this);, addInput: function (modelo, índice ) var input = new Quiz.Views.Input (model: model); este. $ el.append (input.render (). el););

Una sola entrada

La siguiente vista representa un modelo único. Con el fin de mostrar los tipos de cosas que puede hacer al codificar JavaScript de esta manera, he intentado proporcionar algunas técnicas de interacción diferentes y mostrar cómo reaccionar ante las personas con Backbone.

Tenga en cuenta que estamos especificando un 'nombre de etiqueta'aquí junto con una plantilla. En nuestro caso, esto tomará la plantilla que vimos anteriormente, la analizaremos utilizando los datos del modelo y luego envolveremos todo en una pag etiqueta (que nos dará un poco de margen alrededor de cada uno).

También tenga en cuenta cómo los eventos están vinculados a elementos dentro de una vista. Mucho más limpio que el promedio de la devolución de llamada jQuery y, lo que es aún mejor, es la posibilidad de utilizar un selector jQuery como este. esto. $ ('entrada') dentro de nuestras vistas, sabiendo que están automáticamente dentro del alcance de la vista. Esto significa que jQuery no está mirando todo el DOM al intentar hacer coincidir un selector.

En esta vista, podremos:

  1. Saber cuando un campo de entrada ha sido cambiado
  2. Actualice el modelo asociado automáticamente (que se utilizará para actualizar automáticamente el campo de selección debajo de él)
  3. Habilite el botón Guardar en el lado de la entrada que se cambió
  4. Realiza el guardado en la base de datos.
 / * js / admin.js * / Quiz.Views.Input = Backbone.View.extend (tagName: 'p', // Obtenga la plantilla de la plantilla DOM: _. template ($ (wpq.inputTempl) .html ()), // Cuando se guarda un modelo, regrese el botón al estado deshabilitado. Initialize: function () var _this = this; this.model.on ('sync', function () _this. $ ('Button ') .text (' Save ') .attr (' disabled ', true););, // Adjuntar eventos eventos: ' keyup input ':' blur ',' blur input ':' blur ',' haga clic en el botón ':' guardar ', // Realice la función Guardar guardar: (e) e.preventDefault (); $ (e.target) .text (' wait '); this.model.save (); , // Actualice los atributos del modelo con los datos del campo de entrada blur: function () var input = this. $ ('Input'). Val (); if (input! == this.model.get ('answer' )) this.model.set ('answer', input); this. $ ('button'). attr ('disabled', false);, // Render the single input - incluye un índice. function () this.model.set ('index', this.model.collection.indexOf (this.model) + 1); this. $ el.html (this.template (this.model.toJSON ())); devuelve esto );

El elemento selecto

Este elemento de selección es donde el usuario puede elegir la respuesta correcta. Cuando esta vista se ejemplifique, recibirá la misma colección de modelos que la envoltura de la entrada. Esto será útil más adelante porque podremos escuchar los cambios en el modelo en los campos de entrada y actualizar automáticamente los valores correspondientes dentro de este elemento de selección..

 / * js / admin.js * / Quiz.Views.Select = Backbone.View.extend (initialize: function () this.collection.each (this.addOption, this);, addOption: function (model)  var option = new Quiz.Views.Option (model: model); este. $ el.append (option.render (). el););

Una vista de una sola opción

Nuestra vista final creará un elemento de opción para cada modelo y se agregará al elemento de selección anterior. Esta vez he mostrado cómo puede establecer dinámicamente los atributos en el elemento devolviendo un hash desde una función de devolución de llamada asignada a la propiedad de atributos. También tenga en cuenta que en el inicializar() método que hemos 'suscrito' para cambiar los eventos en el modelo (específicamente, el responder atributo). Esto básicamente significa: en cualquier momento este modelo es responder atributo cambiado, llame al hacer() Método (que en este caso, solo actualizará el texto). Este concepto de "suscripción" o "escucha" de eventos que ocurren dentro de un modelo es realmente lo que hace que Backbone.js y las muchas otras bibliotecas lo consideren tan poderoso, útil y una alegría trabajar con él..

 / * js / admin.js * / Quiz.Views.Option = Backbone.View.extend (tagName: 'option', // devolver un hash nos permite establecer atributos de forma dinámica atributos: function () return 'value' : this.model.get ('answer_id'), 'selected': this.model.get ('correcto'), // Esté atento a los cambios en cada modelo (que suceden en los campos de entrada y vuelva a renderizar cuando haya es un cambio initialize: function () this.model.on ('change: answer', this.render, this);, render: function () this. $ el.text (this.model.get (' contesta ')); devuelve esto;);

Colección y vistas de instancias

Ahora estamos tan cerca, todo lo que tenemos que hacer es crear una instancia de una nueva colección y pasarle el JSON que necesita, y luego crear una instancia de las dos vistas de "contenedor" para el elemento seleccionado y para las entradas. Tenga en cuenta que también pasamos el el Propiedad a nuestros puntos de vista. Estas son referencias al elemento div y select que dejamos en blanco anteriormente en el cuadro meta.

 / * js / admin.js * / var answers = nuevo Quiz.Collection (wpq.answers); var selectElem = new Quiz.Views.Select (collection: answers, el: wpq.answerSelect); var inputs = new Quiz.Views.Inputs (collection: answers, el: wpq.answerInput);

3. Activar el Plugin

Si ha llegado al final, ahora debería tener un ejemplo completo de cómo incorporar Backbone JS en un complemento de WordPress. Si sigue adelante y observa los archivos de origen, notará que la cantidad real de código necesaria para incorporar Backbone es relativamente pequeña. Gran parte del código que vimos aquí fue el PHP necesario para el complemento. Trabajar con Backbone a diario durante las últimas 6 semanas realmente me ha dado un nuevo respeto por la organización del código frontal y espero que pueda apreciar los beneficios que seguramente se obtendrán al trabajar de esta manera..

Dentro de la comunidad de WordPress puedo imaginar algunos de los complementos más complejos y de alta calidad que realmente se benefician del uso de Backbone y me siento honrado de haber podido compartir con ustedes una técnica para hacer exactamente eso..