WordPress Gutenberg Block API Opprette egendefinerte blokker

Den nye WordPress-redaktøren (kodenavnet Gutenberg) er på grunn av utgivelse i versjon 5.0. Nå er det den perfekte tiden for å få tak i det før det lander i WordPress-kjerne. I denne serien viser jeg deg hvordan du arbeider med Block API og lager dine egne innholdsblokker som du kan bruke til å bygge ut innlegg og sider.

I forrige innlegg så vi hvordan du bruker lag-guten-blokk verktøykasse for å lage et plugin som inneholder en prøveblokk klar for at vi skal jobbe med. Vi kan enkelt utvide dette etter behov, men det er en god ide å vite hvordan å lage en blokk fra grunnen for å forstå alle aspekter av Gutenberg-blokkutvikling.

I dette innlegget oppretter vi en annen blokk i vår my-custom-blokk plugin for å vise et tilfeldig bilde fra PlaceIMG webtjenesten. Du kan også tilpasse blokken ved å velge bildekategorien fra en rullegardinmeny, velg kontroll.

Men først lærer vi hvordan blokkskripter og stiler blir kalkulert før vi går videre til det aller viktigste registerBlockType () funksjon, noe som er grunnleggende for å skape blokker i Gutenberg.

Enqueueing Block skript og stiler

For å legge til JavaScript og CSS som kreves av våre blokker, kan vi bruke to nye WordPress kroker levert av Gutenberg:

  • enqueue_block_editor_assets
  • enqueue_block_assets

Disse er bare tilgjengelige hvis Gutenberg-plugin er aktiv, og de fungerer på samme måte som vanlige WordPress-kroker for enqueueing-skript. Imidlertid er de beregnet spesielt for å jobbe med Gutenberg-blokkene.

De enqueue_block_editor_assets krok legger til skript og stiler bare til admin editoren. Dette gjør det ideelt for enqueueing JavaScript for å registrere blokker og CSS til stil brukergrensesnittelementer for blokkinnstillinger.

For blokkutgang, vil du imidlertid at blokkene dine skal gjøre det samme i editoren som de gjør på frontenden mesteparten av tiden. Ved hjelp av enqueue_block_assets gjør det enkelt når stiler automatisk legges til både redaktør og frontend. Du kan også bruke denne kroken for å laste inn JavaScript, hvis nødvendig.

Men du lurer kanskje på hvordan du skal skrive og skrive på skript og stiler bare på forsiden. Det er ikke en WordPress-krok for å tillate deg å gjøre dette direkte, men du kan komme rundt dette ved å legge til en betinget uttalelse inne i enqueue_block_assets hook tilbakeringingsfunksjon.

