Använda backbone Inom WordPress Admin Back End

Rykten är sanna! WordPress Admin Panel använder nu Underscore och Backbone! Det innebär att vi med minimal ansträngning kan börja använda dessa fantastiska JavaScript-bibliotek i våra egna plugins. Denna handledning visar dig exakt hur du kan göra det. Vi skapar Admin-delen av ett Quiz-plugin. Vi använder en enkel anpassad posttyp för att spara frågor, och inom varje fråga lägger vi till en metabox som tillåter oss att skriva in upp till 4 svar och välj vilken som är den rätta. Vi ska gå igenom hur man använder mallar, hur man knyter till klick och nyckelföretag, hur man sparar data tillbaka till WordPress-databasen och viktigast av allt, hur man "får din sanning ur dom" som skaparen Jeremy Ashkenas gillar att uttrycka det.

Jag kommer att säga framåt att det plugin vi bygger i den här handledningen kan tyckas alltför stor för vad den åstadkommer. Det kommer dock att ge dig en utmärkt titt på världen med att använda Backbone och om du kommer att komma över ett projekt i framtiden som kräver ett komplext användargränssnitt med mycket JavaScript, kommer du att vara väl beväpnad och redo att ta fram en välbehövlig organisation för att festen.


Vad vi ska göra

I den här första delen ska vi ställa in baksidan av vårt plugin. Det innebär att du konfigurerar filerna och mapparna samt genomför alla funktioner som vårt plugin kräver i PHP. Vi måste:

  1. Registrera en anpassad posttyp - för våra frågor
  2. Lägg till en metabox som tillåter oss att skriva in svar på samma sida
  3. Spara information från metakassorna när posten sparas
  4. Spara information från våra ajaxförfrågningar (via Backbone)

Sedan i den andra delen ...

När vi har startat vår bakre ände, fortsätter vi sedan med att mata ut den nödvändiga HTML-filen för vår metakassa tillsammans med data för varje svar i JSON-format. Vi skriver också JavaScript som binder allt tillsammans. Vi täcker:

  1. Utmatning av bashtml för meta-rutan
  2. Utmatning av en klientsidemall tillsammans med svaren i JSON
  3. JavaScript behövde binda allt ihop

Jag hoppas att den här lilla serien låter intressant för dig och jag ser fram emot att hjälpa dig att komma igång med att använda Backbone.js inom ett WordPress-plugin.


Vad vi ska bygga

Det här pluginet använder en anpassad posttyp för att spara frågor. Sedan skapar vi fyra ingångar i en metabox som tillåter användare att ange möjliga svar på den aktuella frågan och välj vilken av dem som är det rätta svaret. När ett svar ändras, blir motsvarande sparningsknapp aktiv. När vi klickar använder vi Ryggradets inbyggda model.save () metod för att spara data tillbaka till WordPress-databasen. När svaren skrivs i ingångarna uppdateras även rutan under den automatiskt automatiskt, eftersom det kommer att se ut för ändringar av modellerna. Alla dessa saker är relativt triviala att göra med Backbone och efter att ha läst denna handledning kan du börja ta dina plugins till nästa nivå genom att använda dem inom WordPress.

Det finns mycket att täcka, så låt oss börja!


1. Skapa plugin

Vi måste göra alla vanliga första steg som involveras i något plugin - skapa filmapparna.

  1. Skapa en mapp som heter wp_quiz
  2. Skapa en PHP-fil inuti med samma namn
  3. Skapa en mapp som heter js
  4. Skapa en mapp som heter src

Din mappstruktur ska se ut så här.


2. Lägg till pluginhuvudet

Insidan av wp_quiz.php.

 / * Plugin Name: WP Quiz Plugin URI: http://wp.tutsplus.com/author/shaneosbourne/ Beskrivning: Ett exempel på att använda Backbone i ett plugin. Författare: Shane Osbourne Version: 0.1 Författare URI: http://wp.tutsplus.com/author/shaneosbourne/ * /

3. Lägg till krokar för att aktivera pluginprogrammet

