Hur man lägger till en bildval i ditt anpassade WordPress Gutenberg-block
Det här inlägget är för dig som skapar ett anpassat Gutenberg-block och behöver ett sätt att välja eller ladda upp en bild från mediebiblioteket. De flesta andra fälttyper, såsom kryssrutor, textinmatning eller färgväljare, är ganska enkla att lägga till men en medieuppladdningsverktyg kräver lite mer kod. Vi kommer att skapa en Inspector-komponent som är ansvarig för att rendera en knapp för att öppna Media Library, välja en bild och eventuellt ta bort eller ändra den vid ett senare tillfälle. Alla använder vanliga WordPress-komponenter.
Innan vi dyker in i koden, kom ihåg att detta inlägg kräver viss Gutenberg-kunskap i hur man skriver anpassade block. Vi kommer bara att fokusera på medieuppladdningsdelen och inte hur man registrerar sig och gör ett Gutenberg-block i sig. Om du är osäker på hur man skriver ett anpassat Gutenberg-block har jag en handledningsserie som täcker exakt detta:
Med det ur vägen, låt oss dyka direkt in!
Vad vi ska göra
Funktionen för att välja media kommer funktionellt att vara exakt densamma som WordPress utvalda bildfunktion. Vi kommer inuti Inspector att lägga till en panel som består av en knapp för att välja en bild.
När du klickar på knappen kommer fönstret "Välj eller ladda upp media" att dyka upp så att du kan välja en fil från mediebiblioteket. Vi begränsar mediebiblioteket till att endast visa bilder. När en bild har valts stängs popup-fönstret och panelen förhandsgranskar en liten miniatyr av den valda bilden. Nedan visas förhandsgranskningsknapparna för att ändra och ta bort bilden. Exakt som med utvald bild.
Denna handledning förutsätter att du kommer att använda den valda bilden som blockets bakgrund – bara som ett exempel. Det är därför vi lagrar bildens URL. Jag ska inkludera ett exempel på hur man använder den valda bilden (både i edit
och i save
funktionen). När du väljer en bild kommer bilden att visas som bakgrund till vårt block, både i editorn och i frontend.
Vi lagrar media-ID och media-URL i blockets attribut. Koden använder withSelect
, en högre ordningskomponent som tillhandahålls i wp.data
paketet, för att söka mer information om det valda mediet, med ID.
Jag "lånar" även klassnamn från WordPresss utvalda bildfunktionalitet för att säkerställa att allt ser bra ut och att det inte finns något behov av att skriva någon CSS själv. Detta är naturligtvis valfritt.
Spara det valda mediet i attribut
Vad du behöver spara i ditt blocks attribut är lite upp till dig. Som ett minimum måste vi lagra media-ID, så klart. Detta kan vara tillräckligt om du inte behöver använda medias URL någonstans i skriptkoden. Till exempel om du använder ServerSideRender
där PHP är ansvarig för att rendera blockets utdata. I så fall kan du enkelt få bildens URL från media-ID med [wp_get_attachment_image_src](https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src/)()
t.ex. Men i exemplet nedan visar jag ett enkelt exempel på att visa bilden som bakgrund till vårt block, så jag lagrar även media-URL som attribut. Vi kommer att använda URL-attributet i både edit
(för att lägga till bakgrunden i editorn) och i save
(för att lägga till bakgrunden i frontend).
Låt oss börja med att definiera våra attribut. Media ID ska vara typnummer och standard till 0. Detta gör det enkelt att jämföra mot. Och media URL ska vara typ sträng med standard tom sträng.
attributes: {
mediaId: {
type: 'number',
default: 0
},
mediaUrl: {
type: 'string',
default: ''
}
},
Skapar komponenten
För att göra vår kod mer överskådlig definierar vi en separat komponent för blockets edit
funktion. Vi kommer senare att vidarebefordra denna komponent till withSelect
att linda den runt vår komponent.
I komponentens retur gör vi ett enkelt <div>
för blockinnehållet. Jag antar att du kommer eller har mer faktiskt blockinnehåll för att ersätta dummy-exemplets innehåll. Vi renderar också InspectorControls
(paket wp.blockEditor
) för att lägga till ett avsnitt till inspektören. För nu lägger jag till en tom PanelBody
inuti InspectorControls
. Jag lägger till en <div>
med samma klass som WordPress’ utvalda bildsektion använder. Detta gör att vår styling ser bra ut. Senare kommer vi att fylla detta PanelBody
med koden för den valda mediafunktionen.
Men först, låt oss destrukturera den nödvändiga komponenten i början av filen:
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
const { Fragment } = wp.element;
Ovanför registerBlockType
definierar jag en enkel komponent som heter BlockEdit
. Om du föredrar att flytta detta till en separat fil är du välkommen att göra det. Detta är vanligt och rekommenderat, men för den här handledningen håller jag saker enkelt och håller det i samma fil.
Nu vill vi återge denna komponent i vår edit
funktion. Men vi vill slå in det i en withSelect
.
Använder withSelect
i edit
funktionen
Om du inte är bekant med withSelect
, är det en användbar högre ordningskomponent som låter oss utföra frågor. Du kan till exempel fråga inlägg med detta. Vi kommer dock att använda funktionen select('core').getMedia()
för att fråga media-ID:t. Som svar får vi ett objekt med all medias information. Medieobjektet vi får som svar kommer sedan att tillhandahållas som rekvisita i vår BlockEdit
komponent, redo att användas. Tjusig.
Vi ser till att bara fråga media om media ID-attributet faktiskt är inställt på något annat än 0. Så här kommer vår redigeringsfunktion att se ut:
I slutet, efter att ha stängt withSelect
i kö #3
är det där vi ber withSelect
om att returnera vår BlockEdit
komponent. Med detta har vår BlockEdit
komponent nu tillgång till props.media
.
Återge ett mediaval
Äntligen kommer den roliga delen: delen i Inspektören.
Komponenten vi är intresserade av är MediaUpload
(paket wp.blockEditor
). Om du är intresserad har WordPress Github repo för Gutenberg lite dokumentation om den här komponenten. Vi kommer också att linda in den här komponenten i en komponent som heter MediaUploadCheck
(paket wp.blockEditor
). Den här komponenten ser till att den aktuella användaren har kapacitet att använda mediebiblioteket, så det är bra att använda detta.
Komponenten MediaUpload
har en nödvändig rekvisita: render
. Sättet som den här komponenten fungerar på är att vi definierar en funktion för render
rekvisitan där vi renderar utdata för "mediauppladdningsområdet". I vårt fall kommer vi att göra ett Button
(paket wp.components
). Inuti MediaUploads renderingspropp får vi tillgång till open
funktionen som vi kan anropa för att få WordPress att öppna popupen Media Library:
Det finns några fler rekvisita tillgängliga för MediaUpload
. Vi kommer att täcka de viktiga för att göra det funktionellt i denna handledning, men det finns några fler du kan spela med. Du kan åtminstone vara intresserad av rekvisiten allowedTypes
där du kan begränsa vilka filtyper som är möjliga att välja i biblioteket. I vårt fall ställer vi in det på att endast tillåta bilder.
Lägger tillMediaUpload
Destrukturera de nya komponenterna först;
const { Button } = wp.components;
const { MediaUpload, MediaUploadCheck } = wp.blockEditor;
Låt oss lägga till MediaUploadCheck
och MediaUpload
in i vår div
i vår PanelBody
:
Koden ovan destrukturerar open
inuti funktionen för render
. Vi gör en enkel Button
där dess onClick
egenskap kommer att köra open
funktionen. Jag har också lagt till samma klassnamn som WordPress utvalda bildfunktionalitet för att säkerställa att vi inte behöver lägga till någon styling.
Inuti Button
komponenten kontrollerar vi om en bild har ställts in eller inte (attributes.mediaId
). Om det inte är det, upprepar vi texten "Välj en bild". Vi borde nu få det här i vårt block.
När du klickar på knappen bör popupen Media Library visas. Men att välja en bild fungerar inte just nu, eftersom vi saknar onSelect
och value
rekvisita på MediaUpload
. Låt oss fixa det nu. Vi ställer value
in det valda media-ID:t och vi ställer in onSelect
att köra en funktion som vi senare kommer att definiera inuti vår komponent.
Låt oss definiera onSelectMedia
funktionen inom vår komponent.
Hantera val av media
Obs: Jag definierar mina funktioner som pilfunktioner (onSelectMedia =() => { }
). Pilfunktioner är ganska nya i ESNext och ganska snygga. Nackdelen är att användning av pilfunktioner kräver att du lägger till stöd för detta i din Babel-konfiguration. Om du inte har gjort detta rekommenderar jag att du tittar under rubriken “Sätta upp Babel" i det här inlägget.
Precis före komponentens retursats definierar jag en onSelectMedia
funktion. Allt vi behöver göra är att uppdatera våra attribut med setAttributes()
. Som parameter onSelectMedia
får vi ett mediaobjekt. Vi extraherar helt enkelt det vi behöver från medieobjektet. I vårt fall är det media-ID:t och webbadressen i full storlek, som är id
respektive egenskaper url
.
Prova det nu och du kommer nu att kunna välja en bild från mediebiblioteket. Det valda mediet sparas i blockets attribut. Det finns dock ingen förhandsgranskning av den i Inspektören ännu, och eftersom du har valt en bild försvinner knappen för att välja en bild. Panelen är nu tom. Nästa steg är att återge förhandsgranskningen när en bild har valts samt att tillhandahålla alternativ för att ta bort eller ändra den.
Återge en förhandsgranskningsbild
Inuti Button
komponenten vi renderar inuti MediaUpload
s render
rekvisita ekar vi en text "Välj en bild" om en bild ännu inte är inställd. Men vi måste lägga till lite kod för när en bild ställs in här; en förhandsvisning.
För att hjälpa oss att göra en snygg förhandsvisning använder vi komponenten ResponsiveWrapper
(paketet wp.components
). För att ResponsiveWrapper
fungera fullt ut måste vi tillhandahålla rekvisita för höjd och bredd. Vi behöver också webbadressen för miniatyrbilder. Det är ingen idé att använda hela URL-adressen (som kan vara gigantisk) för att göra en förhandsgranskning inuti inspektören. Det är här rekvisiten withSelect
kommer in. Inuti komponenten renderar vi en enkel <img>
HTML-tagg.
Först destrukturerar vi den nödvändiga komponenten:
const { ResponsiveWrapper } = wp.components;
Som du kan se kommer vi åt rekvisiten withSelect
som komponenten gav oss, props.media
. Vi hämtar bredd, höjd och webbadress till mediets miniatyrstorlek från objektet.
Du bör nu få en fin förhandsvisning av den valda bilden!
Eftersom vi återger förhandsgranskningsbilden inuti Button
kommer klickningen på förhandsgranskningsbilden att utlösa Button
funktionen onClick
– som är att öppna mediebiblioteket. På så sätt kan du redan ändra den valda bilden.
För närvarande finns det inget sätt att ta bort eller återställa den valda bilden. Låt oss fixa det!
Lägger till en borttagningsfunktion
Vi bör åtminstone erbjuda möjligheten för användaren att ta bort den valda bilden. Från och med nu när du har valt en bild kan du bara ändra den, men inte ta bort den.
Vi kommer att göra det på samma sätt som WordPress gör för utvalda bilder: En ny Button
under förhandsgranskningsbilden (helt utanför dess MediaUploadCheck
). Genom att tillhandahålla några smarta rekvisita Button
får vi det att se ut som en länk (isLink
) med röd textfärg (isDestructive
). Läs dokumentationen för Button för att se vad mer som är möjligt. Vi lindar in knappen i ännu en MediaUploadCheck
, bara för att säkerställa att användaren har rätt kapacitet.
För detta Button
evenemang onClick
kör vi en ny funktion i vår komponent: removeMedia()
. Vi definierar det någonstans precis innan komponentens returfunktion, som vi gjorde med onSelectMedia
.
Allt denna funktion gör är att återställa våra två attributvärden.
Vi kommer nu att ha en trevlig, tydlig länk för att ta bort bilden:
När du klickar på den nya knappen försvinner den valda bilden och själva knappen och knappen för att välja en bild visas igen.
Lägger till en ersätt-knapp
Detta steg är helt valfritt. Som nämnts tidigare, genom att klicka på bildens förhandsgranskningsbild öppnas Media Library och låter dig ändra bilden. Men detta kanske inte är lika intuitivt för alla att förstå. WordPress lägger till en separat knapp för att ändra bilden, bara för att göra det väldigt tydligt. Vi kan göra detsamma.
För att återge en ändra bildknapp upprepar vi i princip koden vi har för att välja bilden: en annan MediaUpload
komponent. Vi tillhandahåller samma funktion för onSelect
och allowedFileTypes
som value
tidigare. Inuti render
rekvisitan MediaUpload
gör vi helt enkelt en annan Button
som öppnar mediebiblioteket. Låt oss placera den här knappen före knappen Ta bort – eftersom detta är mer meningsfullt för slutanvändaren:
Så nu borde du få det här:
Använder den valda bilden
Vid det här laget borde det vara ganska klart hur du kan använda den valda bilden. Du har medie-ID och media-URL lagrade i ditt blocks attribut. Men som ett enkelt exempel kommer jag att inkludera en kod som ställer in den valda bilden som blockets bakgrund. Koden kan göras på exakt samma sätt i både edit
och save
funktionerna. Vi skapar helt enkelt ett stilobjekt som vi applicerar på blockets omslagsdiv. I stilobjektet sätter vi bakgrundsbild till media-URL.
Med resten av ditt anpassade blockinnehåll kan det enkelt se ut så här:
Om du tillämpar blockstilen i både edit
och save
, bör ditt block nu få det valda mediet som bakgrund. Både inne i editorn och i frontend.
Slutsats
Att välja en bild (eller fil) från Mediabiblioteket är en funktion som du som Gutenberg-utvecklare utan tvekan kommer att behöva för dina block. Vi har lärt oss hur man lägger till en funktion för att välja en bild från mediebiblioteket i vårt anpassade Gutenberg-block. Vi har gjort det på samma sätt som WordPress själv gör det för den utvalda bilden. (Redigera maj 2020: WordPress har nu uppdaterat den utvalda bilden för att använda useSelect
, React-kroken istället). Detta säkerställer att vår kod inte är "hackisk" med hög risk att gå sönder i framtida uppdateringar.
Låt mig veta om du har haft någon användning av detta!
Fullständig kod
Nedan finns den fullständiga koden för ett anpassat block som har den utvalda mediafunktionen. Och inget annat egentligen. Den delen är upp till dig!