add_action ('enqueue_block_assets', 'load_front_end skript'); funksjon load_front_end scripts () if (! is_admin () // enqueue front end bare skript og stiler her

For å faktisk skape skript og stiler ved hjelp av disse to nye krokene, kan du bruke standarden wp_enqueue_style () og wp_enqueue_scripts () Fungerer som du normalt ville.

Men du må sørge for at du bruker de riktige skriptavhengighetene. For enqueueing-skript på redaktøren kan du bruke følgende avhengigheter:

  • skript: array ('wp-blokker', 'wp-i18n', 'wp-element', 'wp-komponenter')
  • stiler: array ('wp-edit-blocks')

Og når enqueueing stiler for både redaktør og frontend, kan du bruke denne avhengigheten:

  • array ('wp-blokker')

En ting verdt å nevne her er at de faktiske filene enqueued av vår my-custom-blokk plugin er kompilert versjoner av JavaScript og CSS og ikke filene som inneholder JSX og Sass kildekoden.

Dette er bare noe å huske på når du manuelt skriver inn filer. Hvis du prøver å enqueue kildekoden som inneholder React, ES6 + eller Sass, vil du møte mange feil.

Dette er grunnen til at det er nyttig å bruke et verktøy som f.eks lag-guten-blokk som det behandler og enqueues skript for deg automatisk!

Registrering av Gutenberg Blocks

For å opprette en ny blokk, må vi registrere det hos Gutenberg ved å ringe registerBlockType () og passerer i blokknavnet pluss et konfigurasjonsobjekt. Dette objektet har ganske mange egenskaper som krever riktig forklaring.

For det første, la oss ta en titt på blokknavnet. Dette er den første parameteren og er en streng bestående av to deler, et navneområde og blokknavnet i seg selv, adskilt av et fremadstrekkstrekk.

For eksempel:

registerBlockType ('blokknavn / blokknavn', // konfigurasjonsobjekt);

Hvis du registrerer flere blokker i et plugin, kan du bruke det samme navneområdet for å organisere alle blokkene dine. Navneområdet må imidlertid være unikt for pluginet ditt, som bidrar til å forhindre navngivning av konflikter. Dette kan skje hvis en blokk med samme navn allerede er registrert via et annet plugin.

Den andre registerBlockType () parameteren er en innstillingsobjekt og krever at en rekke egenskaper skal angis:

  • tittel (streng): vises i redigeringsprogrammet som den søkbare blokkemerken
  • beskrivelse (valgfri streng): beskriver formålet med en blokk
  • ikon (valgfritt Dashicon eller JSX element): ikon knyttet til en blokk
  • kategori (streng): hvor blokken vises i Legg til blokker dialog
  • søkeord (valgfritt array): opptil tre søkeord brukt i blokk søk
  • egenskaper (valgfritt objekt): håndterer dynamiske blokkdata
  • redigere (funksjon): en funksjon som returnerer markering som skal gjengis i redigereren
  • lagre (funksjon): en funksjon som returnerer markering som skal gjengis på frontenden
  • useOnce (valgfri boolesk): begrense blokk fra å bli lagt til mer enn en gang
  • støtter (valgfritt objekt): definerer blokkstøttede funksjoner

Forutsatt at vi bruker JSX for blokkutvikling, er det et eksempel registerBlockType () samtale kan se ut som en veldig enkel blokk:

registerBlockType ('my-unique-namespace / ultimate-block', title: __ ('Den beste blokk noensinne', 'domene'), ikon: 'wordpress', kategori: 'felles', nøkkelord: [__ ',' domene '), __ (' Gutenberg ',' domene '), __ (' blokk ',' domene ')] 

Velkommen til Gutenberg-redaktøren!

, lagre: () =>

Hvordan ser jeg på forsiden?

);

Legg merke til hvordan vi ikke inkluderte en oppføring for beskrivelse, egenskaper, useOnce, og støtter eiendommer? Eventuelle felt som er valgfrie (og ikke relevante for blokken din) kan utelukkes trygt. For eksempel, da denne blokken ikke innebar noen dynamiske data, trenger vi ikke å bekymre oss for å angi noen attributter.

La oss nå dekke registerBlockType () konfigurasjonsobjektegenskaper mer detaljert en etter en.

Tittel og beskrivelse

Når du setter inn eller søker etter en blokk i redigeringsprogrammet, vises tittelen i listen over tilgjengelige blokker.

Den vises også i blokkinspeksjonsvinduet, sammen med blokkbeskrivelsen hvis den er definert. Hvis blokkinspektøren ikke er synlig for øyeblikket, kan du bruke tannhjulikonet øverst til høyre i Gutenberg-editoren for å bytte synlighet.


Både tittel- og beskrivelsesfeltene skal ideelt sett pakkes inn i i18n-funksjoner for å tillate oversettelse til andre språk.

Kategori

Det er fem blokker for tiden tilgjengelig:

  • felles
  • formatering
  • oppsett
  • widgets
  • embed

Disse bestemmer kategoriseksjonen der blokken din er oppført i Legg til blokk vindu.


De blokker fanen inneholder Vanlige blokker, formatering, Layoutelementer, og widgets kategorier, mens innbygging kategorien har sin egen kategori.

Kategorier er for tiden fastsatt i Gutenberg, men dette kan bli endret i fremtiden. Dette ville være nyttig for eksempel hvis du utviklet flere blokker i en enkelt plugin, og du ville at alle skulle bli oppført under en felles kategori, slik at brukerne kunne finne dem lettere.

Ikon

Blokken din er som standard tildelt skjermdashikonet, men du kan overstyre dette ved å angi en egendefinert Dashicon i ikon felt.


Hver Dashicon er prefiks med dashicons- etterfulgt av en unik streng. For eksempel har tannhjulikonet navnet dashicons-admin-generisk. For å bruke dette som et blokkikon, fjern bare dashicons- prefiks for at det skal gjenkjennes, f.eks. ikon: 'admin-generisk'.

Du er imidlertid ikke bare begrenset til å bruke Dashicons som ikonegenskapen. Funksjonen aksepterer også et JSX-element, noe som betyr at du kan bruke et hvilket som helst bilde eller SVG-element som blokkikonet ditt. 

Bare vær sikker på at du holder ikonstørrelsen i samsvar med andre blokkikoner, som er 20 x 20 piksler som standard.

nøkkelord

Velg opptil tre oversetterbare søkeord for å få blokkene dine til å skille seg ut når brukerne søker etter en blokk. Det er best å velge søkeord som har nær tilknytning til funksjonaliteten til blokken din for å få de beste resultatene.

søkeord: [__ ('søk', 'domene'), __ ('for', 'domene'), __ ('meg', 'domene')]

Du kan til og med erklære firmaet ditt og / eller pluginnavnet som søkeord, slik at hvis du har flere blokker, kan brukerne begynne å skrive firmaets navn og alle blokkene dine vil vises i søkeresultatene.

Selv om du legger til søkeord, er det helt valgfritt, det er en fin måte å gjøre det lettere for brukerne å finne blokkene dine.

Egenskaper

Attributter hjelper med å administrere dynamiske data i en blokk. Denne egenskapen er valgfri fordi du ikke trenger den for svært enkle blokker som utfører statisk innhold.

Men hvis blokken din behandler data som kan endres (for eksempel innholdet i et redigerbart tekstområde) eller du må lagre blokkinnstillinger, er det å bruke attributter å gå. 

Attributter fungerer ved å lagre dynamiske blokkdata enten i innleggets innhold lagret i databasen eller i postmeta. I denne opplæringen bruker vi bare attributter som lagrer data sammen med innleggets innhold.

For å hente attributtdata lagret i innleggsinnhold, må vi spesifisere hvor det ligger i oppmerkningen. Vi kan gjøre dette ved å spesifisere en CSSvelger som peker på attributtdataene.

For eksempel, hvis vår blokk inneholdt en anker-tag, kan vi bruke den tittel Felt som vårt attributt som følger:

attributter: linktitle: kilde: 'attributt', velg: 'a', attributt: 'tittel'

Her er attributtnavnet linktitle, som er en vilkårlig streng og kan være alt du liker.

For eksempel kan vi bruke dette attributtet til å lagre linketittelen  Det er blitt lagt inn via en tekstboks i blokkinnstillinger. Å gjøre det plutselig gjør tittelfeltet dynamisk og lar deg endre verdien i editoren.

Når posten er lagret, blir attributtverdien satt inn i koblingene tittel felt. På samme måte, når redigereren er lastet, verdien av tittel tag hentes fra innholdet og settes inn i linktitle Egenskap.

Det er flere måter du kan bruke kilde for å bestemme hvordan blokkinnhold lagres eller hentes via attributter. For eksempel kan du bruke 'tekst' kilde for å trekke ut den indre teksten fra et avsnittelement.

attributter: avsnitt: kilde: 'tekst', velg: 'p'

Du kan også bruke barn kilde for å trekke ut alle barnnoder av et element i en matrise og lagre det i et attributt.

attributter: editablecontent: source: 'children', selector: '.parent'

Dette velger elementet med klassen .forelder og lagrer alle barnnoder i editablecontent Egenskap.

Hvis du ikke angir en kilde, blir attributtverdien lagret i HTML-kommentarer som en del av postmarkeringen når den lagres i databasen. Disse kommentarene fjernes før innlegget blir gjengitt på forsiden.

Vi ser et bestemt eksempel på denne typen attributt når vi kommer inn på å implementere vår tilfeldige bildeblokk senere i denne opplæringen.

Attributter kan ta litt å bli vant til, så ikke bekymre deg hvis du ikke forstår dem helt første gang. Jeg vil anbefale å se på attributter-delen av Gutenberg-håndboken for flere detaljer og eksempler.

Redigere

De redigere funksjonen styrer hvordan blokken din vises i redigeringsgrensesnittet. Dynamiske data sendes til hver blokk som Rekvisitter, inkludert eventuelle egendefinerte attributter som er definert.

Det er vanlig å legge til className = props.className til hovedblokkelementet for å utføre en CSS-klasse spesifikk for blokken din. WordPress legger ikke til dette for deg inne i editoren, så det må legges manuelt for hver blokk hvis du vil inkludere det.

Ved hjelp av props.className er standard praksis og anbefales fordi det gir en måte å skreddersy CSS stiler for hver enkelt blokk. Formatet av den genererte CSS-klassen er .wp-blokk- navnerom - name. Som du kan se, er dette basert på blokknavn / -navn og gjør det ideelt å bli brukt som en unik blokkidentifikator.

Redigeringsfunksjonen krever at du returnerer gyldig markering via render () metode, som deretter brukes til å gjøre blokken din inne i editoren.

Lagre

Ligner på redigere funksjon, lagre viser en visuell fremstilling av blokken din, men på forsiden. Den mottar også dynamiske blokkdata (hvis definert) via rekvisitter.

En viktig forskjell er det props.className er ikke tilgjengelig på innsiden lagre, men dette er ikke et problem fordi det er satt inn automatisk av Gutenberg.

støtter

De støtter eiendom aksepterer et objekt med boolske verdier for å avgjøre om blokken din støtter visse kjernefunksjoner.

De tilgjengelige objektegenskapene du kan angi, er som følger.

  • anker (standard false): lar deg koble direkte til en bestemt blokk
  • customClassName (sant): legger til et felt i blokkinspektøren for å definere en egendefinert klassenavn for blokken 
  • klassenavn (sant): legger til a klassenavn til blokkrotelementet basert på blokknavnet
  • html (sant): gjør at blokkoppretting kan redigeres direkte

De useOnce Eiendom

Dette er en nyttig egenskap som lar deg begrense en blokk fra å bli lagt til mer enn en gang til en side. Et eksempel på dette er kjernen Mer blokk, som ikke kan legges til en side hvis den allerede er til stede.


Som du kan se, en gang Mer blokk er lagt til, blokkikonet er gråtonet og kan ikke velges. De useOnce eiendommen er satt til falsk som standard.

La oss bli kreative!

Det er på tide å bruke kunnskapen vi har oppnådd så langt for å implementere et solidt fungerende eksempel på en blokk som gjør noe mer interessant enn bare å utføre statisk innhold.

Vi lager en blokk for å utføre et tilfeldig bilde oppnådd via en ekstern forespørsel til PlaceIMG-nettstedet, som returnerer et tilfeldig bilde. Videre kan du velge kategorien bilde som returneres via en velg rullegardinkontroll.


For enkelhets skyld legger vi til vår nye blokk til det samme my-custom-blokk plugin, i stedet for å lage et helt nytt plugin. Koden for standardblokken er plassert inne i / Src / blokk mappe, så legg til en annen mappe inne / src kalt random-bilde og legg til tre nye filer:

  • index.js: Registrerer vår nye blokk
  • editor.scss: For editor stiler
  • style.scss: Stiler for redaktør og frontend

Alternativt kan du kopiere / Src / blokk mappe og endre navn på det hvis du ikke vil skrive alt ut for hånd. Pass på at du endrer navn block.js til index.js inne i den nye blokkmappen.

Vi bruker index.js for hovedblokken filnavn som dette tillater oss å forenkle import uttalelsen inni blocks.js. I stedet for å måtte inkludere stien og hele filnavnet til blokken, kan vi bare spesifisere banen til blokkmappen, og importere vil automatisk se etter en index.js fil.

Åpne opp /src/blocks.js og legg til en referanse til vår nye blokk øverst i filen, rett under den eksisterende importoppstillingen.

importere './random-image';

Innsiden /src/random-image/index.js, legg til følgende kode for å starte vår nye blokk.

// Import CSS. importere './style.scss'; importer './editor.scss'; const __ = wp.i18n; const registerBlockType, query = wp.blocks; registerBlockType ('cgb / blokk-tilfeldig bilde', title: __ ('Tilfeldig bilde'), ikon: 'format-image', kategori: 'felles', nøkkelord: [__ ('random'), __ bilde ')], rediger: funksjon (rekvisitter) retur ( 

Tilfeldig bildeblokk (redaktør)

); , lagre: funksjon (rekvisitter) retur (

Tilfeldig bildeblokk (frontend)

); );

Dette setter opp rammen av vår blokk og er ganske lik den boilerplate blokkkode generert av lag-guten-blokk verktøykasse.

Vi begynner med å importere redigeringsarkitekten og front-end stilark, og så trekker vi ut noen vanlige funksjoner fra wp.i18n og wp.blocks inn i lokale variabler.

Innsiden registerBlockType (), verdier er angitt for tittel, ikon, kategori, og søkeord egenskaper, mens redigere og lagre Funksjoner som for øyeblikket bare utfører statisk innhold.

Legg til tilfeldig bildeblokk til en ny side for å se produksjonen som er generert hittil.


Sørg for at du fremdeles ser på filer for endringer, slik at noen blokkkildekode (JSX, ES6 +, Sass, etc.) blir transpulert til gyldig JavaScript og CSS. Hvis du for øyeblikket ikke ser filer for endringer, åpner du et kommandolinjevindu inni my-custom-blokk Plugg inn rotmappe og skriv inn npm start.

Du lurer kanskje på hvorfor vi ikke behøvde legge til noen PHP-kode for å kreve flere blokkskript. Blokkskriptene for my-custom-blokk blokkering er innregnet via init.php, men vi trenger ikke å enqueue skript spesielt for vår nye blokk som dette er tatt vare på for oss av lag-guten-blokk.

Så lenge vi importerer vår hovedblokkfil i src / blocks.js (som vi gjorde over), trenger vi ikke å gjøre noe ekstra arbeid. Alle JSX, ES6 + og Sass-koden vil automatisk bli kompilert i følgende filer:

  • dist / blocks.style.build.css: Stiler for redaktør og frontend
  • Dist / blocks.build.js: JavaScript bare for redaktør
  • dist / blocks.editor.build.css: Stiler for editor bare

Disse filene inneholder JavaScript og CSS for alle blokkene, så det er bare et sett med filer som skal regnes, uavhengig av antall blokker som er opprettet!

Vi er nå klare til å legge til litt interaktivitet i blokken vår, og vi kan gjøre dette ved først å legge til et attributt for å lagre bildekategorien.

attributter: kategori: type: 'streng', standard: 'natur'

Dette skaper et attributt som heter kategori, som lagrer en streng med en standardverdi på 'natur'. Vi angav ikke en plassering i markeringen for å lagre og hente attributtverdien, så spesielle HTML-kommentarer vil bli brukt i stedet. Dette er standardoppførselen hvis du unnlater en attributtkilde.

Vi trenger en måte å endre bildekategorien på, som vi kan gjøre via en velg rullegardinkontroll. Oppdater redigere funksjon til følgende:

rediger: funksjon (rekvisitter) const attributter: category, setAttributes = = rekvisitter; funksjon setCategory (event) const selected = event.target.querySelector ('option: checked'); setAttributes (category: selected.value); event.preventDefault ();  komme tilbake ( 
Nåværende kategori er: category
);

Her er hvordan det vil se ut:

Dette er ganske forskjellig fra den forrige statiske redigere funksjon, så la oss gå gjennom endringene.

Først har vi lagt til en velg rullegardinkontroll med flere valg som passer til bildekategorier som er tilgjengelige på PlaceIMG-siden.


Når rullegardinmenyen endres, vil setCategory funksjonen heter, som finner den aktuelt valgte kategorien og deretter igjen kalles setAttributes funksjon. Dette er en kjerne Gutenberg-funksjon og oppdaterer en attributtverdi på riktig måte. Det anbefales at du bare oppdaterer et attributt ved hjelp av denne funksjonen.

Nå, når en ny kategori er valgt, oppdateres attributtverdien og sendes tilbake til redigere funksjon, som oppdaterer utgående meldingen.


Vi må fullføre ett siste skritt for å få tilfeldig bilde å vise. Vi må opprette en enkel komponent som vil ta i gjeldende kategori og sende ut en tag med et tilfeldig bilde hentet fra PlaceIMG nettstedet.

Forespørselen vi må gjøre til PlaceIMG er av skjemaet: https://placeimg.com/[width]/[height]/[category]

Vi beholder bredden og høyden for nå, så vi må bare legge til den nåværende kategorien på slutten av forespørselsadressen. For eksempel, hvis kategorien var 'natur' så vil hele forespørselsadressen være: https://placeimg.com/320/220/nature.

Legg til en RandomImage komponent over registerBlockType ():

funksjonen RandomImage (category) const src = 'https://placeimg.com/320/220/' + category; komme tilbake category; 

For å bruke det, legg det bare til i redigeringsfunksjonen og fjern den statiske utgangsmeldingen. Mens vi er i det, gjør det samme for lagringsfunksjonen.

Den fulle index.js filen skal nå se slik ut:

// Import CSS. importere './style.scss'; importer './editor.scss'; const __ = wp.i18n; const registerBlockType, query = wp.blocks; funksjonen RandomImage (category) const src = 'https://placeimg.com/320/220/' + category; komme tilbake category;  registerBlockType ('cgb / blokk-tilfeldig bilde', title: __ ('Tilfeldig bilde'), ikon: 'format-image', kategori: 'vanlig', nøkkelord: [__ ('tilfeldig'), __ 'kategori')], attributter: kategori: type: 'streng', standard: 'natur', rediger: funksjon (rekvisitter) const attributter: category, setAttributes = rekvisitter; ) const selected = event.target.querySelector ('option: checked'); setAttributes (category: selected.value); event.preventDefault (); returnere 
); , lagre: funksjon (rekvisitter) const attributter: category = rekvisitter; komme tilbake (
); );