Fortfarande inuti wp_quiz.php, vi behöver göra följande saker:

  1. Inkludera vår huvudsakliga plugin-klass
  2. Skapa en funktion som skapar en förekomst av klassen
  3. Lägg till en krok för att bara ringa funktionen när användaren är en administratör
 / ** wp_quiz.php ** / include 'src / WpQuiz.php'; // Class File // Skapa en instans av Plugin Class-funktionen call_wp_quiz () returnera nya WpQuiz ("admin");  // Endast när den nuvarande användaren är en Admin om (is_admin) add_action ('init', 'call_wp_quiz'); // Helperfunktion om (! Function_exists ('pp')) funktion pp () return plugin_dir_url (__FILE__); 

Att sätta hjälparfunktionen pp () inom den här filen tillåter vi att hänvisa till andra filer i förhållande till roten i plugin-mappen (det kommer du snart att se).


4. Skapa plugin-klassen

Inne i src mapp, skapa en fil som heter WpQuiz.php.

I denna plugin-klass kommer vi att behöva några olika metoder för att uppnå alla följande:

  1. Registrera den anpassade posttypen
  2. Lägg till en metabox
  3. Hämta innehållet för metakassen och mata både HTML och vissa JSON-data till den
  4. Lyssna på PUT-förfrågningar och spara data i databasen
  5. Spara våra metaboxdata vid vanliga "spara" -åtgärder

Innan vi skriver metoderna kommer vi att lagra viss information som klassegenskaper. Vi lagrar den här informationen högst upp i vår klassfil så att ändringar är enklare att göra senare. De answerIds array innehåller de nycklar som vi ska använda hela det här pluginet för att spara data med hjälp av den inbyggda add_post_meta ().

Lägg till egenskaperna

 / ** src / WpQuiz.php ** / class WpQuiz // Namn på anpassad posttyp public $ postTypeNameSingle = 'Question'; public $ postTypeNamePlural = 'Questions'; // Meta Box Stuff public $ metaBoxTitle = 'Svar'; offentliga $ metaBoxTempl = 'mallar / metabox.templ.php'; // Fråga Id: s offentliga $ answerIds = array ("quiz-a-1", "quiz-a-2", "quiz-a-3", "quiz-a-4"); // Javascript public $ jsAdmin = '/js/admin.js'; 

Lägg till byggaren

  1. Först registrerar vi den anpassade posttypen med hjälp av en annan hjälparmetod (som kommer att ses senare)
  2. Då registrerar vi en krok för att ladda vår meta box
  3. Vi behöver också en separat metod för att acceptera våra ajaxförfrågningar
  4. Slutligen, när en sida laddas, vill vi spara information från vår metabox
 / ** src / WpQuiz.php ** / allmän funktion __construct ($ typ) switch ($ typ) fall 'admin': // Registrera posttyp $ this-> registerPostType ($ this-> postTypeNameSingle, $ this -> postTypeNamePlural); // Lägg till Meta Box add_action ('add_meta_boxes', array ($ this, 'addMetaBox')); // Acceptera en Ajax-förfrågan add_action ('wp_ajax_save_answer', array ($ this, 'saveAnswers')); // Se till att posten sparas add_action ('save_post', array ($ this, 'savePost')); 

Lägg till Meta Box

  1. Lägg till de JavaScript-filer som behövs för det här plugin-igen med hjälp av en hjälparmetod (ses senare)
  2. Skapa ett unikt ID för det här pluginet baserat på namnet på posttypen
  3. Lägg till metaboxen med de egenskaper vi ställde in tidigare
 / ** src / WpQuiz.php ** / public function addMetaBox () // Ladda Javascript krävs på denna admin sida. $ This-> addScripts (); // Skapa ett id baserat på posttypsnamn $ id = $ this-> postTypeNameSingle. '_Metabox'; // Lägg till metaboxen add_meta_box ($ id, $ this-> metaBoxTitle, array ($ this, 'getMetaBox'), // Få markeringen behövs $ this-> postTypeNameSingle); 

