Hur man integrerar WordPress Media Uploader i temat och pluginalternativ

Välkommen WordPress Theme och Plugin utvecklare! Vi vill alla att våra temanvändare ska kunna ladda upp egna bilder eller logotyper genom att använda en temanalternativssida som skapats av oss (inklusive pluginsidor) men hur programmerar du det? Använder du WordPress Media Uploader (som när du laddar upp en utvald bild eller lägger in en bild i ett inlägg) eller lägger du bara till ett filinmatningsfält och glömmer allt annat? Överför du bilder till en uppladdningsmapp korrekt? Fäster du bilden i WordPress Media Library? Och det här är en viktig punkt, tar du bort filen (om det är vad användaren vill) korrekt? Tja, det är dags att forma vår sida Temaalternativ med hjälp av WordPress-gränssnittet. Vi vill ha glada användare, vi vill ha ett användarvänligt gränssnitt.

Denna handledning är inriktad på att ladda upp bilder till en teman Alternativ sida, så om du inte är helt säker på hur du skapar en, rekommenderar jag dig först och främst, ta en titt på den fantastiska Tom McFarlins handledning. Den fullständiga guiden till WordPress-inställningarna API-serien.


Vad ska vi göra i den här handledningen?

  • Vi lägger till en knapp i vårt formulär för att ladda upp bilder eller logotyper till vårt serverfilsystem och en annan knapp för att ta bort den här bilden.
  • Vi kommer att skapa ett inmatningsfält för att förhandsgranska bilden.
  • Vi använder WordPress Media Uploader för att ladda upp filen eller välja en befintlig, så vi behöver inte oroa oss för hela processen. Vi klarar också att ladda upp bilden till den högra mappen och vi bifogar den till WordPress Media Library.
  • Vi kommer att kunna ta bort själva bilden och dess bilaga till WordPress Media Library. Vi vill inte slösa bort serverns utrymme.

Förberedelse Skapa en teman Alternativ sida

Vi måste skapa en mapp som heter wptuts-options i temat rotmappen som innehåller en fil som heter wptuts-options.php där hela koden som behövs för att skapa vår sida för teman Alternativ kommer att definieras. Vi måste också skapa en mapp som heter js där vi ska spara de JavaScript-filer som vi behöver.

Först av allt måste vi ringa vår wptuts-options.php filen från vår sida functions.php:

 require_once ('wptuts-options / wptuts-options.php');

