Bruke Backbone Innenfor WordPress Admin Front End

Velkommen til den andre delen av bruk av ryggrad Innenfor WordPress Admin. I første del setter vi opp "back-end" av plugin-modulen, og i den andre delen vil vi avslutte ved å legge til funksjonen "klientside" eller "frontend". For en oversikt over hva vi bygger i denne opplæringen sammen med mappestrukturen og -filene, vennligst gå gjennom den første delen.


1. Opprett malfilen

Innen src mappe, opprett en annen som heter maler og en fil i den som heter metabox.templ.php. Det er her vi skal sette HTML-koden for vår meta-boks. Det er også en flott mulighet til å sende ut de JSON-dataene som trengs for våre svar.

Dine mapper og filer skal nå se slik ut.

Opprett mal for et enkelt svar

La oss ta en titt på hva vi skaper. Du kan tenke på hvert svar som en Modell av data og fordi vi skal bruke klientsiden maler for å generere en utsikt for hver enkelt kan denne visningen reagere på endringer i modellen. Dette gjør at vi kan være svært spesifikke når bindende hendelser til brukergrensesnittet, og fører naturlig til en lettere arbeidsflyt - når du har fått hodet rundt det, det er.

Inne i vår nyopprettede metabox.templ.php, Dette er malen som vi skal bruke for hver av våre modeller. Du kan se at vi i utgangspunktet pakker inn noen HTML i en skriptetikett. Vi gir skriptet taggen attributtet type = "text / mal" slik at nettleseren ikke gjør det til siden. Denne lille biten av HTML skal brukes senere for å generere den nødvendige oppgraderingen for hver visning. Vi vil bruke Underscore's innebygde malmuligheter slik at verdier innpakket som dette vil bli erstattet av data i våre modeller senere.

    

Base HTML

Fortsatt innsiden av src / templates / metabox.templ.php - her legger vi bare ned beholderne som vil bli befolket med inngangene fra malen over. Dette skjer etter at Backbone har analysert JSON-dataene som trengs for modellen, så for øyeblikket er dette alt vi trenger å gjøre her.

  

Skriv inn svarene nedenfor

Korrekt svar:

Utfør JSON

Den endelige tingen trengte inne i src / templates / metabox.templ.php fil, er JSON-dataene som representerer hvert svar. Her skaper vi et objekt på det globale navneområdet og tilordner de verdiene vi sendte gjennom $ teledata array. Jeg liker også å lagre referanser til beholderne vi skal bruke senere, slik at jeg ikke har ID i to separate filer.

  

2. JavaScript

Ok, hvis du har kommet så langt, har du satt opp pluginet ditt for å tillate bruk av Backbone.js og meta-boksen din sender ut de nødvendige opplysningene og JSON-dataene. Nå er det på tide å bringe alt sammen og bruke Backbone.js til å organisere vår klientsidekode. Det er på tide å dekke:

  1. Opprette en samling av modeller fra JSON-dataene
  2. Bruke klientsiden maler for å lage en visning for hver
  3. Ser etter klikk, tast opp og slør hendelser innen hver visning
  4. Lagre en modell tilbake til databasen

Lag filen admin.js og legg det inn i js Mappe

Din endelige katalogstruktur og filer skal se slik ut.

Først av alt vil vi pakke alt vi gjør i en umiddelbart kalt funksjon og passere i jQuery for å bli brukt sammen med $ tegn, jeg vil ikke vise denne wrappen i noen flere utdrag, så sørg for at du legger alt under det.

 / * js / admin.js * / (funksjon ($) / ** Vår kode her ** / (jQuery));

Deretter trenger vi tilgang til våre data som er lagret på det globale navneområdet, og også opprette et nytt objekt som lagrer våre Backbone-objekter.

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

Modellen