Hämta Meta Box-innehållet

Här slingar vi igenom våra svar-ID och konstruerar en array som innehåller postmeta hämtade med vår hjälparmetod getOneAnswer. Vi gör denna nya array så att vi kan koda den och skicka den till vår mall i JSON-format - precis som Backbone tycker om det. Vi skicka data till vår mall med hjälp av $ viewdata array ses nedan. Detta håller hela HTML-filen bort och skadar oss och gör det möjligt för oss att arbeta med det i en separat fil. Vi tar en snabb titt på getTemplatePart metod senare, men om du vill ha en fördjupad förklaring om varför jag använder den, kolla in Förbättra ditt arbetsflöde - Separera din uppmärksamhet från din logik!

 / ** src / WpQuiz.php ** / allmän funktion getMetaBox ($ post) // Hämta de aktuella värdena för frågorna $ json = array (); foreach ($ this-> answerIds as $ id) $ json [] = $ this-> getOneAnswer ($ post-> ID, $ id);  // Ange data som behövs i mallen $ viewData = array ('post' => $ post, 'answers' => json_encode ($ json), 'korrekt' => json_encode (get_post_meta ($ post-> ID, 'correct_answer '))); echo $ this-> getTemplatePart ($ this-> metaBoxTempl, $ viewData); 

Få ett enkelt svar - hjälpen

Vi returnerar bara en rad data som behövs i vår mall. Du kan tänka på detta som att skapa en enda modell som behövs på framsidan.

 / ** src / WpQuiz.php ** / allmän funktion getOneAnswer ($ post_id, $ answer_id) return array ('answer_id' => $ answer_id, 'answer' => get_post_meta ($ post_id, $ answer_id, true)); 

Spara inlägget

När en användare klickar på att spara ett inlägg som vår meta-box är för närvarande måste vi göra ett par kontroller för att säkerställa att vi sparar vår anpassade posttyp och att den nuvarande användaren har rätt behörigheter - om båda kontrollerna är okej så vi spara de fyra svaren från metaboxen och det korrekta svaret.

 / ** src / WpQuiz.php ** / public function savePost ($ post_id) // Kontrollera att vi sparar vår anpassade posttyp om ($ _POST ['post_type']! == strtolower ($ this-> postTypeNameSingle) )  lämna tillbaka;  // Kontrollera att användaren har rätt behörigheter om (! $ This-> canSaveData ($ post_id)) return;  // Hämta data från $ _POST global och skapa en ny array som innehåller // den info som behövs för att göra spara $ fields = array (); foreach ($ this-> answerIds as $ id) $ fält [$ id] = $ _POST [$ id];  // Gå igenom den nya matrisen och spara / uppdatera var och en för ($ fält som $ id => $ fält) add_post_meta ($ post_id, $ id, $ field, true); // eller update_post_meta ($ post_id, $ id, $ fält);  // Spara / uppdatera rätt svar add_post_meta ($ post_id, 'correct_answer', $ _POST ['correct_answer'], true); // eller update_post_meta ($ post_id, 'correct_answer', $ _POST ['correct_answer']); 

Spara svar från Ajax-förfrågningar

Här kommer vi att ta emot data som skickas till servern från Backbone. Vi måste:

  1. Öppna data som skickas som en PUT-förfrågan. Som det kommer att vara i JSON-format, måste vi avkoda det
  2. Kontrollera igen att den aktuella användaren har relevanta behörigheter
  3. Fortsätt och försök spara
  4. Om antingen Lägg till eller Uppdatering lyckades kan vi helt enkelt returnera den nyligen sparade dataen och Backbone kommer att se detta som en lyckad spara
  5. Om inte heller lyckades returnerar vi bara 0 för att indikera ett fel
 / ** src / WpQuiz.php ** / public function saveAnswers () // Hämta PUT data och avkoda den $ model = json_decode (file_get_contents ("php: // input")); // Se till att den här användaren har rätt behörigheter om (! $ This-> canSaveData ($ model-> post_id)) return;  // Försök att infoga / uppdatera $ update = add_post_meta ($ model-> post_id, $ model-> answer_id, $ model-> answer, true); // eller $ update = update_post_meta ($ model-> post_id, $ model-> answer_id, $ model-> answer); // Om en spara eller uppdatering lyckades, returnera modellen i JSON-format om ($ update) echo json_encode ($ this-> getOneAnswer ($ model-> post_id, $ model-> answer_id));  annars echo 0;  dö (); 

