Hittills har vi renderat blockets utdata i Javascript. Men med dynamiskt innehåll som senaste inlägg eller visning av ett inlägg måste vi rendera blockets utdata i PHP. I det här inlägget kommer vi att lära oss hur och varför.
Varför behöver vi hantera dynamiska block annorlunda?
Några exempel är uppenbara; ett block som visar de senaste inläggen i en kategori är dynamiskt eftersom inläggen kommer att förändras över tiden. Du väljer inte inläggen i blocket; istället kommer du förmodligen att ha inställningar för att välja kategori, vilken information som ska visas för varje inlägg, antalet inlägg, antalet kolumner och så vidare. Varje gång WordPress laddar ett inlägg med detta block måste det fråga WordPress vid den tidpunkten för de senaste inläggen. Att titta på samma inlägg månaden efter kan ge olika resultat även om inlägget med själva blocket inte har uppdaterats.
Men nödvändigheten av dynamiska block är ibland inte så uppenbar. Du kanske föreställer dig ett utvalt inläggsblock där du väljer ett specifikt inlägg för att visa det, inte nödvändigtvis är dynamiskt. Men det kan vara – och borde vara. Kom ihåg att det valda inlägget kan uppdatera sin titel, utdrag eller utvalda bild när som helst – och det bör återspeglas i blocken som innehåller detta inlägg.
För att göra ett icke-dynamiskt block för att visa ett enskilt inlägg måste du spara inläggets ID, dess URL, webbadress för utvald bild, utdragssträng eller vad du nu behöver för att förhandsgranska inlägget, i blockets attribut. Och här ligger problemet. Om du uppdaterar det valda inläggets utvalda bild kommer inlägget med det utvalda inläggsblocket inte automatiskt att uppdatera dess attribut. Den förblir sparad med den gamla utvalda bildens URL. Först när du redigerar inlägget med blocket, och ser till att det sparar attributen med den uppdaterade informationen, kommer blocket att visa den korrekta uppdaterade informationen.
Så närhelst vi hanterar dynamiskt innehåll – inlägg, kategorier eller något som kan förändras över tid – har vi att göra med dynamiska block. Och för dynamiska block måste vi använda PHP – kod på serversidan – för att rendera vårt block för att säkerställa att det kommer att hämta uppdaterad information varje gång det renderas.
Den förändrade karaktären hos dynamiska block i editorn
När du börjar utveckla dynamiska block kommer karaktären på ditt block i editorn att ändras. Ditt blocks edit
funktion behöver ofta också vara dynamisk. Till exempel för ett utvalt inläggsblock måste du hämta inlägg att välja mellan, eller för ett senaste nyhetsblock måste du hämta en lista med kategorier som användaren kan välja mellan.
Det är fullt möjligt att begära information från WordPress inifrån editorn genom att göra AJAX-förfrågningar – antingen genom att använda paket och komponenter eller utföra dem manuellt med WordPress REST API. Oavsett vilken metod du väljer måste ditt block hantera den asynkroniserade strömmen av input – tidsramen medan du väntar på ett svar.
Det finns flera metoder och mönster för att skapa ett dynamiskt block för Gutenberg. Vanligtvis använder du ett React-mönster som kallas komponenter av högre ordning där WordPress tillhandahåller massor av funktioner och komponenter för.
Vi kommer att titta på hur man hämtar inlägg och hur man hämtar kategorier i vårt block i nästa handledningsdel. För nu måste vi lära oss hur vi får PHP att rendera vårt block.
Gör vårt block redo för PHP-rendering
Huvuddelen vi behöver göra i Javascript är att få blockets save
funktion att returnera null
. Du kan behålla originalutgången, men när vi säger åt WordPress att använda PHP för att rendera blocket kommer detta att ignoreras. För att göra det klart för oss själva och andra att blockets utdata inte hanteras i Javascript kommer vi att ändra save
funktionen.
Glöm inte att om du ändrar sparfunktionen kommer alla befintliga block att gå sönder. Lägg till blocket igen. Blocket ska fungera precis som tidigare; med inställningarna och uppdatering av attributen. Det kommer nu bara inte att mata ut något i frontend. Kommentarsblocket kommer att finnas där och lagrar alla attribut i JSON, men ingen synlig HTML renderas.
I alla fall; om något av dina attribut använder source
egenskapen måste du ändra detta. Detta stöds inte med block som renderas med PHP eftersom de tolkas direkt från savens utdata – vilket vi nu återkommer null
till. Vi använder källa på den andra RichText
i vårt block – för stycket. Redaktören sparar inte alls det du lägger i det här RichText
.
Så om du också fortfarande använder source
på myRichText
attributet, måste vi ta bort egenskaperna source
och selector
för att säkerställa att attributen kommer att lagras och inte tolkas från save
funktionen:
attributes: {
...
myRichText: {
type: 'string',
},
...
Efter detta är vårt block redo för rendering i PHP. Vi kan lämna Javascript-filerna (glöm inte att bygga det) och resten görs i PHP.
Rendering av block i PHP
För att säga åt WordPress att rendera blockets utdata i PHP lägger vi till ett nytt argument till funktionen register_block_type()
. Vi måste lägga till nyckeln render_callback
till arrayen med ett värde för funktionen den ska köra.
PHP-renderingsfunktionen
Låt oss definiera funktionen awp_myfirstblock_render
längre ner i functions.php
(eller var du än har lagt din PHP-kod). Vår funktion kommer att få två parametrar; vi ringer dem $attr
och $content
.
function awp_myfirstblock_render($attr, $content) {
// return the block's output here
}
Parametern $attr
kommer att vara en associativ array med alla sparade attribut. Den andra parametern, $content
, är för block inuti vårt block. Detta är endast relevant för block som stöder kapslade block – vilket till exempel Columns eller Cover gör.
Funktionen får aldrig echo
ut något. All utdata måste returneras så du måste bygga en sträng och returnera den i slutet.
Något som är viktigt att komma ihåg om attribut är att endast sparade attribut visas i den första parametern till funktionen. Om ett attribut faktiskt aldrig ändrades och sparades – dvs bara förlitade sig på dess default
, kommer attributet inte att inkluderas alls för vår PHP-funktion.
Du måste hantera detta problem genom att antingen alltid kontrollera if (isset($attr['...']))
eller på det bästa sättet: definiera attributen i vårt register_block_type()
samtal. Vi kan tillhandahålla en annan nyckel, attributes
, och ställa in dess värde till en array med alla attribut vi vill extrahera från vårt block. Strukturen bör vara identisk med den du definierade i Javascript, men istället för ett Javascript-objekt behöver du det i en PHP-array. Det här kan vara lite krångligt att omdefiniera samma attribut, men med en smart kodredigerare borde det gå ganska snabbt att kopiera+klistra in och redigera flera rader i PHP.
Lägger till attributen för vår renderingsfunktion
Låt oss lägga till det nya attributes
elementet register_block_type()
och klistra in exakt samma attribut som vi definierade i vår Javascript-fil:
Tänk på att om du definierar a default
för alla attribut ska din funktions $attr
parameter alltid innehålla alla attribut. Till exempel kommer attributet textAlignment
ovan bara att finnas i $attr
om det ändrades – och du måste kontrollera isset($attr['textAlignment'])
.
Tyvärr finns det för tillfället två saker du inte kommer att få tag på med PHP block render. Den ena är className
rekvisiten – så du måste bygga omslagsklassen (om du vill ha det) själv. Den andra är support
egenskapen för blockinriktning. För tillfället stöder WordPress inte den här egenskapen i dynamiska block. Vi kommer inte att få tag på värdet på den valda blockjusteringen om vi inte ändrar det till ett attribut och hanterar det manuellt i Javascript.
När det gäller HTML-utdata för funktionen är detta helt upp till dig!
Begär PHP-rendering från insidan av editorn
Det är möjligt att begära PHP-renderingen av vårt block inuti editorn. Detta är användbart om du vill kunna förhandsgranska blockets utdata i editorn. Vi kan göra detta med en komponent som anropas ServerSideRender
från wp.editor
paketet.
Som rekvisita till ServerSideRender
dig måste du definiera alla attribut du vill förmedla. Som ett minimum måste du ange blockets namn till prop block
, så att WordPress vet vilken renderingsmetod du ska leta efter. Detta är tillgängligt för dig i props.name
funktionen edit
. Du måste också ange alla attribut du behöver i rekvisitan attributes
. Om du vill kan du lägga till anpassade variabler utanför attribut här också. Tänk bara på att detta bara kommer att fungera för inre editor, och inte frontend.
Du kan inte använda ServerSideRender
i blockets save
funktion. Din save
funktion måste fortfarande återvända null
.
Låt oss implementera ServerSideRender
i vårt block för att se det i praktiken.
Använder ServerSideRender för blockera förhandsgransknings-/redigeringsläge
Om du följde föregående steg där vi gjorde en förhandsgransknings-/redigeringslägesväxlare för vårt block, kan vi nu använda ServerSideRender
för att återge förhandsvisningen av blocket från PHP när vi växlar till förhandsgranskningsläge.
Först måste vi komma ihåg att destrukturera ServerSideRender
överst:
const { ServerSideRender } = wp.editor;
Om du kommer ihåg från föregående steg använde vi komponenterna Disabled
och/eller Placeholder
för att hålla förhandsvisningen. Problemet med att använda Placeholder
är att vi får oönskad styling applicerad på vår produktion. Låt oss ersätta Placeholder
med ServerSideRender
. Du kan välja att behålla Disabled
komponenten för att säkerställa att inget av dess innehåll är klickbart eller dragbart.
Vid koden för att rendera blocket när attributet editMode
är falskt gör vi:
Nu kommer vår anpassade knapp i verktygsfältet att återge utdata från PHP när vi byter till förhandsgranskningsläge. Utdata ska vara identisk när du tittar på inlägget i frontend. Detta är en god vana att se till att resultatet är identiskt i både editor och frontend.
Exempel: Dynamiskt block som visar ett valt inlägg
Utdata i din PHP-renderingsfunktion kan vara vad som helst och du har full tillgång till alla WordPress-funktioner. Antag ett block där ett inläggs-ID kommer att sparas i ett attribut. I render_callback
PHP-funktionen kan du fråga inlägget från ID:t och mata ut dess information. Det borde vara ganska självförklarande hur man gör detta, men här är ett snabbt exempel.
OBS: I det här exemplet lägger vi helt enkelt till en textinmatning till editorn för manuell inmatning av ett inläggs-ID. Det här är inte en väldigt intuitiv och användarvänlig lösning för att välja ett inlägg – men det här är vad vi kommer att lära oss i nästa steg. Fokus här ligger på PHP-delen av renderingen av det valda inlägget.
Låt oss lägga till ett attribut selectedPostId
av typnummer:
attributes: {
selectedPostId: {
type: 'number'
}
}
Och någonstans inne i vårt blocks edit
funktion lägger vi till en TextControl
komponent. Den kan vara var du vill – inne i blocket eller i Inspektören.
Observera att jag är extra noga med att säkerställa att indata sparar attributet korrekt som ett tal genom att konvertera det till heltal med parseInt()
. Även om vi ställer in typ prop type
för number
att återge en sifferinmatning, tolkas det ändrade värdet fortfarande som en sträng. WordPress kommer inte att spara ditt attribut om det är i fel format.
Glöm inte att lägga till det nya attributet till din ServerSideRender
komponent om du har en:
PHP-delen
Det borde ha tagit hand om Javascript-delen. Låt oss gå vidare till PHP. Först måste vi lägga till det nya attributet selectedPostId
till attributes
arrayen i register_block_type()
:
I render_callback
funktionen kan vi nu komma åt post-ID med $attr['selectedPostId']
. Vi kan med det utföra en enkel get_post()
och mata ut postens data; dess länk och titel:
Detta är ett mycket grundläggande exempel menat som en springbräda för dig att skriva mer avancerad och anpassad kod.
Nu när vi vet hur man hanterar rendering av dynamiska block, är nästa steg att lära sig hur man gör redigeringsdelen mer intuitiv också. I nästa steg kommer vi att fokusera på hur man frågar efter inlägg från blockredigeraren och ger användaren ett bättre sätt att välja ett inlägg.