Modellen representerer et enkelt svar. Innenfor konstruktøren gjør vi et par ting.

  1. Angir en standardverdi for korrekt som falsk
  2. Angi nettadressen som Backbone krever for å lagre modellen tilbake til databasen. Vi kan få tilgang til den riktige nettadressen takket være WordPress som viser at ajaxurl variabel som er tilgjengelig på hver admin side. Vi legger også til navnet på vår metode som håndterer ajax-forespørselen
  3. Neste overskriver vi toJSON Metode for å legge til gjeldende innleggs ID til hver modell. Dette kunne vært gjort på server side, men jeg har lagt det inn her som et eksempel på hvordan du kan overstyre det som er lagret på serveren (dette kan komme inn veldig hendig som er grunnen til at jeg har tatt med det her)
  4. Til slutt i initialiseringsmetoden, kontrollerer vi om gjeldende modell er det riktige svaret ved å sammenligne ID-en til ID-en for det riktige svaret. Vi gjør dette slik at vi senere vet hvilken svar som skal velges som standard
 / * js / admin.js * / Quiz.Model = Backbone.Model.extend (standard: 'correct': false, url: ajaxurl + '? action = save_answer', toJSON: funksjon () var attrs = _ .clone (this.attributes); attrs.post_id = wpq.post_id; return attrs;, initialiser: funksjon () hvis (this.get ('answer_id') === wpq.answers.correct) this.set ('riktig', sant););

Samlingen

En samling er egentlig bare en wrapper for en haug med modeller, og det gjør det å jobbe med disse modellene en bris. For vårt lille eksempel vil vi ikke endre samlingen, annet enn å spesifisere hvilken modell den skal bruke.

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

Inputs Wrapper

Vår første visning kan betraktes som en wrapper for de enkelte innfelt feltene. Vi trenger ikke å erklære en mal eller hvilket HTML-element vi ønsker Backbone å opprette for oss i dette tilfellet, fordi senere når vi overfører denne visningen, vil vi sende den IDen til en div som vi opprettet i meta-boksfilen. Ryggraden vil så enkelt bruke det elementet som sin beholder. Denne visningen tar en samling, og for hver modell i samlingen vil den opprette en ny inngang element og legg det til seg selv.

 / * js / admin.js * / Quiz.Views.Inputs = Backbone.View.extend (initialiser: funksjon () this.collection.each (this.addInput, this);, addInput: funksjon (modell, indeks ) var input = ny Quiz.Views.Input (modell: modell); dette. $ el.append (input.render (). el););

En enkel inngang

Denne neste visning representerer en enkelt modell. For å avdekke de typene ting du kan gjøre når du kodes JavaScript på denne måten, har jeg forsøkt å gi noen forskjellige interaksjonsteknikker og vise hvordan du reagerer på de med ryggraden.

Merk at vi spesifiserer en 'TagNavn'her sammen med en mal. I vårt tilfelle kommer dette til å hente den malen vi så på tidligere, analysere den ved å bruke data fra modellen, og deretter pakke alt i en p tag (som vil gi oss en fin bit av margin rundt hver og en).

Legg også merke til hvordan hendelser er bundet til elementer i en visning. Mye renere enn din gjennomsnittlige jQuery tilbakeringing og hva som er enda bedre er muligheten til å bruke en jQuery-velger som dette dette. $ ( 'inngang') innenfor våre synspunkter å vite at de automatisk scoped i visningen. Dette betyr at jQuery ikke ser på hele DOM når du prøver å matche en velger.

