Utilizzo di Backbone All'interno dell'amministratore di WordPress Front End

Benvenuti nella seconda parte dell'utilizzo di Backbone all'interno dell'amministratore di WordPress. Nella prima parte, abbiamo impostato il "back-end" del nostro plug-in e ora nella seconda parte completeremo aggiungendo la nostra funzionalità "client-side" o "front-end". Per una panoramica di ciò che stiamo costruendo in questo tutorial insieme alla nostra struttura di cartelle e file, ti preghiamo di rivedere la prima parte.


1. Creare il file modello

All'interno del src cartella, creane un'altra chiamata Modelli e un file all'interno di quello chiamato metabox.templ.php. Qui è dove inseriremo l'HTML necessario per la nostra meta-box. È anche una grande opportunità per produrre i dati JSON necessari per le nostre risposte.

Ora le cartelle e i file dovrebbero assomigliare a questo.

Crea il modello per una singola risposta

Diamo un'altra occhiata a ciò che stiamo creando. Puoi pensare a ciascuna risposta come a Modello di dati e perché useremo i modelli lato client per generare un vista per ognuno, quella vista può reagire ai cambiamenti all'interno del modello. Questo ci permette di essere molto specifici quando leghiamo gli eventi all'interfaccia utente e naturalmente porta ad un flusso di lavoro più semplice - una volta che hai capito, questo è.

All'interno del nostro nuovo creato metabox.templ.php, questo è il modello che useremo per ciascuno dei nostri modelli. Puoi vedere che stiamo fondamentalmente avvolgendo un codice HTML in un tag script. Diamo il tag script all'attributo type = "text / template" in modo che il browser non lo renda alla pagina. Questa piccola parte di HTML deve essere utilizzata in seguito per generare il markup necessario per ciascuna vista. Utilizzeremo le funzionalità di template incorporate di Underscore in modo tale che i valori vengano avvolti in questo modo saranno sostituiti dai dati nei nostri modelli in seguito.

    

HTML di base

Ancora dentro src / templates / metabox.templ.php - qui stiamo solo posizionando i contenitori che verranno popolati con gli input del template sopra. Questo accade dopo che Backbone ha analizzato i dati JSON necessari per il modello, quindi per ora questo è tutto ciò che dobbiamo fare qui.

  

Inserisci le risposte qui sotto

Risposta corretta:

Emetti il ​​JSON

L'ultima cosa necessaria all'interno del src / templates / metabox.templ.php file, è il dato JSON che rappresenta ogni risposta. Qui stiamo creando un oggetto su Global Namespace e quindi assegnando i valori che abbiamo inviato con $ Viewdata array. Mi piace anche salvare i riferimenti ai contenitori che utilizzeremo in seguito, in modo da non avere ID in due file separati.

  

2. Il JavaScript

Ok, se sei arrivato a questo punto, hai configurato correttamente il tuo plug-in per consentire l'uso di Backbone.js e la tua meta-box sta emettendo i markup e i dati JSON richiesti. Ora è il momento di riunire tutto e utilizzare Backbone.js per organizzare il nostro codice lato client. È tempo di coprire:

  1. Creazione di una raccolta di modelli dai dati JSON
  2. Utilizzo di modelli lato client per costruire una vista per ciascuno
  3. Guardando per click, key up e sfocatura eventi all'interno di ogni vista
  4. Salvataggio di un modello nel database

Crea il file admin.js e posizionarlo nel js Cartella

La struttura e i file finali della directory dovrebbero assomigliare a questo.

Prima di tutto avvolgeremo tutto ciò che facciamo in una funzione immediatamente chiamata e passeremo in jQuery per essere usati con $ firmare, non mostrerò questo wrapper in altri frammenti, quindi assicurati di mettere tutto quanto al di sotto di esso.

 / * js / admin.js * / (function ($) / ** Il nostro codice qui ** / (jQuery));

Successivamente, dobbiamo accedere ai nostri dati memorizzati nel namespace globale e anche creare un nuovo oggetto che archivierà i nostri oggetti Backbone.

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

Il modello

Il modello rappresenta una singola risposta. All'interno del suo costruttore stiamo facendo un paio di cose.

  1. Impostazione di un valore predefinito per correggere come falso
  2. Impostazione dell'URL richiesto da Backbone per salvare il modello nel database. Possiamo accedere all'URL corretto grazie a WordPress comprovante ajaxurl variabile che è disponibile su ogni pagina di amministrazione. Aggiungiamo anche il nome del nostro metodo che gestisce la richiesta Ajax
  3. Quindi stiamo sovrascrivendo il toJSON metodo per aggiungere l'ID del post corrente a ciascun modello. Questo potrebbe essere stato eseguito sul lato server, ma l'ho inserito qui come esempio di come puoi ignorare ciò che viene salvato sul server (questo può succedere molto a portata di mano, ecco perché l'ho incluso qui)
  4. Infine, nel metodo di inizializzazione, stiamo controllando se il modello corrente è la risposta corretta confrontando il suo ID con l'ID della risposta corretta. Lo facciamo in modo che in seguito sappiamo quale risposta deve essere selezionata per impostazione predefinita
 / * 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 ('corretto', vero););

La collezione

Una collezione è essenzialmente solo un involucro per un sacco di modelli e rende il lavoro con questi modelli un gioco da ragazzi. Per il nostro piccolo esempio, non modificheremo la raccolta, se non specificando quale modello dovrebbe utilizzare.

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

Input Wrapper

La nostra prima vista può essere considerata un wrapper per i singoli campi di input. Non abbiamo bisogno di dichiarare un modello o quale elemento HTML vogliamo che Backbone crei per noi in questo caso, perché in seguito quando istanzeremo questa vista, passeremo l'ID di un div che abbiamo creato nel file meta box. Backbone utilizzerà semplicemente quell'elemento come contenitore. Questa vista prenderà una raccolta e per ciascun modello in quella raccolta creerà una nuova ingresso elemento e aggiungerlo a se stesso.

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