Helpermetoderna

Här är de fyra hjälparna som nämns i ovanstående snippets.

  1. canSaveData () - Detta garanterar bara att den nuvarande användaren har relevanta behörigheter för att redigera / uppdatera det här inlägget.
  2. addScripts () - Observera att vi här ser till att vi passerar 5: e parametern till wp_register_script () fungera. Detta laddar vår anpassade JavaScript i sidfoten och säkerställer att vår JSON-data är tillgänglig. Om du använder WordPress-redigeraren i ditt plugin behöver du inte ange Backbone som ett beroende eftersom det redan är tillgängligt för dig. Jag inkluderar det här för exempelets skull.
  3. registerPostType () - Detta är något jag ofta använder i plugins. Det gör bara livet enklare när du lägger till en ny anpassad posttyp. Det accepterar både singulära och flertalsversioner av namnet eftersom det inte alltid är så enkelt att bara lägga till en s '.
  4. getTemplatePart () - Jag har aldrig varit förtjust i att ha mark-up inuti mina metoder. Den här lilla hjälpen tillåter användning av en separat mallfil.
 / ** src / WpQuiz.php ** / / ** * Bestäm om den nuvarande användaren har relevant behörighet * * @param $ post_id * @return bool * / privat funktion canSaveData ($ post_id) om (definierat ('DOING_AUTOSAVE ') && DOING_AUTOSAVE) returnera false; om ('sida' == $ _POST ['post_type']) if (! current_user_can ('edit_page', $ post_id)) returnera false;  annars om (! current_user_can ('edit_post', $ post_id)) returnera false;  returnera sant;  privat funktion addScripts () wp_register_script ('wp_quiz_main_js', pp (). $ this-> jsAdmin, array ('backbone'), null, true); wp_enqueue_script ('wp_quiz_main_js');  / ** * Registrera en anpassad posttyp * * @param $ single * @param $ plural * @param null $ supports * / privat funktion registerPostType ($ single, $ plural, $ supports = null) $ labels = array 'namn' => _x ($ plural, 'posttyp generellt namn'), 'singular_name' => _x ("$ singel", "posttyp singular name"), "add_new" => _x "," $ single ")," add_new_item "=> __ (" Lägg till ny $ singel ")," edit_item "=> __ (" Redigera $ singel ")," new_item "=> __ (" Ny $ singel ") , 'all_items' => __ ("All $ plural"), "view_item" => __ ("Visa $ singel"), "search_items '=> __ (" Sök $ flertalet ")," not_found "=> __ "No $ plural found"), "not_found_in_trash '=> __ (" No $ single found in Trash ")," parent_item_colon' => "," menu_name "=> $ plural); $ args = array > $ label, 'public' => true, 'publicly_queryable' => true, 'show_ui' => sant, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => true, 'capability_type' = > 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => nul l, 'support' => ($ support)? $ stöder: array ("title", "editor", "page attributes")); register_post_type ($ single, $ args);  / ** * Rendera en mallfil * * @param $ filePath * @param null $ viewData * @returnsträng * / allmän funktion getTemplatePart ($ filePath, $ viewData = null) ($ viewData)? extrakt ($ viewData): null; ob_start (); inkludera ("$ filePath"); $ template = ob_get_contents (); ob_end_clean (); returnera $ template; 

5. På framsidan

Vid denna tidpunkt har vi satt upp allt som behövs för vår baksida. Det är dags att ta en paus och förbereda sig för nästa del där vi kommer ner och smutsar med klientsidemallar, JavaScript och Backbone.js. Jag hoppas att vi ses där - det kommer att bli bra.