Til slutt (for nå), legg til følgende stiler til editor.scss å legge til en farget ramme rundt bildet.

.wp-block-cgb-blokk-tilfeldig bilde select padding: 2px; margin: 7px 0 5px 2px; border-radius: 3px; 

Du trenger også noen stiler i style.css.

 .wp-blokk-cgb-blokk-tilfeldig bilde bakgrunn: # f3e88e; farge: #fff; grense: 2px solid # ead9a6; border-radius: 10px; polstring: 5px; bredde: -webkit-fit-innhold; bredde: -moz-fit-innhold; Bredde: Fit-Content; img border-radius: arv; grense: 1px prikket # caac69; skjerm: grid; 

Når siden oppdateres i redigeringsprogrammet eller på forsiden, vises et nytt tilfeldig bilde. 

Hvis du ser det samme bildet som vises om og om igjen, kan du gjøre en hard oppdatering for å forhindre at bildet blir servert fra nettleserens cache.

Konklusjon

I denne opplæringen har vi dekket ganske mye grunnlag. Hvis du har gjort det hele veien gjennom, gi deg selv en velfortjent klapp på ryggen! Gutenberg blokk utvikling kan være mye moro, men det er definitivt utfordrende å forstå hvert konsept ved første eksponering.

Underveis har vi lært hvordan vi skal legge til blokkeringsskript og stiler og dekket registerBlockType () fungere i dybden.

Vi fulgte opp dette ved å sette teorien i praksis og skape en tilpasset blokk fra grunnen til å vise et tilfeldig bilde fra en bestemt kategori ved hjelp av PlaceIMG webtjenesten.

I neste og siste del av denne opplæringsserien legger vi til flere funksjoner i vår tilfeldige bildeblokk via innstillingspanelet i blokkinspektøren.

Hvis du har fulgt med denne opplæringen og bare vil eksperimentere med koden uten å skrive alt inn, kan du laste ned den endelige my-custom-blokk plugin i neste opplæring.