I denne visningen vil vi kunne:

  1. Vet når et inntastingsfelt har blitt endret
  2. Oppdater modellen som er tilknyttet den automatisk (som vil bli brukt til å automatisk oppdatere markeringsfeltet under det)
  3. Aktiver lagre-knappen på siden av inngangen som ble endret
  4. Utfør lagre tilbake til databasen
 / * js / admin.js * / Quiz.Views.Input = Ryggrad.View.extend (tagName: 'p', // Få malen fra DOM-malen: _. mal ($ (wpq.inputTempl) .html ()), // Når en modell er lagret, returner knappen til deaktivert tilstand initialiser: funksjon () var _this = dette; this.model.on ('sync', funksjonen () _this. $ ') .text (' Lagre ') .attr (' deaktivert ', sant);;; / / Fest hendelsesbegivenheter: ' keyup input ':' uskarphet ' Klikk på knappen ':' lagre ', // Utfør Lagre lagre: funksjonen (e) e.preventDefault (); $ (e.target) .text (' wait '); this.model.save (); , // Oppdater modellattributtene med data fra inntastingsfelt uskarphet: funksjon () var input = dette. $ ('Input') .val (); hvis (input! == this.model.get ('answer' )) this.model.set ('answer', input); dette. $ ('button'). attr ('deaktivert', false);, // Gjenta enkeltinngangen - inkludere en indeks. funksjon () this.model.set ('index', this.model.collection.indexOf (this.model) + 1); dette. $ el.html (this.template (this.model.toJSON ())); returnere dette; );

Velg elementet

Dette valgelementet er hvor brukeren kan velge riktig svar. Når denne visningen blir opprettet, vil den motta den samme samlingen av modeller som inngangens omslag gjorde. Dette vil komme til nytte senere fordi vi vil kunne lytte til endringer i modellen i inntastingsfeltene og automatisk oppdatere de tilsvarende verdiene i dette velgningselementet.

 / * js / admin.js * / Quiz.Views.Select = Backbone.View.extend (initialiser: funksjon () this.collection.each (this.addOption, this); addOption: funksjon (modell)  var alternativ = ny Quiz.Views.Option (modell: modell); dette. $ el.append (option.render (). el););

En enkelt valgvisning

Vår endelige visning vil skape et alternativelement for hver modell og vil bli vedlagt til valgelementet ovenfor. Denne gangen har jeg vist hvordan du dynamisk kan sette attributter på elementet ved å returnere en hash fra en tilbakeringingsfunksjon tilordnet egenskapene attributter. Legg også merke til at i initialize () Metode vi har "abonnert" for å endre hendelser på modellen (spesielt, svar Egenskap). Dette betyr egentlig bare: når som helst denne modellen er svar Attributtet er endret, ring render () metode (som i dette tilfellet vil bare oppdatere teksten). Dette begrepet "abonnere" eller "lytte" til hendelser som forekommer i en modell, er virkelig det som gjør Backbone.js og de mange andre bibliotekene som det så kraftige, nyttige og en glede å jobbe med.

 / * js / admin.js * / Quiz.Views.Option = Backbone.View.extend (tagName: 'alternativ', // retur en hash lar oss sette attributter dynamisk attributter: funksjon () return 'value' : this.model.get ('answer_id'), 'selected': this.model.get ('correct'), / / ​​Se etter endringer i hver modell (som skjer i inntastingsfeltene og gjenopprett når det er er en endring initialiser: funksjon () this.model.on ('change: answer', this.render, this); render: function () this. $ el.text (this.model.get (' svar ')); returner dette;);

Instantiate Collection og Views

Vi er så nær nå, alt vi trenger å gjøre er å ordne en ny samling og sende den den JSON den trenger, og sett deretter begge innpakningene for valgelementet og for inngangene. Legg merke til at vi også passerer el eiendom til våre synspunkter. Dette er referanser til div og velg element som vi forlot blank tidligere i meta-boksen.

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

3. Aktiver pluggen

Hvis du har gjort det til slutten, bør du nå ha et fullt fungerende eksempel på hvordan du skal inkorporere Backbone JS i et WordPress-plugin. Hvis du går videre og tar en titt på kildefilene, vil du legge merke til at den faktiske mengden kode som trengs for å inkorporere Ryggraden, er relativt liten. Mye av koden vi gikk her var PHP som trengs for plugin. Å jobbe med Backbone på daglig basis de siste 6 ukene har virkelig gitt meg en ny funnet respekt for front end-kode organisasjon og jeg håper at du kan sette pris på fordelene som sikkert kommer fra å jobbe på denne måten.

Innenfor WordPress-fellesskapet kan jeg forestille noen av de mer komplekse og høykvalitets plugins der ute, virkelig dra nytte av å bruke Backbone, og jeg er beæret over å ha kunnet dele med deg en teknikk for å gjøre akkurat det.