Un singolo ingresso

Questa prossima vista rappresenta un singolo modello. Nell'interesse di mostrare i tipi di cose che puoi fare quando codi JavaScript in questo modo, ho provato a fornire alcune diverse tecniche di interazione e mostrare come reagire a quelli con Backbone.

Si noti che stiamo specificando un 'tagName'qui insieme a un modello. Nel nostro caso, questo andrà ad afferrare quel modello che abbiamo visto prima, analizzarlo usando i dati del modello e poi avvolgere tutto in un p tag (che ci darà un bel margine di margine attorno a ciascuno).

Nota anche come gli eventi sono legati agli elementi all'interno di una vista. Molto più pulito del tuo callback jQuery medio e ciò che è ancora meglio è la possibilità di usare un selettore jQuery come questo questo. $ ( 'input') all'interno dei nostri punti di vista sapendo che sono automaticamente inclusi nella vista. Ciò significa che jQuery non sta guardando l'intero DOM quando prova ad abbinare un selettore.

In questa vista, saremo in grado di:

  1. Sapere quando un campo di input è stato modificato
  2. Aggiorna il modello associato automaticamente (che verrà utilizzato per aggiornare automaticamente il campo di selezione sottostante)
  3. Abilita il pulsante di salvataggio sul lato dell'input che è stato modificato
  4. Eseguire il salvataggio sul database
 / * js / admin.js * / Quiz.Views.Input = Backbone.View.extend (tagName: 'p', // Ottieni il modello dal modello DOM: _. template ($ (wpq.inputTempl) .html ()), // Quando un modello viene salvato, riporta il pulsante allo stato disabilitato initialize: function () var _this = this; this.model.on ('sync', function () _this. $ ('Button ') .text (' Salva ') .attr (' disabled ', true););, // Allega eventi eventi: ' input keyup ':' blur ',' blur input ':' blur ',' click button ':' save ', // Esegui Save save: function (e) e.preventDefault (); $ (e.target) .text (' wait '); this.model.save (); , // Aggiorna gli attributi del modello con i dati del campo di input blur: function () var input = this. $ ('Input'). Val (); if (input! == this.model.get ('answer' )) this.model.set ('answer', input); this. $ ('button'). attr ('disabled', false);, // Render il singolo input - include un indice. function () this.model.set ('index', this.model.collection.indexOf (this.model) + 1); this. $ el.html (this.template (this.model.toJSON ())); restituiscilo; );

L'elemento Seleziona

Questo elemento di selezione è dove l'utente può scegliere la risposta corretta. Quando questa vista viene istanziata, riceverà la stessa collezione di modelli che ha fatto il wrapper dell'input. Questo sarà utile in seguito, poiché saremo in grado di ascoltare le modifiche al modello nei campi di input e aggiornare automaticamente i valori corrispondenti all'interno di questo elemento select.

 / * 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); this. $ el.append (option.render (). el););

Una singola vista opzione

La nostra vista finale creerà un elemento opzione per ogni modello e verrà aggiunto all'elemento selezionato sopra. Questa volta ho mostrato come è possibile impostare dinamicamente gli attributi sull'elemento restituendo un hash da una funzione di callback assegnata alla proprietà attributes. Si noti inoltre che nel inizializzare() metodo che abbiamo 'sottoscritto' per modificare gli eventi sul modello (in particolare, il risposta attributo). Questo in pratica significa solo: ogni volta che questo modello è risposta l'attributo è cambiato, chiama il render () metodo (che in questo caso aggiornerà solo il testo). Questo concetto di "sottoscrizione" o "ascolto" di eventi che si verificano all'interno di un modello è in realtà ciò che rende Backbone.js e molte altre librerie come così potente, utile e una gioia per lavorare con.

 / * js / admin.js * / Quiz.Views.Option = Backbone.View.extend (tagName: 'option', // restituire un hash ci consente di impostare attributi dinamicamente attributi: function () return 'value' : this.model.get ('answer_id'), 'selected': this.model.get ('correct'), // Controlla le modifiche a ciascun modello (che si verificano nei campi di input e ri-rendering quando ci sono è una modifica initialize: function () this.model.on ('change: answer', this.render, this);, render: function () this. $ el.text (this.model.get (' rispondi ')); restituisci questo;);

Crea un'istanza raccolta e viste

Siamo così vicini ora, tutto ciò che dobbiamo fare è istanziare una nuova raccolta e passarla al JSON di cui ha bisogno, quindi istanziare entrambe le viste 'wrapper' per l'elemento select e per gli input. Nota che passiamo anche il EL proprietà ai nostri punti di vista. Questi sono riferimenti all'elemento div e select che abbiamo lasciato in bianco prima nella meta-box.

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

3. Attiva il plugin

Se sei arrivato alla fine, dovresti ora avere un esempio pienamente funzionante su come incorporare Backbone JS in un plugin per WordPress. Se vai avanti e dai un'occhiata ai file sorgente, noterai che la quantità effettiva di codice necessaria per incorporare Backbone è relativamente piccola. Gran parte del codice che abbiamo passato qui era il PHP necessario per il plugin. Lavorare quotidianamente con Backbone per le ultime 6 settimane mi ha dato un nuovo rispetto per l'organizzazione del front end e spero che tu possa apprezzare i benefici che sicuramente verranno dal lavorare in questo modo.

All'interno della comunità di WordPress posso immaginare alcuni dei plugin più complessi e di alta qualità che possono beneficiare dell'utilizzo di Backbone e sono onorato di aver potuto condividere con voi una tecnica per fare esattamente questo.