Inuti vårt wptuts-options.php fil ska vi skapa en funktion där vi kommer att ange standardvärdena. I det här fallet kommer värdet att vara bildadressen på vår server. Vi kommer att tilldela en tom sträng som standard men vi kan också tilldela webbadressen till en bild som vi redan har i en temakatalog.

 funktion wptuts_get_default_options () $ options = array ('logo' => "); returnera $ options;

Nu ska vi skapa en funktion som om vårt alternativ inte finns i databasen (vi kommer att kalla det theme_wptuts_options), kommer att initiera det med de värden som ges av vår tidigare funktion.

 funktion wptuts_options_init () $ wptuts_options = get_option ('theme_wptuts_options'); // Har våra alternativ sparats i DB? om (false === $ wptuts_options) // Om inte, sparar vi våra standardalternativ $ wptuts_options = wptuts_get_default_options (); add_option ('theme_wptuts_options', $ wptuts_options);  // I annat fall behöver vi inte uppdatera DB // Initialize Theme options add_action ('after_setup_theme', 'wptuts_options_init');

Nu är det dags att skapa vår sida Temaalternativ, lägga till den i administratörspanelen och skapa ett formulär.

 // Lägg till "WPTuts Options" länk till menyn "Utseende" menyn wptuts_menu_options () // add_theme_page ($ page_title, $ menu_title, $ capability, $ menu_slug, $ function); add_theme_page ('WPTuts Options', 'WPTuts Options', 'Edit_theme_options', 'wptuts-inställningar', 'wptuts_admin_options_page');  // Ladda administratörsalternativ sidan add_action ('admin_menu', 'wptuts_menu_options'); funktion wptuts_admin_options_page () ?>  

Sammanfattningsvis: Genom att använda kroken admin_menu Vi har lagt till vår sida i administratörspanelen under Utseende -> WPTuts Alternativ och det kunde identifieras av sluggan wptuts-settings. Efter det har vi skapat ett formulär som fortfarande inte har något inmatningsfält baserat på setting_fields och do_settings_sections funktioner. Som jag har sagt tidigare, är målet med denna handledning inte att beskriva hur dessa fungerar, så vi kommer inte att förklara vad de är för. Du kan läsa Toms serie på det som länkats ovan.

Men var uppmärksam på att bortsett från att skapa knappen lämna, vi har också skapat en annan, a Återställa knapp. När vi trycker på det kommer bildvärdet att vara det som standard.

Slutligen kommer vi att skapa vår knapp för att ladda upp bilder och ett inmatningsfält där den en gång uppladdad visar webbadressen.

 funktion wptuts_options_settings_init () register_setting ('theme_wptuts_options', 'theme_wptuts_options', 'wptuts_options_validate'); // Lägg till en blankett för Logo add_settings_section ('wptuts_settings_header', __ ('Logo Options', 'wptuts'), 'wptuts_settings_header_text', 'wptuts'); // Lägg till Logo Uploader add_settings_field ('wptuts_setting_logo', __ ('Logo', 'wptuts'), 'wptuts_setting_logo', 'wptuts', 'wptuts_settings_header');  add_action ('admin_init', 'wptuts_options_settings_init'); funktion wptuts_settings_header_text () ?> 

Det finns inte mycket mer att säga här, bara det värdet av logotyp fältet visar den slagna bildadressen. Just nu är detta vad vår skärm visar:

Och glöm inte bort vår data valideringsfunktion:

 funktion wptuts_options_validate ($ input) $ default_options = wptuts_get_default_options (); $ valid_input = $ default_options; $ submit =! tomt ($ input ['submit'])? sant falskt; $ återställ =! tomt ($ input ['reset'])? sant falskt; om ($ inlämna) $ valid_input ['logo'] = $ input ['logotyp']; elseif ($ reset) $ valid_input ['logo'] = $ default_options ['logotyp']; returnera $ valid_input; 

Låt oss spara värdet på logotyp fältet precis som det är om vi skickar in formuläret eller lämnar det med standardvärdet om vi återställer formuläret. Det är lämpligt att kontrollera värdet på inmatningsfältet och validera webbadresserna.

Om vi ​​har kommit fram till denna punkt (jag hoppas det) och vi är inte riktigt trötta kan vi prova formuläret. Vi kommer att se att värdet på inmatningsfältet sparas utan problem och det visar därefter en webbadress som värde.

Nu, låt oss fortsätta med vad det är väldigt viktigt.


Steg 1 Lägga till nödvändig JavaScript

Om vi ​​vill att WordPress Media Uploader ska fungera korrekt måste vi importera flera JavaScript-biblioteken och några ytterligare CSS:

  • Thickbox (JS) - Ansvarig för hantering av modalfönstret, som vi kommer att kunna dra eller välj filer. Det tillhandahålls av WordPress Core.
  • Thickbox (CSS) - Ger de stilar som behövs för det här fönstret. Det kommer också med WordPress-installationen.
  • Media Upload (JS) - Ger alla funktioner som behövs för att ladda upp, validera och ge format till filer. Det är WordPress Media Uploader-hjärta.
  • Vår egen JS - Det kommer att initiera de parametrar som behövs för att visa fönstret korrekt.

Vi måste presentera följande kod i wptuts-options.php fil:

 funktion wptuts_options_enqueue_scripts () wp_register_script ('wptuts-upload', get_template_directory_uri (). '/ wptuts-options / js / wptuts-upload.js', array ('jquery', 'media-upload', 'thickbox')); om ('appearance_page_wptuts-settings' == get_current_screen () -> id) wp_enqueue_script ('jquery'); wp_enqueue_script ( 'thickbox'); wp_enqueue_style ( 'thickbox'); wp_enqueue_script ( 'media-upload'); wp_enqueue_script ( 'wptuts-upload');  add_action ('admin_enqueue_scripts', 'wptuts_options_enqueue_scripts');

Det finns ett par saker som vi måste klargöra: I första raden registrerar vi ett manus (vi har inte pratat om det ännu) som hanterar processen för att öppna modellfönstret och samla bilddata. Som vi har förklarat innan kommer vi att skapa en mapp som heter js. En särdrag hos det här skriptet är att det beror på ett antal andra bibliotek som jQuery, Media-Upload och Thickbox, alla kommer när du installerar WordPress.

I den andra raden använder vi get_current_screen () funktion som ger oss slugen på sidan vi jobbar med. Denna funktion kan inte alltid användas och beroende på vilken krok vi använder, kommer den vara tillgänglig eller inte. Med kroken admin_enqueue_scripts funktionen fungerar utan problem. get_current_screen () -> id ger oss en slug på sidan där vi arbetar. För de sidor som kommer som standard i WordPress-administrationspanelen kan det här vara "teman''redigera inlägg''plugin-program"etc. I vårt fall ser denna slug ut appearance_page_ OUR_SLUG. Kommer du ihåg den slug som vi definierade i add_theme_page fungera? Tja, vår sida med teman Alternativ har äntligen följande slug: appearance_page_wptuts-settings. Så vi laddar bara skript när det är lämpligt.

De andra två raderna lägger till Javascript-bibliotek jQuery, Thickbox, Media Upload och vår JS, wptuts-upload.js. Dessutom lägger vi också till Thickbox CSS.

Vårt skript: wptuts-upload.js

Trots hur det ser ut, blir vårt skript enklare än det kan visas. Det är bara nödvändigt att lära känna några Thickbox-funktioner och Media Uploader för att få det att fungera. Problemet är att det är svårt att hitta information om det och i slutändan, som de bra programmerare att vi är, har vi inget annat val än att arbeta med kod. Som vi bara ska se är det verkligen lätt att göra. Låt oss fortsätta direkt till vår första versionskod:

 jQuery (dokument) .ready (funktion ($) $ ('# upload_logo_button'). klicka (funktion () tb_show ('Ladda upp en logotyp', 'media-upload.php? referer = wptuts-inställningar & typ = bild & TB_iframe = true & post_id = 0 ', false); return false;););

Framgång! Om vi ​​trycker just nu vår Ladda upp logotypen knappen visas WordPress Media Uploader. Bra, vi är klar, vi ses snart! Nej, det här är inte sant, men det tar inte mycket längre tid att göra vår Temaalternativs sida på ett enkelt sätt.

Genom att granska koden kan vi se att vi har tilldelat en klickhändelse till knappen som startar en Thickbox-funktion som syftar till att visa modalfönstret. Denna funktion accepterar tre parametrar:

  • Fönstets namn - I vårat fall 'Ladda upp en logotyp'
  • URL - Utför ett WordPress-bibliotek som hanterar och validerar filer, förutom att skapa innehåll för fönstret.
  • Imagegroup - Vi har valt alternativet falsk för att vi inte kommer att arbeta med grupper av bilder men bara med en.

Bland dem är den mest intressanta adressen URL. WordPress använder en fil som heter media-upload.php att hantera fönstret och tillåter också flera $ _GET parametrar. Vi måste komma ihåg det & tecken måste kodas med deras HTML-enhet så URL-adressen fungerar utan problem.

  • referer - Denna parameter är valfri. Vi använder det senare för att göra lite knep.
  • typ - Det är typen av fil. Det kan vara video-, audio, bild eller fil.
  • TB_iframe - Det måste alltid väljas Sann så fönstret visas i en iframe, eller det fungerar inte. Även om du kan hitta det här svårt att tro, är det den viktigaste parametern och nu kommer vi att se varför.
  • post_id - Det används för att indikera att bilden inte kommer att fästas på något inlägg och att det blir gratis som en liten fågel.

Tja, jag vill inte ljuga för dig. Bara en av dessa tre parametrar är verkligen nödvändig: TB_iframe. Vi kan glömma bort de andra. Vissa versioner sedan, förenade WordPress sin Media Uploader för att ladda upp vilken typ av fil som helst, utan att behöva skilja bilder från video eller musik, så typ är inte nödvändigt och post-id är 0 som standard. Hur som helst, det är ingen skada att lämna dem bara om vi har några problem med kompatibilitet. Det skulle vara intressant att ange post_id om det är en Meta Box i ett inlägg.

Följande del av vår JavaScript måste innehålla följande funktion:

 window.send_to_editor = function (html) var image_url = $ ('img', html) .attr ('src'); $ (# Logo_url) val (bild_URL). tb_remove (); 

send_to_editor är en händelse som ingår i WordPress JavaScript Media Uploader-biblioteket. Den kommer att leverera bilddata i HTML-format, så vi kan placera dem varhelst vi vill.

Denna händelse ger en parameter till handlarfunktionen, html som innehåller följande kod (som exempel):

 

Så det är lätt att extrahera bildadressen en gång laddad till servern med hjälp av raden $ (Img ", html) .attr ( 'källa'); då lagras det i vårt inmatningsfält med linjen $ (# Logo_url) val (bild_URL)..

Funktionen tb_remove stänger det modala fönstret, det är allt. Nu kan vi redan skicka in formuläret och spara bildadressen i databasen. Vi kunde sluta nu, men resultatet skulle inte se riktigt vackert eller användarvänligt så låt oss göra en förbättring.

Om vi ​​uppmärksammar, när vi laddar upp bilden med hjälp av Media Uploader kan vi infoga bildadressen i vårt inmatningsfält genom Infoga i Post knapp. Detta kan förvirra användaren. Därför kan vi ändra texten genom att använda filter i WordPress. Vi skriver följande kod i vår wptuts-options.php fil:

 funktion wptuts_options_setup () global $ pagenow; om ('media-upload.php' == $ pagenow || 'async-upload.php' == $ pagenow) // Nu ska vi ersätta 'Infoga in post-knappen' i Thickbox add_filter ('gettext' 'replace_thickbox_text', 1, 3);  add_action ('admin_init', 'wptuts_options_setup'); funktion replace_thickbox_text ($ translated_text, $ text, $ domain) if ('Insert into Post' == $ text) $ referer = strpos (wp_get_referer (), 'wptuts-inställningar'); om ($ referer! = ") return __ ('Jag vill att detta ska vara min logga!', 'wptuts'); returnera $ translated_text;

Använda kroken admin_init, Vi kontrollerar att sidorna vi arbetar på är de som används av Media Uploader. Dessa sidor är: media-upload.php och async-upload.php. Den första öppnar modalfönstret och den andra laddas när bilden har laddats upp. För att bekräfta att vi arbetar på någon av dem måste vi använda den globala variabeln $ pagenow och inte funktionen get_current_screen () därför att admin_init tillåter fortfarande inte denna funktion.

Nu, varför använder vi referer variabel? Ok, det här är lite knepigt och det fungerar så här:

  • När vi klickar på Ladda upp bild knappen är referensadressen något liknande http://www.ourdomain.com/.../wp-admin / themes.php? page = wptuts_settings
  • Om vi ​​sedan klickar på en flik som Media Library i Media Uploader ändras referensadressen och tar nästa värde: http: // localhost / ... /wp-admin/media-upload.php?referer=wptuts-settings&type=image.
  • Samma sak händer när vi laddar upp en ny bild. Refereradressen ändras och tar samma värde.

Se nu varför vi inkluderade refererparametern i vår JavaScript? Vi behöver veta från vilken sida vi startar Media Uploader eftersom vi behöver byta ut Infoga i Post Text i knappen bara på vår sida Temaalternativ och inte på en postsida till exempel. Därför inkluderade jag refererparametern. Nu använder du wp_get_referer () funktion vi får refereradressen och vi måste bara hitta wptuts-settings strängen inuti den webbadressen. Med denna metod ersätter vi den i rätt sammanhang.

Vi tillämpar nu gettext filtrera och varje mening innehåller "Infoga i inlägg" vi ersätter med "Jag vill att detta ska vara min logotyp!". Om vi ​​öppnar igen Thickbox-fönstret och laddar in en ny fil ser vi att texten på knappen har ändrats. Om du inte är helt säker på hur du använder gettext filtrera, och eftersom det inte är något av målen i denna handledning, kan du besöka WordPress Codex.

Några förbättringar har gjorts, har inte de?


Steg 2 Förhandsgranskar bilden

Användaren behöver alltid titta på saker som händer på skärmen. Det räcker inte för användaren att ladda upp en bild och gå till sidan för att kontrollera att bilden finns där. Nu ska vi lägga till ett inmatningsfält på vår sida Temaalternativ så att användaren kommer att kunna se den vackra bilden som redan laddats.

Vi måste skriva följande kod i vår wptuts_options_settings_init () fungera:

 // Lägg till aktuell bildförhandsvisning add_settings_field ('wptuts_setting_logo_preview', __ ('Logo Preview', 'wptuts'), 'wptuts_setting_logo_preview', 'wptuts', 'wptuts_settings_header');

Och vi måste också skapa en ny funktion för förhandsvisningen:

 funktion wptuts_setting_logo_preview () $ wptuts_options = get_option ('theme_wptuts_options'); ?> 

Om vi ​​laddar upp en ny bild just nu och vi skickar formuläret så ser vi det här:

Häftigt! Ta det lugnt, kör inte. Det finns två steg att ta, först laddar vi upp bilden och vi är tvungna att skicka in formuläret om vi vill spara ändringarna. Användaren kan tänka när bilden är uppladdad, var i helvete är min logotyp? Måste jag skicka in formuläret? Undvik att bli upprörd genom att lägga till några enkla linjer till vår JavaScript:

 window.send_to_editor = function (html) var image_url = $ ('img', html) .attr ('src'); $ (# Logo_url) val (bild_URL). tb_remove (); $ ('# upload_logo_preview img'). Attr ('src', image_url); $ (# Submit_options_form) trigger ( 'klick'). 

Vi laddar upp bilden och vi kan se att formuläret har skickats! Bara lägger till en mening: Nu när bilden laddas, utlöser vi klick händelse på knappen Lämna och formuläret skickas omedelbart, uppdatering av databasen och bildförhandsvisningen samtidigt. Perfekt!

Ta bort vad som är onödigt

Hittills är formuläret attraktivt, användbart och det fungerar mer än okej men det finns något som börjar störa oss. Varför behöver vi inmatningsfältet? Hej, vi behöver det för att spara bildadressen. Låt oss se det på ett annat sätt: varför användaren behöver inmatningsfält? För ingenting. Det räcker att visa användaren den bild som har laddats upp och att allt fungerar ordentligt.

Låt oss konvertera vår form lite mer med wptuts_setting_logo () fungera:

 funktion wptuts_setting_logo () $ wptuts_options = get_option ('theme_wptuts_options'); ?>     

Om du inte hade märkt, är det enda vi har gjort att ändra inmatningstypen av formuläret. Vi pratar nu om a dold Inmatningsfältet och inte a text Inmatningsområde. Blanketten håller samma funktionalitet men det är mycket trevligare för användaren:


Steg 3 Radera bilden

Naturligtvis vill användaren vid något tillfälle ta bort bilden. För att underlätta saker ska vi skapa en knapp för att ta bort den. Men bilden ska inte raderas först när användaren klickar på knappen, den ska också tas bort när de laddar upp en ny bild eller vi återställer formuläret.

Första saker först. Vi ska skapa den nya knappen i wptuts_setting_logo () fungera:

 funktion wptuts_setting_logo () $ wptuts_options = get_option ('theme_wptuts_options'); ?>        

Om vi ​​uppmärksammar kommer den nya knappen bara att visas när det redan finns en logotyp. Dessutom talar vi om en inmatningsknapp, så vi skickar in formuläret när vi klickar på det.

Vi måste lägga till följande valideringsfunktionalitet så att knappen fungerar som vi vill, wptuts_options_validate ():

 $ default_options = wptuts_get_default_options (); $ valid_input = $ default_options; $ wptuts_options = get_option ('theme_wptuts_options'); $ submit =! tomt ($ input ['submit'])? sant falskt; $ återställ =! tomt ($ input ['reset'])? sant falskt; $ delete_logo =! tomt ($ input ['delete_logo'])? sant falskt; om $ submit if ($ wptuts_options ['logo']! = $ input ['logotyp'] && $ wptuts_options ['logo']! = ") delete_image ($ wptuts_options ['logo']); $ valid_input [ 'logo'] = $ input ['logotyp']; elseif ($ reset) delete_image ($ wptuts_options ['logotyp']); $ valid_input ['logo'] = $ default_options ['logotyp']; elseif $ delete_logo) delete_image ($ wptuts_options ['logo']); $ valid_input ['logo'] = ";  returnera $ valid_input;

Okej, vad gör vi här? Vi har lagt till en ny $ wptuts_options variabel för att verifiera om användaren har klickat på Ta bort logotyp knapp. Om användaren gör det, ska delete_image funktionen körs och vi anger värdet av logotypens URL som en tom sträng. Dessutom kommer logotypen att raderas om vi skickar in och vi lägger upp en annan bild till den vi redan har eller ens om vi återställer formuläret.

Försiktig! Återställning av formuläret och radering av bilden behöver inte vara samma process. I vårt fall är standardvärdet en tom sträng, så de matchar.

Nu lägger vi till delete_image () fungera:

 funktion delete_image ($ image_url) global $ wpdb; // Vi behöver få bildens meta-ID. $ query = "VÄLJ ID FRÅN wp_posts där guid = '". esc_url ($ image_url). "'OCH post_type =' bilaga '"; $ results = $ wpdb-> get_results ($ query); // Och radera det för ($ resultat som $ rad) wp_delete_attachment ($ row-> ID); 

Sanningen är att det här steget behöver en djupare förklaring, men det är väldigt enkelt. Det första vi gör är att utföra en fråga som kommer att ta reda på Meta ID för vår bild i databasen. Du kanske tror att det är en lögn, men vår bilddata finns i wp_posts tabell. Tja, försöker sökningen att välja de register som vilar (bild-, post- eller sidadress) matchar vår bild och post_type = 'attachment' (Det är en bilaga, eller hur?). Vi lagrar detta ID (det borde inte vara mer än en) i $ resultat och skicka det som en parameter till WordPress wp_delete_attachment () som kommer att ta bort själva bilden och även ta bort bilagan från mediebiblioteket. Det är enkelt, rent och optimalt.


Steg 4 visar vår logotyp i vår webbplatsrubrik

Låt oss se var all denna röra ledde oss till. Vi behöver header.php mall där vi ska infoga ett utrymme för vår kära logotyp där vi sätter in den här koden på den plats vi gillar bäst:

 > 

Här är resultatet:


Slutliga anteckningar

Sanningen är att det inte finns mycket mer att säga. Är det möjligt att göra detta på ett annat sätt? Självklart, och i själva verket hittar jag exempel hela tiden, men från min synvinkel är WordPress Media Uploader verkligen användbar och när den är känd i djupet gör det verkligen livet enkelt. Vi sparar kod, validering (i handledningen vi inte har använt mycket, borde vi ha använt mer, och rekommenderar att du läser upp detta) och använd det filsystem som WordPress ställer till vårt förfogande. Alla är fördelar för användaren, som är van vid att arbeta med WordPress 'gränssnitt och kan se hur allt fungerar ordentligt och enligt WordPress standardfunktionalitet. Faktum är att det kan anses att det är WordPress standardfunktionalitet.


Externa resurser

Även om vi har pratat om specifik WordPress-funktionalitet, är sanningen att det finns mycket mellanmedvetenhet som är nödvändig. Här har vi en lista med relaterade resurser:

  • Den fullständiga guiden till WordPress Settings API
  • Thickbox på Github
  • gettext Filtrera
  • Gränssnitt med databasen i WordPress
  • wp_delete_attachment