Många klagar på att det är svårt att komma igång med att bygga Gutenbergblock och appar. Inlärningskurvan är brant, främst på grund av svårigheten att installera och konfigurera utvecklingsmiljön. Gedigna kunskaper i JavaScript, Node.js, React och Redux är dessutom nödvändiga ingredienser för detta ganska komplexa recept.

Den officiella Handboken för WordPress Blockredigerare ger utvecklare en enorm mängd information, men det kan hända att du går vilse i detta hav av detaljer.

Och det är värt att nämna vad Matías Ventura, ansvarig arkitekt för Gutenberg-projektet, rapporterade i sin intervju med WP Tavern:

Även om det finns folk som kan lära sig detta snabbt så är det fortfarande ett stort hinder för många. Jag tror att det finns flera lager av detta; dokumentationen skulle kunna vara en nivå bättre både när det gäller organisation och presentation. Jag hoppas att vi kan göra mycket mer där.

Med detta i åtanke så har vi beslutat att tillhandahålla en steg för steg-handledning som syftar till att hjälpa våra läsare att komma igång med utvecklingen av Gutenberg-block.

Låter det intressant? Låt oss köra igång!

Förutsättningar för utveckling av Gutenbergblock

De enda färdigheter som krävs för den här handledningen är goda kunskaper om utveckling av WordPress-plugins och åtminstone en grundläggande förståelse för HTML, CSS, JavaScript och React.

Blir det här ett ambitiöst projekt? Det kan du räkna med att det blir!

Det var inte lätt att hitta den rätta kompromissen mellan fullständighet och enkelhet eller att bestämma vilka ämnen som skulle inkluderas och vilka som skulle utelämnas.

Förhoppningsvis så blir vi förlåtna av medelkunniga- och avancerade läsare för att vi inte fördjupar oss i vissa begrepp som React state, Redux store, high order components och så vidare. Dessa ämnen kräver ytterligare utrymme och uppmärksamhet och är förmodligen för avancerade för att börja utveckla block (om du inte är React-utvecklare).

Av samma anledning så kommer vi inte heller att gå igenom några av de mer avancerade ämnena som rör Gutenbergs blockutveckling, exempelvis dynamiska block och metarutor.

Med den kunskap som du får i slutet av den här artikeln så kan du börja att ha roligt och vara produktiv direkt.

När du väl kommit igång med blockbyggandet så kommer du att vara redo att förbättra dina kunskaper ytterligare och bygga ännu mer avancerade Gutenbergblock på egen hand.

Vad är ett Gutenbergblock?

Sedan den först släpptes i december år 2018 så har blockredigeraren förbättrats avsevärt i alla aspekter: kraftfullare API: er, ett mer avancerat användargränssnitt, förbättrad användbarhet, massor av nya block, de första implementeringarna av Full Site Editing och mycket mer.

Kort sagt, även om Gutenberg fortfarande är under stark utveckling så har den kommit långt – och idag är blockredigeraren en fullfjädrad kandidat som en pålitlig och funktionell sid- och webbplatsbyggare.

Ur en utvecklares synvinkel så är Gutenberg en React-baserad Single Page Application (SPA) som gör det möjligt för WordPress-användare att skapa, redigera och radera innehåll i WordPress. Detta är dock inte en förbättrad version av den traditionella innehållsredigeraren.

Vi vill göra detta klart och tydligt:

I Gutenberg så delas innehållet in i block, som är ”tegelstenar” som användarna kan använda för att skapa inlägg och sidor eller hela webbplatser.

Men vad är egentligen ett block?

Vi gillar WordPress definition:

”Block” är den abstrakta term som används för att beskriva enheter av markeringar som tillsammans bildar innehållet eller layouten på en webbsida. Idén kombinerar koncept av det som vi uppnår i WordPress idag med kortkoder, anpassad HTML och inbäddning till ett enda konsekvent API och en enhetlig användarupplevelse.

Titlar, stycken, kolumner, bilder, gallerier och alla element som utgör redigeringsgränssnittet, från sidofältspaneler till blockverktygsfältet, är React-komponenter.

Så vad är React-komponenter? W3Schools ger följande definition:

Komponenter är oberoende och återanvändbara kodbitar. De tjänar samma syfte som JavaScript-funktioner, men arbetar isolerat och returnerar HTML via en render() -funktion.

Arbeta med Gutenberg-block i WordPress 5.8.
Arbeta med Gutenberg-block i WordPress 5.8.

Även om redigeringsupplevelsen som levereras av Gutenberg är ny jämfört med den klassiska WordPress-redigeraren, så ändras inte WordPress sätt att lagra dina innehållsdelar i databasen överhuvudtaget. Detta beror på att Gutenberg är en applikation som fungerar i WordPress men som inte ändrar CMS: ets sätt att fungera i grunden.

Inlägg (och detta inkluderar inlägg, sidor och anpassade inläggstyper) som skapas med Gutenberg lagras fortfarande i tabellen wp_posts, precis som med den klassiska redigeraren.

Men i ett inlägg som har skapats med Gutenberg så hittar du ytterligare bitar av information i tabellen. Den representerar en grundläggande skillnad mellan inlägg som har skapats via den klassiska redigeraren kontra Gutenberg.

Dessa informationsbitar ser ut som HTML-kommentarer och har en specifik funktion: att avgränsa block:

Ett blogginlägg i kodredigeringsvyn.
Ett blogginlägg i kodredigeringsvyn.

Blockavgränsare talar om för WordPress vilket block som ska återges på skärmen. De ger även värden för blockegenskaper i ett JSON-objekt. Denna rekvisita dikterar hur blocket ska återges på skärmen:

Ett blogginlägg som lagras i tabellen wp_posts.
Ett blogginlägg som lagras i tabellen wp_posts.

Inställning av din WordPress-utvecklingsmiljö

För att inrätta en modern JavaScript-utvecklingsmiljö så krävs det gedigna kunskaper om avancerad teknik som Webpack, React och JSX, Babel, ESLint osv.

Är du avskräckt? Var inte det! WordPress-communityt har redan kommit till undsättning genom att tillhandahålla kraftfulla verktyg som låter dig undvika en rörig manuell konfigurationsprocess.

För att hålla saker och ting enkla så kommer vi inte att gå igenom transpiling i den här artikeln (vilket vi ändå rekommenderar att du bekantar dig med när du har lärt dig grunderna i blockutveckling). Vi kommer istället att presentera två alternativa verktyg som du kan använda för att snabbt och enkelt sätta upp en modern JavaScript-utvecklingsmiljö på några minuter. Det är upp till dig att välja det som du finner mest praktiskt för ditt projekt.

Att sätta upp en JavaScript-utvecklingsmiljö för att bygga Gutenbergblock är en process i tre steg:

  1. Installera Node.js och npm
  2. Ställ in utvecklingsmiljön
  3. Ställ in blockpluginet

Nu sätter vi igång.

1. Installera Node.js och npm

Innan du installerar din utvecklingsmiljö och registrerar ditt första block så måste du installera Node.js och Node-pakethanteraren (npm).

Du kan installera Node.js och npmflera olika sätt. Men först så bör du kanske kontrollera om programvaran redan är installerad på din maskin.

För att göra detta så startar du terminalen och kör följande kommando:

node -v

Om resultatet är command not found så är Node.js inte installerat på din dator och du kan fortsätta med installationen.

I den här artikeln så har vi valt det enklaste installationsalternativet, vilket är Node Installer. Allt som du behöver göra är att ladda ner den version som motsvarar ditt operativsystem och starta installationsguiden:

Sidan för nedladdningar av Node.js.
Sidan för nedladdningar av Node.js.

När du har installerat Node.js så kör du kommandot node -v i din terminal igen. Du kan även köra kommandot npm -v för att bekräfta att du har npm-paketet tillgängligt.

Du är nu utrustad med följande verktyg:

  • Paketköraren npx Node.js (se dokumentationen). Detta gör att du kan köra ett npm -kommando utan att installera det först.
  • Node.js-pakethanteraren npm Node.js (se dokumentation). Detta används för att installera beroenden och köra skript.

Nästa steg är att installera utvecklingsmiljön.

2. Installera din utvecklingsmiljö

När du har de senaste versionerna av Node.js och npm på din lokala maskin så behöver du en utvecklingsmiljö för WordPress.

Du kan antingen använda en lokal utvecklingsmiljö som DevKinsta eller använda det officiella WordPress-verktyget. Låt oss ta en titt på båda alternativen.

Alternativ 1: Lokal utvecklingsmiljö (DevKinsta)

Med endast några få klick så kan du installera WordPress lokalt med DevKinsta, vårt moderna lokala WordPress-utvecklingsverktyg. Du kan även välja ett annat lokalt utvecklingsverktyg, till exempel MAMP eller XAMPP:

Skapa en ny WordPress-webbplats i DevKinsta.
Skapa en ny WordPress-webbplats i DevKinsta.

Alternativ 2: wp-env

Du kan även välja det officiella verktygetwp-env , som ger en lokal WordPress-utvecklingsmiljö som du kan starta direkt från kommandoraden. Noah Alen definierar detta på följande sätt:

Att skapa lokala WordPress-miljöer är nu lika enkelt som att köra ett enda kommando. wp-env är ett verktyg med nollkonfiguration för smärtfria lokala WordPress-miljöer. Det gör att användare kan starta WordPress snabbt och smidigt utan att slösa tid. Målet är faktiskt att göra dessa miljöer lättillgängliga för alla – oavsett om du är utvecklare, designer, chef eller något annat.

Om du bestämmer dig för att ge det ett försök så kräver installationen av wp-env en minimal ansträngning. Följ bara dessa steg:

Steg 1: Bekräfta installationen av Docker och Node.js

För att uppfylla de tekniska kraven så måste du först ha både Docker och Node.js installerade på din dator. Detta beror på att wp-env skapar en Docker-instans som kör en WordPress-webbplats. Alla ändringar som görs i koden återspeglas omedelbart i WordPress-instansen.

Steg 2: Installera @wordpress/env från kommandoraden

När Docker och Node.js körs på din dator så kan du gå vidare och installera WordPress-utvecklingsmiljön.

Du kan antingen installera wp-env globalt eller lokalt. För att göra det globalt så måste du köra följande kommando från plugins-katalogen (mer om detta i rutan ”Viktigt” nedan):

npm install -g @wordpress/env

Låt oss dela upp detta:

För att bekräfta att wp-env har installerats framgångsrikt, kör följande kommando:

wp-env --version

Du bör se den aktuella versionen av wp-env, vilket innebär att du nu kan starta miljön med följande kommando från din pluginmodulmapp:

wp-env start

Du kan komma åt WordPress instrumentpanel med följande adress:

  • http://localhost:8888/wp-admin/

Standardinloggningsuppgifterna är följande:

  • Användarnamn: admin
  • Lösenord: password

Ställ in ditt blockplugin

Nu behöver du ett startblockplugin att bygga vidare på. Men i stället för att manuellt skapa ett utvecklingsblockplugin med alla nödvändiga filer och mappar så kan du helt enkelt köra ett utvecklingsverktyg som tillhandahåller alla filer och konfigurationer som du behöver för att komma igång med blockutvecklingen.

Du har återigen ett par alternativ att välja mellan. Låt oss ta en titt på vart och ett av dessa.

Alternativ 1: Konfigurera en blockplugin med @wordpress/create-block

@wordpress/create-block är det officiella nollkonfigurationsverktyget för att skapa Gutenbergblock:

Create Block är ett officiellt sätt för skapandet av block och för att registrera ett block för ett WordPress-plugin. Det erbjuder en modern bygguppsättning utan konfiguration. Verktyget genererar PHP-, JS- och CSS-kod och allt annat som du behöver för att starta projektet.

Det är till stor del inspirerat av create-react-app. Stort tack till @gaearon, hela Facebook-teamet och React-communityt.

När din lokala miljö är igång så kan du sätta upp ett startblock genom att helt enkelt köra kommandot npx @wordpress/create-block.Detta kommer att tillhandahålla alla filer och mappar som du behöver för att skapa plugin-ställningar och registrera ett nytt block.

Låt oss köra ett test för att se hur det fungerar.

Från ditt kommandoradsverktyg så navigerar du till katalogen /wp-content/plugins/ och kör följande kommando:

npx @wordpress/create-block my-first-block

När du blir ombedd att bekräfta så skriver du y för att fortsätta:

Skapa ett block med @wordpress/create-block.
Skapa ett block med @wordpress/create-block.

Processen tar några ögonblick. När den är klar så bör du få följande svar:

Blockpluginet har skapats.
Blockpluginet har skapats.

Och det var allt!

Starta nu din WordPress-utvecklingsmiljö och gå till skärmen Plugins i WordPress-instrumentpanelen. Ett nytt plugin som heter ”My First Block” borde ha lagts till i din pluginlista:

Blockpluginet har installerats framgångsrikt.
Blockpluginet har installerats framgångsrikt.

Aktivera pluginet om det behövs, skapa ett nytt blogginlägg, scrolla ner i blockpluginet till avsnittet Widgets och välj ditt nya block:

Ett exempelblock som är skapat med @wordpress/create-block.
Ett exempelblock som är skapat med @wordpress/create-block.

Gå nu tillbaka till terminalen och ändra den aktuella katalogen till my-first-block:

cd my-first-block

Kör sedan följande kommando:

npm start

Detta gör att du kan köra pluginet i utvecklingsläge. För att skapa produktionskoden så ska du använda följande kommando:

npm run build

Alternativ 2: Konfigurera ett blockplugin med create-guten-block

create-guten-block är ett utvecklingsverktyg från tredje part för att bygga Gutenbergblock:

create-guten-block är ett utvecklingsverktygs-kit med nollkonfiguration (#0CJS) för att utveckla WordPress Gutenbergblock på några minuter utan att konfigurera React, webpack, ES6/7/8/Next, ESLint, Babel osv.

Precis som det officiella verktyget create-block så är create-guten-block baserat på create-react-app och kan hjälpa dig att skapa ditt första blockplugin utan problem.

Verktygslådan inkluderar allt som du behöver för att skapa ett modernt WordPress-plugin, inklusive följande:

  • React, JSX och ES6 syntaxstöd.
  • Webpack dev/produktionsbyggnadsprocess under huven.
  • Språkliga extrafunktioner utöver ES6 som objektspridningsoperatorn.
  • CSS med automatisk prefixering så att du inte behöver -webkit eller andra prefix.
  • Ett byggskript för att paketera JS, CSS och bilder för produktion med källkortsmappning.
  • Problemfria uppdateringar för ovanstående verktyg med ett enda beroende cgb-script.

Observera följande varning:

Motprestationen är att dessa verktyg är förkonfigurerade för att fungera på ett visst sätt. Om ditt projekt behöver mer anpassning så kan du ”kasta dig ut” och anpassa det, men då måste du upprätthålla denna konfiguration.

När du har en lokal WordPress-webbplats till hands så startar du ditt kommandoradsverktyg, navigerar till mappen /wp-content/plugins i din installation och kör följande kommando:

npx create-guten-block my-first-block

Du måste vänta en minut eller två medan projektstrukturen skapas och beroenden hämtas:

Skapa ett Gutenberg-block med create-guten-block.
Skapa ett Gutenberg-block med create-guten-block.

När processen är klar så bör du se följande skärm:

Gutenberg-blocket har skapats med create-guten-block.
Gutenberg-blocket har skapats med create-guten-block.

Nästa bild visar projektstrukturen när terminalen körs i Visual Studio Code:

Blockplugin i Visual Studio Code.
Blockplugin i Visual Studio Code.

Gå nu tillbaka till din WordPress-instrumentpanel. Ett nytt objekt bör listas i skärmen Plugins – det är pluginet my-first-block:

Skärmen Plugins med ett nytt plugin som har skapats med create-guten-block.
Skärmen Plugins med ett nytt plugin som har skapats med create-guten-block.

Aktivera pluginet och gå tillbaka till terminalen. Ändra den aktuella katalogen till my-first-block och kör sedan npm start:

cd my-first-block
npm start

Du bör få följande svar:

npm har startat
npm har startat

Återigen så gör detta att du kan köra pluginet i utvecklingsläge. För att skapa produktionskoden så bör du använda:

npm run build

Aktivera pluginet och skapa ett nytt inlägg eller en ny sida, bläddra sedan bland dina block och välj ditt helt nya Gutenberg-block:

Ett nytt block som har skapats med create-guten-block.
Ett nytt block som har skapats med create-guten-block.

Om du vill ha en mer ingående översikt eller om du har gjort fel så kan du läsa dokumentationen från Ahmad Awais.

En genomgång av startblockets byggnadsställning

Oavsett vilket av de två utvecklingsverktygen – create-block eller create-guten-block – som du väljer så har du nu en blockställning som du kan använda som utgångspunkt för att bygga ett blockplugin.
Men vad är egentligen en blockställning?

Blockställningar är en kortfattad term som beskriver den stödjande katalogstruktur som du behöver för att WordPress ska känna igen ett block. Den katalogen innehåller vanligtvis filer som index.php, index.js, style.css och andra – som i sin tur innehåller anrop som register_block_type.

Vi valde det officiella utvecklingsverktyget Create Block, eftersom det används i Handboken för Blockredigeraren. Men även om du väljer att använda ett tredjepartsverktyg som create-guten-block, så kommer din upplevelse inte att vara alltför annorlunda.
Med detta sagt, låt oss dyka djupare in i verktygetcreate-block.

En närmare titt på utvecklingsverktyget Create Block

Som vi nämnde ovan så är Create Block det officiella kommandoradsverktyget för att skapa Gutenbergblock. Genom att köra @wordpress/create-block i din terminal så genereras de PHP-, JS- och SCSS-filer och den kod som behövs för att registrera en ny blocktyp:

npx @wordpress/create-block [options] [slug]
  • [slug] (valfritt) – används för att tilldela blockets slug och installera pluginet.
  • [options] (valfritt) – tillgängliga alternativ

Som standard så tilldelas en ESNext-mall. Det innebär att du får nästa version av JavaScript med tillägget JSX-syntaxen.

Om du utelämnar blocknamnet så körs kommandot i interaktivt läge, så att du kan anpassa flera alternativ innan filerna genereras:

npx @wordpress/create-block
Kör Create Block i interaktivt läge
Kör Create Block i interaktivt läge

Bilden nedan visar filstrukturen för ett blockinsticksprogram som skapats med det officiella verktyget Create Block:

Filer och mappar i ett blockinsticksprogram som skapats med @wordpress/create-block.
Filer och mappar i ett blockinsticksprogram som skapats med @wordpress/create-block.

Med detta sagt, låt oss gå igenom de viktigaste filerna och mapparna i vårt nya blockplugin.

Pluginfilen

Med den huvudsakliga pluginfilen så registrerar du blocket på servern:

<?php
/**
 * Plugin Name:       Kinsta Academy Block
 * Plugin URI:        https://kinsta.com/
 * Description:       An example block for Kinsta Academy students
 * Requires at least: 5.9
 * Requires PHP:      7.0
 * Version:           0.1.0
 * Author:            Kinsta Students
 * License:           GPL-2.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain:       ka-example-block
 *
 * @package           ka-example-block
 */

/**
 * Registers the block using the metadata loaded from the `block.json` file.
 * Behind the scenes, it registers also all assets so they can be enqueued
 * through the block editor in the corresponding context.
 *
 * @see https://developer.wordpress.org/reference/functions/register_block_type/
 */
function ka_example_block_ka_example_block_block_init() {
	register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'ka_example_block_ka_example_block_block_init' );

Funktionen register_block_type registrerar en blocktyp på servern med hjälp av metadata som lagras i filen block.json.

Funktionen tar emot två parametrar:

  • Blocktypens namn inklusive namnområde, eller en sökväg till mappen där filen block.json finns, eller ett komplett WP_Block_Type -objekt.
  • En matris med blocktypargument.

I koden ovan så returnerar den magiska konstanten __DIR__ den aktuella mappen. Detta innebär att filen block.json finns i undermappen /build.

Filen package.json

I filen package.json definieras JavaScript-egenskaper och skript för ditt projekt. Det är här som du kan installera dina projektberoenden.

För att bättre förstå vad den här filen är avsedd för så öppnar du den med din favoritkodredigerare:

{
	"name": "ka-example-block",
	"version": "0.1.0",
	"description": "An example block for Kinsta Academy students",
	"author": "Kinsta Students",
	"license": "GPL-2.0-or-later",
	"homepage": "https://kinsta.com/",
	"main": "build/index.js",
	"scripts": {
		"build": "wp-scripts build",
		"format": "wp-scripts format",
		"lint:css": "wp-scripts lint-style",
		"lint:js": "wp-scripts lint-js",
		"packages-update": "wp-scripts packages-update",
		"plugin-zip": "wp-scripts plugin-zip",
		"start": "wp-scripts start"
	},
	"devDependencies": {
		"@wordpress/scripts": "^24.1.0"
	},
	"dependencies": {
		"classnames": "^2.3.2"
	}
}

Egenskapen scripts är en ordbok som inkluderar kommandon som körs vid olika tidpunkter under ett pakets livscykel med hjälp av npm run [cmd].

I den här artikeln så kommer vi att använda följande kommandon:

  • npm run build — Skapa en (komprimerad) produktionsuppbyggnad.
  • npm run start eller npm start — skapar en (okomprimerad) utvecklingsbyggnad.

dependencies och devDependencies är två objekt som mappar ett paketnamn till en version. dependencies krävs i produktionen, medan devDependences endast behövs för lokal utveckling (läs mer).

Det enda standardutvecklingsberoendet är paketet @wordpress/scripts, som definieras som ”en samling återanvändbara skript som är skräddarsydda för WordPress-utveckling”.

Filen block.json

Från och med WordPress 5.8 så är metadatafilen block.json det kanoniska sättet att registrera blocktyper.

Att ha en block.json-fil ger flera fördelar, bland annat förbättrad prestanda och bättre synlighet i WordPress Pluginkatalog:

Ur ett prestandaperspektiv, när teman har stöd för lata laddningar av tillgångar, så kommer block som registreras med block.json att få sin tillgångskö optimerad från början. De CSS- och JavaScript-tillgångar som anges i egenskaperna style eller script kommer endast att köas när blocket finns på sidan, vilket leder till minskade sidstorlekar.

Om du kör kommandot @wordpress/create-block så genereras följande block.json-fil:

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 2,
	"name": "ka-example-block/ka-example-block",
	"version": "0.1.0",
	"title": "Kinsta Academy Block",
	"category": "widgets",
	"icon": "superhero-alt",
	"description": "An example block for Kinsta Academy students",
	"supports": {
		"html": false
	},
	"textdomain": "ka-example-block",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css"
}

Här är den fullständiga listan över standardegenskaper:

  • apiVersion – Den version av API: et som används av blocket (nuvarande version är 2).
  • name – En unik identifierare för ett block, inklusive ett namnområde.
  • version – Den aktuella versionen av ett block.
  • title – En visningstitel för ett block.
  • category – En blockkategori.
  • icon – En Dashicon-slug eller en egen SVG-ikon.
  • description – En kort beskrivning som är synlig i blockinspektören.
  • supports – En uppsättning alternativ för att styra funktioner som används i redigeraren.
  • textdomain – pluginets textdomän
  • editorScript – definition av redigerar-skriptet
  • editorStyle – Definition av redigeringsstil.
  • style – ger alternativa stilar för ett block.

Förutom de egenskaper som anges ovan så kan du (och kommer förmodligen att) definiera ett attributes -objekt som innehåller information om data som lagras i blocket. I din block.json så kan du ställa in valfritt antal attribut i nyckel/värde-par, där nyckeln är attributnamnet och värdet är attributdefinitionen.

Ta en titt på följande exempel på attributdefinitioner:

"attributes": {
	"content": {
		"type": "array",
		"source": "children",
		"selector": "p"
	},
	"align": {
		"type": "string",
		"default": "none"
	},
	"link": { 
		"type": "string", 
		"default": "https://kinsta.com" 
	}
},

Vi kommer att gå djupare in på block.json-filen senare i artikeln, men du kan även läsa Handboken för Blockredigeraren för mer detaljerad information om metadata och attribut i block.json.

Mappen src

Det är i mappen src som utvecklingen sker. I den mappen så hittar du följande filer:

  • index.js
  • redigera.js
  • spara.js
  • editor.scss
  • style.scss

index.js

Filen index.js är din utgångspunkt. Här importerar du beroenden och registrerar blocktypen på klienten:

import { registerBlockType } from '@wordpress/blocks';

import './style.scss';

import Edit from './edit';
import save from './save';
import metadata from './block.json';

registerBlockType( metadata.name, {
	/**
	 * @see ./edit.js
	 */
	edit: Edit,

	/**
	 * @see ./save.js
	 */
	save,
} );

Det första påståendet importerar funktionen registerBlockType från paketet @wordpress/blocks. De följande importförklaringarna importerar formatmallen tillsammans med funktionerna Edit och save samt ett metadataobjekt från filen block.json.

Funktionen registerBlockType registrerar komponenten på klienten. Funktionen tar emot två parametrar: ett blocknamn och ett objekt för blockkonfiguration.

Funktionen Edit tillhandahåller blockgränssnittet som det återges i blockredigeraren, medan funktionen save tillhandahåller den struktur som kommer att serialiseras och sparas i databasen (läs mer).

edit.js

I edit.js byggs blockadministrationsgränssnittet:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';

export default function Edit() {
	return (
		<p {...useBlockProps()}>
			{__('My First Block – hello from the editor!', 'my-first-block')}
		</p>
	);
}

Först så importeras funktionen __ från paketet @wordpress/i18n (detta paket inkluderar en JavaScript-version av översättningsfunktionerna), funktionen useBlockProps React hook och filen editor.scss.

Därefter så exporteras React-komponenten (läs mer om import– och exportförklaringar).

save.js

I filen save.js så bygger vi upp blockstrukturen som ska sparas i databasen:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';

export default function save() {
	return (
		<p {...useBlockProps.save()}>
			{__(
				'My First Block – hello from the saved content!',
				'my-first-block'
			)}
		</p>
	);
}

editor.scss och style.scss

Förutom skripten så finns det två SASS-filer i src-mapparna. Filen editor.scss innehåller de stilar som tillämpas på blocket i redigerarkontexten, medan filen style.scss inkluderar blockets stilar för visning i frontend såväl som i redigeraren. Vi kommer att dyka djupare in i dessa filer i den andra delen av den här guiden.

Mapparna node_modules och build

Mappen node_modules innehåller node-moduler och deras beroenden. Vi kommer inte att dyka djupare ner i node-paket eftersom det ligger utanför ramen för den här artikeln, men du kan läsa mer i den här artikeln om var npm installerar paketen.

Mappen build innehåller JS- och CSS-filer som är resultatet av byggprocessen. Du kan fördjupa dig i byggprocessen i guiderna ESNext syntax och JavaScript Build Setup.

Projektet: Bygg ditt första Gutenberg-block

Det är dags att skita ner händerna litegrann. Det här avsnittet kommer att lära dig hur du skapar ett plugin som tillhandahåller ett CTA-block med namnet Kinsta Academy Block.

Blocket kommer att bestå av två kolumner, med en bild till vänster och ett textavsnitt till höger. En knapp med en anpassningsbar länk kommer att placeras under texten:

Blocktypen som du kommer att lära dig att bygga i den här guiden.
Blocktypen som du kommer att lära dig att bygga i den här guiden.

Det här är bara ett enkelt exempel, men det gör att vi kan täcka grunderna för utveckling av Gutenbergblock. När du har fått en tydlig förståelse för grunderna så kan du gå vidare och skapa mer och mer komplexa Gutenbergblock med hjälp av Handboken för Blockredigeraren och alla andra av de stora resurser som finns tillgängliga där ute.

Om du antar att du har igång den senaste versionen av WordPress i din lokala utvecklingsmiljö, så är det här vad du kommer att lära dig från och med nu:

Redo… klart… inställt… igång!

Så här ställer du in startblockpluginet

Starta ditt kommandoradsverktyg och navigera till mappen /wp-content/plugins:

Ny terminal i mappen i Mac OS.
Ny terminal i mappen i Mac OS.

Kör nu följande kommando:

npx @wordpress/create-block

Det här kommandot genererar PHP-, SCSS- och JS-filer för att registrera ett block i interaktivt läge, så att du enkelt kan lägga till de nödvändiga uppgifterna för ditt block. I vårt exempel så använder vi följande uppgifter:

  • Mallvariant: statisk
  • Blockets namn: ka-example-block
  • Internt namnområde: ka-example-block
  • Blockets visningstitel: Kinsta Academy Block
  • Kort blockbeskrivning: Ett exempelblock för Kinsta Academy-studenter
  • Dashicon: superhero-alt
  • Kategorinamn: widgets
  • Vill du anpassa WordPress-pluginet?: ja
  • Pluginets hemsida: https://kinsta.com/
  • Nuvarande version av pluginet: 0.1.0
  • Författare till pluginet: ditt namn
  • Licens: –
  • Länk till licenstexten: –
  • Anpassad domänväg för översättningar: –

 

Det tar några minuter att installera pluginet och alla beroenden. När processen är klar så får du följande svar:

Exempelblocket har installerats och registrerats för utveckling.
Exempelblocket har installerats och registrerats för utveckling.

Kör nu följande kommando från mappen /wp-content/plugins:

cd ka-example-block
Körning av kommandon från Visual Studio Code Terminal.
Körning av kommandon från Visual Studio Code Terminal.

Slutligen så kan du starta utvecklingen från din plugin-mapp (ka-example-block i vårt exempel) med:

npm start

Öppna nu skärmen Plugins för att hitta och aktivera Kinsta Academy Block-pluginet:

Aktivera exempelblocket
Aktivera exempelblocket

Skapa ett nytt inlägg, öppna blockinsatsen och bläddra ner till kategorin Design. Klicka för att lägga till Kinsta Academy-blocket:

Ett startblock som är byggt med @wordpress/create-block.
Ett startblock som är byggt med @wordpress/create-block.

block.json på jobbet

Som vi nämnde tidigare så sker blockregistreringen på serversidan i huvudfilen .php. Vi kommer dock inte att definiera inställningar i .php-filen. Vi kommer istället att använda filen block.json.
Så öppna block.json igen och titta närmare på standardinställningarna:

{
"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 2,
	"name": "ka-example-block/ka-example-block",
	"version": "0.1.0",
	"title": "Kinsta Academy Block",
	"category": "widgets",
	"icon": "superhero-alt",
	"description": "An example block for Kinsta Academy students",
	"supports": {
		"html": false
	},
	"textdomain": "ka-example-block",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css"
}

 

Skript och stilar

editorScript-egenskaperna Skript och stilar, editorStyle och style anger de relativa sökvägarna till skript och stilar för frontend och backend.
Du behöver inte registrera de skript och stilar som definieras här manuellt eftersom de registreras och köas automatiskt av WordPress. För att bevisa detta så startar du webbläsarinspektorn och öppnar fliken Nätverk:

Inspektion av resurser i Chrome DevTools.
Inspektion av resurser i Chrome DevTools.

Som du kan se på bilden ovan så har vårt index.js-skript som finns i byggmappen regelbundet ställts in i kö utan att det har krävts någon PHP-kod.

UI-etiketter

Egenskaperna title och description ger de etiketter som krävs för att identifiera blocket i redigeraren:

Blockets namn och beskrivning i blockets sidofält.
Blockets namn och beskrivning i blockets sidofält.

Nyckelord

Som vi nämnde tidigare så kan du konfigurera dina blockinställningar noggrant med hjälp av egenskaper och attribut. Du kan exempelvis lägga till en eller flera keywords för att hjälpa användarna att söka efter block:

"keywords": [ 
"kinsta", 
		"academy", 
		"superhero" 
	],

Om du nu anger ”kinsta”, ”academy” eller ”superhero” i snabbinfogaren så kommer redigeraren att föreslå Kinsta Academy-blocket:

Söka efter ett block med hjälp av ett nyckelord i snabbinfogaren.
Söka efter ett block med hjälp av ett nyckelord i snabbinfogaren.

Lokalisering

Om du undrar hur lokaliseringen av strängarna i JSON-filen går till så kommer svaret här:

I JavaScript så kan du använda metoden registerBlockTypeFromMetadata från paketet @wordpress/blocks för att registrera en blocktyp med hjälp av metadata som laddas från filen block.json. Alla lokaliserade egenskaper blir automatiskt förpackade i _x (från @wordpress/i18n -paketet)-funktionsanropet på samma sätt som det fungerar i PHP med register_block_type_from_metadata. Det enda kravet är att ställa in egenskapen textdomain i filen block.json.

Här använder vi funktionen registerBlockType i stället för registerBlockTypeFromMetadata, eftersom den senare har blivit överspelad sedan Gutenberg 10.7, men mekanismen är densamma.

Användning av inbyggda komponenter: RichText-komponenten

De element som ingår i ett Gutenberg-block är React-komponenter, och du kan komma åt dessa komponenter via den globala variabeln wp. Försök exempelvis att skriva wp.editor i webbläsarens konsol. Då får du en fullständig lista över de komponenter som ingår i modulen wp.editor.
Bläddra igenom listan och gissa vad komponenterna är avsedda för utifrån deras namn.
På samma sätt kan du kontrollera listan över de komponenter som ingår i modulen wp.components:

WP-komponenter
WP-komponenter

.

Gå nu tillbaka till filen edit.js och titta närmare på skriptet:

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';

export default function Edit() {
return (
		<p { ...useBlockProps() }>
			{ __(
				'Kinsta Academy Block – hello from the editor!',
				'ka-example-block'
			) }
		</p>
	);
}

Den här koden genererar ett statiskt block med enkel, icke-redigerbar text. Men vi kan enkelt ändra saker och ting:

Startblocket i kodredigeraren.
Startblocket i kodredigeraren.

För att göra texten redigerbar måste du ersätta den nuvarande <p> -taggen med en komponent som gör det inmatade innehållet redigerbart. För detta tillhandahåller Gutenberg den inbyggda RichText-komponenten.

Att lägga till en inbyggd komponent i ditt block är en process i fem steg:

  1. Importera de nödvändiga komponenterna från ett WordPress-paket
  2. Inkludera motsvarande element i din JSX-kod.
  3. Definiera de nödvändiga attributen i filen block.json.
  4. Definiera händelsehanterare.
  5. Spara data

Steg 1: Importera de nödvändiga komponenterna från ett WordPress-paket

Öppna nu filen edit.js och ändra följande import -angivelse:

import { useBlockProps } from '@wordpress/block-editor';

…till:

import { useBlockProps, RichText } from '@wordpress/block-editor';

På detta sätt importerar du funktionen useBlockProps och komponenten RichText från paketet @wordpress/block-editor.

useBlockProps

useBlockProps React hook markerar blockets omslagselement:

När du använder API version 2 måste du använda den nya useBlockProps -kroken i blockets edit -funktion för att markera blockets omslagselement. Haken infogar de attribut och händelsestyrare som behövs för att aktivera blockets beteende. Alla attribut som du vill skicka till blockelementet måste skickas via useBlockProps och det returnerade värdet måste spridas till elementet.

Enkelt uttryckt tilldelar useBlockProps automatiskt attribut och klasser till omslagselementet ( p -elementet i vårt exempel):

Element och klasser som genereras av useBlockProps.
Element och klasser som genereras av useBlockProps.

Om du tar bort useBlockProps från omslagselementet har du en enkel textsträng utan tillgång till blockfunktionalitet och stil:

Samma block utan useBlockProps.
Samma block utan useBlockProps.

Som vi förklarar senare kan du också skicka ett objekt med egenskaper till useBlockProps för att anpassa utmatningen.

RichText

RichText-komponenten ger en innehållsanpassad ingång, vilket gör att användarna kan redigera och formatera innehållet.

Du hittar komponenten dokumenterad på GitHub på gutenberg/packages/block-editor/src/components/rich-text/README.md.

Steg 2: Inkludera motsvarande element i din JSX-kod

...

const blockProps = useBlockProps();

return (
	<RichText 
		{ ...blockProps }
		tagName="p"
		onChange={ onChangeContent }
		allowedFormats={ [ 'core/bold', 'core/italic' ] }
		value={ attributes.content }
		placeholder={ __( 'Write your text...' ) }
	/>
);

Låt oss kommentera koden rad för rad:

  • tagName — Taggenamnet för det redigerbara HTML-elementet.
  • onChange — Funktion som anropas när elementets innehåll ändras.
  • allowedFormats — En matris med tillåtna format. Som standard är alla format tillåtna.
  • value — Den HTML-sträng som ska göras redigerbar.
  • placeholder — Platshållartext som ska visas när elementet är tomt.

Steg 3: Definiera de nödvändiga attributen i filen block.json

Attribut ger information om de data som lagras av ett block, t.ex. rikt innehåll, bakgrundsfärg, URL:er osv.

Du kan ställa in ett godtyckligt antal attribut i ett attributes -objekt i nyckel/värdepar, där nyckeln är attributnamnet och värdet är attributdefinitionen.

Öppna nu filen block.json och lägg till följande attributes -prop:

"attributes": {
	"content": {
		"type": "string",
		"source": "html",
		"selector": "p"
	}
},

Med attributet content kan man lagra den text som användaren skriver i det redigerbara fältet:

  • type anger vilken typ av data som lagras i attributet. Typ krävs om du inte definierar en egenskap enum.
  • source definierar hur attributvärdet extraheras från inläggets innehåll. I vårt exempel är det HTML-innehållet. Observera att om du inte anger en egenskap för källan lagras data i blockavgränsaren (läs mer).
  • selector är en HTML-tagg eller någon annan selektor, t.ex. ett klassnamn eller ett id-attribut.

Vi skickar ett objekt med egenskaper till funktionen Edit. Gå tillbaka till filen edit.js och gör följande ändring:

export default function Edit( { attributes, setAttributes } ) { ... }

Steg 4: Definiera händelsehanterare

Elementet RichText har ett onChange -attribut som ger en funktion som ska anropas när elementets innehåll ändras.

Låt oss definiera denna funktion och se hela edit.js-scriptet:

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';
import './editor.scss';

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();

	const onChangeContent = ( newContent ) => {
		setAttributes( { content: newContent } )
	}

	return (
		<RichText 
			{ ...blockProps }
			tagName="p"
			onChange={ onChangeContent }
			allowedFormats={ [ 'core/bold', 'core/italic' ] }
			value={ attributes.content }
			placeholder={ __( 'Write your text...' ) }
		/>
	);
}

Spara nu filen och gå tillbaka till din WordPress-instrumentpanel, skapa ett nytt inlägg eller en ny sida och lägg till ditt anpassade block:

Utmatningen av RichText-komponenten i Block Editor.

Lägg till lite text och växla till kodvyn. Så här bör din kod se ut:

<!-- wp:ka-example-block/ka-example-block -->
<p class="wp-block-ka-example-block-ka-example-block">Kinsta Academy Block – hello from the saved content!</p>
<!-- /wp:ka-example-block/ka-example-block -->

Som du kan se har innehållet i ditt block ändrats om du byter till kodredigeraren. Det beror på att du måste ändra filen save.js för att lagra användarinmatningen i databasen när inlägget sparas.

Steg 5: Spara data

Öppna nu filen save.js och ändra skriptet enligt följande:

import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ attributes.content } 
		/>
	);
}

Det är vad vi gör här:

  • Importera komponenten RichText från paketet block-editor.
  • Skicka flera egenskaper via ett objektargument till funktionen save (i det här exemplet skickar vi bara egenskapenattributes).
  • Återge innehållet i komponenten RichText.
Blockets innehåll har sparats i databasen
Blockets innehåll har sparats i databasen

Du kan läsa mer om komponenten RichText i Handboken för Blockredigeraren och hitta den fullständiga listan över props på Github.

Nu ska vi ta det ett steg längre. I nästa avsnitt så lär du dig hur du lägger till kontroller i blockverktygsfältet.

Lägga till kontroller till Blockverktygsfältet

Blockverktygsfältet innehåller en uppsättning kontroller som gör det möjligt för användare att manipulera delar av blockinnehållet. För varje kontroll i verktygsfältet så finns det en komponent:

Det centrala verktygsfältet för block.
Det centrala verktygsfältet för block.

Du kan exempelvis lägga till en kontroll för textjustering för ditt block. Allt som du behöver göra är att importera två komponenter från paketet @wordpress/block-editor.

Vi går igenom samma steg som i det föregående exemplet:

  1. Importera nödvändiga komponenter från WordPress-paket
  2. Inkludera motsvarande element i din JSX-kod
  3. Definiera de nödvändiga attributen i filen block.json
  4. Definiera händelsehanterare
  5. Spara data

Steg 1: Importera komponenterna BlockControls och AlignmentControl från @wordpress/block-editor

För att lägga till en justeringskontroll i verktygsfältet för block så behöver du två komponenter:

  • BlockControls visar ett dynamiskt verktygsfält med kontroller (odokumenterat).
  • AlignmentControl Renderar en rullgardinsmeny som visar justeringsalternativ för det valda blocket (läs mer).

Öppna filen edit.js och redigera import -angivelsen enligt nedan:

import { 
	useBlockProps, 
	RichText, 
	AlignmentControl, 
	BlockControls 
} from '@wordpress/block-editor';

Steg 2: Lägg till BlockControls och AlignmentControl-element

Gå till funktionen Edit och infoga elementet <BlockControls /> på samma nivå som <RichText />. Lägg sedan till <AlignmentControl /> inom <BlockControls />:

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();
	return (
		<>
			<BlockControls>
				<AlignmentControl
					value={ attributes.align }
					onChange={ onChangeAlign }
				/>
			</BlockControls>
			<RichText 
				{ ...blockProps }
				tagName="p"
				onChange={ onChangeContent }
				allowedFormats={ [ 'core/bold', 'core/italic' ] }
				value={ attributes.content }
				placeholder={ __( 'Write your text...' ) }
				style={ { textAlign: attributes.align } }
			/>
		</>
	);
}

I koden ovan är <> och </> den korta syntaxen för att deklarera React-fragment, vilket är hur vi returnerar flera element i React.

I det här exemplet så har AlignmentControl två attribut:

  • value ger det aktuella värdet för elementet
  • onChange tillhandahåller en händelsehanterare som ska köras när värdet ändras

Vi har även definierat ytterligare attribut för elementet RichText (se hela listan över attribut med exempel).

Steg 3: Definiera attributet align i block.json

Gå nu till filen block.json och lägg till attributet align:

"align": {
	"type": "string",
	"default": "none"
}

När du är klar så går du tillbaka till blockredigeraren, uppdaterar sidan och väljer blocket. Du bör se ett felmeddelande i blocket.

Blocket visar ett felmeddelande
Blocket visar ett felmeddelande

Orsaken är att vi ännu inte har definierat vår händelsehanterare.

Steg 4: Definiera händelsehanteraren

Definiera nu onChangeAlign:

const onChangeAlign = ( newAlign ) => {
	setAttributes( { 
		align: newAlign === undefined ? 'none' : newAlign, 
	} )
}

Om newAlign är undefined, så ställer vi in newAlign till none. Annars så använder vi newAlign.

Vårt edit.js-skript borde vara färdigt (för tillfället):

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();
	const onChangeContent = ( newContent ) => {
		setAttributes( { content: newContent } )
	}
	const onChangeAlign = ( newAlign ) => {
		setAttributes( { 
			align: newAlign === undefined ? 'none' : newAlign, 
		} )
	}
	return (
		<>
			<BlockControls>
				<AlignmentControl
					value={ attributes.align }
					onChange={ onChangeAlign }
				/>
			</BlockControls>
			<RichText 
				{ ...blockProps }
				tagName="p"
				onChange={ onChangeContent }
				allowedFormats={ [ 'core/bold', 'core/italic' ] }
				value={ attributes.content }
				placeholder={ __( 'Write your text...' ) }
				style={ { textAlign: attributes.align } }
			/>
		</>
	);
}

Nu kan du gå tillbaka till redigeraren och anpassa blockets innehåll. Ditt block bör nu stolt visa ett verktygsfält för justering.

Vårt block har nu ett verktygsfält för justering
Vårt block har nu ett verktygsfält för justering

Men om du sparar inlägget så kommer du att se att innehållet i ditt block inte är justerat på frontend som det är i blockredigeraren. Detta beror på att vi måste ändra funktionen save för att lagra blockets innehåll och attribut i databasen.

Steg 5: Spara data

Öppna save.js och ändra funktionen save på följande sätt:

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ attributes.content } 
			style={ { textAlign: attributes.align } }
		/>
	);
}

För att göra koden mer lättläst så kan du slutligen extrahera de enskilda egenskaperna från attribute -objektet med hjälp av syntaxen för destructuring assignment:

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	const { content, align } = attributes;
	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ content } 
			style={ { textAlign: align } }
		/>
	);
}

Du kan göra samma sak i filen edit.js.

Spara nu filen och växla till kodredigeraren. Blockkoden bör se ut ungefär så här:

<!-- wp:ka-example-block/ka-example-block {"align":"right"} -->
<p class="wp-block-ka-example-block-ka-example-block" style="text-align:right">This is my first editable <strong>Gutenberg</strong> <em>block</em> 😎</p>
<!-- /wp:ka-example-block/ka-example-block -->
Kontroll av blockets verktygsfält
Kontroll av blockets verktygsfält

Nu är det klart! Du har just lagt till en justeringskontroll i blockets verktygsfält 🤓.

Du kan läsa mer om kontroller i verktygsfältet för block i Handboken för Blockredigeraren.

Anpassa sidofältet för blockinställningar

Du kan även lägga till kontroller till blockets inställningssidofält (eller till och med skapa ett nytt sidofält för din applikation).

API tillhandahåller en InspectorControls -komponent för detta.

I Handboken för Blockredigeraren förklaras det hur du använder Inställningssidofältet:

Inställningssidofältet används för att visa inställningar som används mindre ofta eller inställningar som kräver mer skärmutrymme. Inställningssidofältet bör endast användas för inställningar på blocknivå.

Om du har inställningar som endast påverkar valt innehåll i ett block (t.ex. inställningen ”fet” för vald text i ett stycke): placera den inte i Inställningssidofältet. Detta sidofält visas även när du redigerar ett block i HTML-läge, så det bör endast innehålla inställningar på blocknivå.

Återigen:

  1. Importera nödvändiga komponenter från WordPress-paket
  2. Inkludera motsvarande element i din JSX-kod
  3. Definiera de nödvändiga attributen i filen block.json
  4. Definiera händelsehanterare
  5. Spara data

Steg 1. Importera komponenterna InspectorControls och PanelColorSettings från @wordpress/block-editor

Du kan lägga till flera kontroller så att användarna kan anpassa specifika aspekter av blocket. Du kan exempelvis tillhandahålla en färgkontrollpanel. För att göra detta så måste du importera komponenterna InspectorControls och PanelColorSettings från modulen block-editor:

import { 
	useBlockProps, 
	RichText, 
	AlignmentControl, 
	BlockControls,
	InspectorControls,
	PanelColorSettings
} from '@wordpress/block-editor';

Steg 2: Inkludera motsvarande element i din JSX-kod

Nu kan du lägga till motsvarande element i den JSX som returneras av funktionen Edit:

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();

	const { content, align, backgroundColor, textColor } = attributes;

	const onChangeContent = ( newContent ) => {
		setAttributes( { content: newContent } )
	}
	const onChangeAlign = ( newAlign ) => {
		setAttributes( { 
			align: newAlign === undefined ? 'none' : newAlign, 
		} )
	}
	return (
		<>
			<InspectorControls>
				<PanelColorSettings 
					title={ __( 'Color settings', 'ka-example-block' ) }
					initialOpen={ false }
					colorSettings={ [
						{
						  value: textColor,
						  onChange: onChangeTextColor,
						  label: __( 'Text color', 'ka-example-block' )
						},
						{
						  value: backgroundColor,
						  onChange: onChangeBackgroundColor,
						  label: __( 'Background color', 'ka-example-block' )
						}
					] }
				/>
			</InspectorControls>
			<BlockControls>
				<AlignmentControl
					value={ align }
					onChange={ onChangeAlign }
				/>
			</BlockControls>
			<RichText 
				{ ...blockProps }
				tagName="p"
				onChange={ onChangeContent }
				allowedFormats={ [ 'core/bold', 'core/italic' ] }
				value={ content }
				placeholder={ __( 'Write your text...' ) }
				style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
			/>
		</>
	);
}

Observera att vi även har uppdaterat attributet style i elementet RichText:

<RichText 
	 { ...blockProps }
	 tagName="p"
	 onChange={ onChangeContent }
	 allowedFormats={ [ 'core/bold', 'core/italic' ] }
	 value={ content }
	 placeholder={ __( 'Write your text...' ) }
	 style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
/>

Steg 3: Definiera de nödvändiga attributen i block.json

Definiera nu attributen backgroundColor och textColor i filen block.json:

"attributes": {
	"content": {
		"type": "string",
		"source": "html",
		"selector": "p"
	},
	"align": {
		"type": "string",
		"default": "none"
	},
	"backgroundColor": {
		"type": "string"
	},	 
	"textColor": {
		"type": "string"
	}
},

Steg 4: Definiera händelsehanterare

Nu måste du definiera två funktioner för att uppdatera backgroundColor och textColor vid användarinmatning:

const onChangeBackgroundColor = ( newBackgroundColor ) => {
	setAttributes( { backgroundColor: newBackgroundColor } )
}

const onChangeTextColor = ( newTextColor ) => {
	setAttributes( { textColor: newTextColor } )
}

Steg 5: Spara data

Ett sista steg: Öppna filen save.js och ändra skriptet på följande sätt:

export default function save( { attributes } ) {
	const blockProps = useBlockProps.save();
	const { content, align, backgroundColor, textColor } = attributes;
	return (
		<RichText.Content 
			{ ...blockProps } 
			tagName="p" 
			value={ content } 
			style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
		/>
	);
}

Spara filen och kontrollera blocket i redigeraren. Du kanske hittar en ovälkommen överraskning: ett felmeddelande som talar om att blocket innehåller oväntat eller ogiltigt innehåll.

Felmeddelande om oväntat eller ogiltigt innehåll
Felmeddelande om oväntat eller ogiltigt innehåll

Detta sker eftersom filen save.js ändras och den kod som sparas i databasen inte stämmer överens med den kod som används i redigeraren.

För att åtgärda detta så uppdaterar du sidan, tar bort alla exempel på ditt block och lägger till det igen i ditt inlägg:

Panelen för färginställningar i sidofältet för blockinställningar
Panelen för färginställningar i sidofältet för blockinställningar

Gör dina ändringar, spara inlägget och visa det på frontend. Nu bör de ändringar som du har gjort i blockredigeraren återspeglas på frontend.

Det anpassade blocket fungerar nu korrekt på frontend
Det anpassade blocket fungerar nu korrekt på frontend

I det här avsnittet så lägger du till nya komponenter till din blocktyp:

  • En ExternalLink -komponent som gör det möjligt för användare att lägga till en anpassningsbar länk till ditt anpassade block.
  • Flera kontroller i sidofältet som gör det möjligt för användare att anpassa länkinställningarna.

Steg 1. Importera komponenter från @wordpress/components

Nu måste du importera flera komponenter från @wordpress/components. Öppna din edit.js-fil och lägg till följande import -meddelande:

import {
	TextControl,
	PanelBody,
	PanelRow,
	ToggleControl,
	ExternalLink
} from '@wordpress/components';
  • PanelBody lägger till en ihopfällbar container till inställningssidofältet.
  • PaneRow Producerar en generisk container för sidobarkontroller.
  • TextControl ger en textinmatningskontroll.
  • ToggleControl ger en växel som gör det möjligt för användare att aktivera/avaktivera ett visst alternativ.
  • ExternalLink är en enkel komponent för att lägga till en extern länk.

Steg 2. Inkludera motsvarande element i din JSX-kod

Först så lägger du till ExternalLink -elementet på samma nivå som RichText i en div -container:

<div { ...blockProps }>
	<RichText 
		...
	/>
	<ExternalLink 
		href={ kaLink }
		className="ka-button"
		rel={ hasLinkNofollow ? "nofollow" : "" }
	>
			{ linkLabel }
	</ExternalLink>

</div>

Komponenten ExternalLink är inte dokumenterad, så vi hänvisar till själva komponenten för att få en lista över tillgängliga attribut. Här så använder vi attributen href, className och rel.

Som standard så är värdet för attributet rel inställt på noopener noreferrer. Vår kod kommer att lägga till nyckelordetnofollow till attributet rel i den resulterande a -taggen när växelkontrollen är aktiverad.

Nu kan du lägga till länkinställningar i blockets sidofält.

Först så lägger du till ett PanelBody -element inuti InspectorControls på samma nivå som PanelColorSettings:

<InspectorControls>
	<PanelColorSettings 
	...
	/>
	<PanelBody 
		title={ __( 'Link Settings' )}
		initialOpen={true}
	>
	...
	</PanelBody>
</InspectorControls>

Så här gör vi med detta:

  1. Attributet title anger panelens titel.
  2. initialOpen anger om panelen är öppen från början eller inte.

Därefter så lägger vi till två PanelRow -element i PanelBody och ett TextControl -element i varje PanelRow:

<PanelBody 
	title={ __( 'Link Settings', 'ka-example-block' )}
	initialOpen={true}
>
	<PanelRow>
		<fieldset>
			<TextControl
				label={__( 'KA link', 'ka-example-block' )}
				value={ kaLink }
				onChange={ onChangeKaLink }
				help={ __( 'Add your Academy link', 'ka-example-block' )}
			/>
		</fieldset>
	</PanelRow>
	<PanelRow>
		<fieldset>
			<TextControl
				label={__( 'Link label', 'ka-example-block' )}
				value={ linkLabel }
				onChange={ onChangeLinkLabel }
				help={ __( 'Add link label', 'ka-example-block' )}
			/>
		</fieldset>
	</PanelRow>
</PanelBody>

Koden ovan bör nu se ganska enkel ut. De två textkontrollerna gör det möjligt för användaren att ställa in länketikett och webbadress.

Vi lägger även till ytterligare en PanelRow med ToggleControl för att slå på/av ett visst alternativ, t.ex. om ett attribut ska inkluderas eller inte:

<PanelRow>
	<fieldset>
		<ToggleControl
			label="Add rel = nofollow"
			help={
				hasLinkNofollow
					? 'Has rel nofollow.'
					: 'No rel nofollow.'
			}
			checked={ hasLinkNofollow }
			onChange={ toggleNofollow }
		/>
	</fieldset>
</PanelRow>

Steg 3: Definiera de nödvändiga attributen i block.json

Definiera nu attributen kaLink, linkLabel och hasLinkNofollow i filen block.json:

"kaLink": {
	"type": "string",
	"default": ""
},
"linkLabel": {
	"type": "string",
	"default": "Check it out!"
},
"hasLinkNofollow": {
	"type": "boolean",
	"default": false
}

Inget mer att tillägga här! Låt oss gå vidare till att definiera funktionerna för hantering av händelser.

Steg 4: Definiera Funktionerna för hantering av händelser

Gå tillbaka till filen edit.js, lägg till de nya attributen till attributobjektet och lägg till följande funktioner:

const { content, align, backgroundColor, textColor, kaLink, linkLabel, hasLinkNofollow } = attributes;

const onChangeKaLink = ( newKaLink ) => {
	setAttributes( { kaLink: newKaLink === undefined ? '' : newKaLink } )
}

const onChangeLinkLabel = ( newLinkLabel ) => {
	setAttributes( { linkLabel: newLinkLabel === undefined ? '' : newLinkLabel } )
}

const toggleNofollow = () => {
	setAttributes( { hasLinkNofollow: ! hasLinkNofollow } )
}

Dessa funktioner uppdaterar motsvarande attributvärden vid användarinmatning.

Steg 5: Spara data

Till sist så måste vi uppdatera funktionen save i save.js:

export default function save( { attributes } ) {
	
	const { content, align, backgroundColor, textColor, kaLink, linkLabel, hasLinkNofollow } = attributes;

	const blockProps = useBlockProps.save( {
		className: `has-text-align-${ align }`
	} );
	
	return (
		<div 
			{ ...blockProps }
			style={ { backgroundColor: backgroundColor } }
		>
			<RichText.Content 
				tagName="p" 
				value={ content } 
				style={ { color: textColor } }
			/>
			<p>
				<a 
					href={ kaLink }
					className="ka-button"
					rel={ hasLinkNofollow ? "nofollow" : "noopener noreferrer" }
				>
					{ linkLabel }
				</a>
			</p>
		</div>
	);
}

Observera att vi här har använt ett vanligt a -element i stället för ExternalLink.

Du kan se resultatet i bilden nedan.

Panelen för länkinställningar i sidofältet för blockinställningar
Panelen för länkinställningar i sidofältet för blockinställningar

Lägga till flera blockstyper

I ett tidigare avsnitt så lärde du dig hur du lägger till en blockverktygsbalkskontroll som gör det möjligt för användare att justera användarinmatningen. Vi kan lägga till fler stilkontroller till blockverktygsfältet, men vi kan även tillhandahålla en uppsättning fördefinierade blockstilar som användaren kan välja mellan med ett enda klick.

För detta ändamål så kommer vi att använda en användbar funktion i Block API: Blockformat.

Allt som du behöver göra är att definiera egenskapen block.json styles och deklarera motsvarande stilar i dina formatmallar.

Du kan exempelvis lägga till följande array av stilar:

"styles": [
	{
		"name": "default",
		"label": "Default",
		"isDefault": true
	},
	{
		"name": "border",
		"label": "Border"
	}
],

Med detta så har du bara lagt till en standardstil och en ytterligare stil som heter border. Gå nu tillbaka till blockredigeraren:

Två förbyggda blockstilar.
Två förbyggda blockstilar.

Stilarna kommer att vara tillgängliga för användaren genom att den klickar på blockväxlaren och sedan letar efter panelen Stilar i sidofältet för blockinställningar.

Välj en stil och kontrollera de klasser som tillämpas på elementet p. Högerklicka på blocket och inspektera. En ny klass har lagts till med ett namn som är strukturerat på följande sätt:

is-style-{style-name}

Om du har markerat stilen ”Border” så läggs klassen is-style-border till i elementet p. Om du har markerat stilen ”Default” så kommer klassen is-style-default att läggas till i stället.

Nu behöver du bara deklarera CSS-egenskaperna. Öppna filen editor.scss och ersätt de nuvarande stilarna med följande:

.wp-block-ka-example-block-ka-example-block {
    padding: 4px;
}

Nu kan du göra samma sak med style.scss. Som vi nämnde ovan så tillämpas stilar som definieras i style.scss både på frontend och i redigeraren:

.wp-block-ka-example-block-ka-example-block {
	&.is-style-default{
		border: 0;
        background-color: #FFE2C7;
	}
	&.is-style-border{
		border: 2px solid #000;
        border-radius: 16px;
        background-color: #F6F6F6;
	}
}

Och det är allt! Uppdatera sidan och ha kul med dina nya blockformatmallar:

Jämförelse av blockformat
Jämförelse av blockformat

Bädda in Gutenberg Block med InnerBlocks-komponenten

Även om vårt anpassade block är fullt fungerande så är det fortfarande inte särskilt tilltalande. För att göra det mer engagerande för publiken så kan vi lägga till en bild.

Detta kan lägga till ett lager av komplexitet till vårt block, men som tur är så behöver du inte uppfinna hjulet på nytt. Gutenberg tillhandahåller nämligen en specifik komponent som du kan använda för att skapa en struktur av inbäddade block.

Komponenten InnerBlocks definieras på följande sätt:

InnerBlocks exporterar ett par komponenter som kan användas i blockimplementationer för att möjliggöra inbäddat blockinnehåll.

Först så måste du skapa en ny .js-fil i mappen src. I vårt exempel så kallar vi filen container.js.

Nu måste du importera den nya resursen till filen index.js:

import './container';

Gå tillbaka till container.js och importera de nödvändiga komponenterna:

import { registerBlockType } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import {
	useBlockProps, 
	InnerBlocks 
} from "@wordpress/block-editor";

Nästa steg är att definiera en mall som ger den struktur i vilken blocken kommer att placeras. I följande exempel så definierar vi en mall som består av två kolumner som innehåller en kärnblocksbild och vårt anpassade block:

const TEMPLATE = [ [ 'core/columns', { backgroundColor: 'yellow', verticalAlignment: 'center' }, [
	[ 'core/column', { templateLock: 'all' }, [
		[ 'core/image' ],
	] ],
	[ 'core/column', { templateLock: 'all' }, [
		[ 'ka-example-block/ka-example-block', { placeholder: 'Enter side content...' } ],
	] ],
] ] ];

Mallen är strukturerad som en array av blockTyper (blocknamn och valfria attribut).

I koden ovan så använde vi flera attribut för att konfigurera blocken Kolumner och Kolumn. Särskilt attributet templateLock: 'all' låser Kolumn-blocken så att användaren inte kan lägga till, ändra eller ta bort befintliga block. templateLock kan ha ett av följande värden:

  • allInnerBlocks är låst, och inga block kan läggas till, ordnas om eller tas bort.
  • insert — Blocken kan endast omordnas eller tas bort.
  • false — Mallen är inte låst.

Mallen tilldelas sedan elementet InnerBlocks:

<InnerBlocks
	template={ TEMPLATE }
	templateLock="all"
/>

För att förhindra kompatibilitetsproblem så har vi även lagt till attributet templateLock till InnerBlocks -elementet (se även ärende #17262 och pull #26128).

Här är vår slutliga container.js-fil:

registerBlockType('ka-example-block/ka-example-container-block', {
	title: __( 'KA Container block', 'ka-example-block' ),
	category: 'design',

	edit( { className } ) {
		
		return(
			<div className={ className }>
				<InnerBlocks
					template={ TEMPLATE }
					templateLock="all"
				/>
			</div>
		)
	},

	save() {
		const blockProps = useBlockProps.save();
		return(
			<div { ...blockProps }>
				<InnerBlocks.Content />
			</div>
		)
	},
});
Det slutgiltiga blocket i blockredigeraren
Det slutgiltiga blocket i blockredigeraren

Ytterligare förbättringar

Vårt block är fullt fungerande, men vi kan förbättra det ytterligare med några små ändringar.

Vi tilldelade attributet backgroundColor till stycket som genereras av komponenten RichText. Vi kanske föredrar att tilldela bakgrundsfärgen till containern div:

Ändra därför filen edit.js och save.js divs på följande sätt:

<div 
	{ ...blockProps }
	style={ { backgroundColor: backgroundColor } }
>
...
</div>

Detta gör det möjligt för användaren att ändra bakgrundsfärgen för hela blocket.

En mer relevant ändring gäller däremot metoden useBlockProps. I den ursprungliga koden så definierade vi konstanten blockProps på följande sätt:

const blockProps = useBlockProps();

Men vi kan använda useBlockProps mer effektivt genom att skicka en uppsättning egenskaper. Vi kan exempelvis importera classnames från modulen classnames och ställa in namnet på wrapperklassen i enlighet med detta.

I följande exempel så tilldelar vi ett klassnamn baserat på värdet av attributet align (edit.js).s

import classnames from 'classnames';

...

export default function Edit( { attributes, setAttributes } ) {
	...
	
	const onChangeAlign = ( newAlign ) => {
		setAttributes( { 
			align: newAlign === undefined ? 'none' : newAlign, 
		} )
	}

	const blockProps = useBlockProps( {
		className: `has-text-align-${ align }`
	} );
	...
}

Vi gör samma ändring i filen save.js:

import classnames from 'classnames';

...

export default function save( { attributes } ) {
	...
	const { content, align, backgroundColor, textColor, kaLink, linkLabel, hasLinkNofollow } = attributes;

	const blockProps = useBlockProps.save( {
		className: `has-text-align-${ align }`
	} );
	...
}

Och det är klart! Du kan nu köra byggnaden för produktion:

npm run build

Sammanfattning

Och nu har vi kommit till slutet av denna otroliga resa! Vi började med konfigurationen av utvecklingsmiljön och slutade med att skapa en komplett blocktyp.

Som vi nämnde i inledningen så är en gedigen kunskap om Node.js, Webpack, Babel och React nödvändig för att skapa avancerade Gutenbergblock och positionera dig på marknaden som en professionell Gutenbergutvecklare.

Men du behöver dock inte ha etablerad React-erfarenhet för att börja ha kul med blockutveckling. Blockutveckling kan ge dig motivation och mål att skaffa dig allt bredare färdigheter i teknikerna bakom Gutenbergblock.

Den här guiden är därför långt ifrån komplett. Den är endast en introduktion till en mängd olika ämnen som hjälper dig att komma igång med att bygga dina allra första Gutenbergblock.

Därför så rekommenderar vi att du fördjupar dina kunskaper genom att noggrant läsa dokumentation och guider online. Bland de många resurser som finns där ute så rekommenderar vi följande:

Om du precis har börjat med WordPress-utveckling så kanske du vill förstå de grundläggande begreppen för frontend-utveckling. Här är en snabb lista över resurser som kan hjälpa dig att komma igång:

Kom ihåg att den fullständiga koden för exemplen i den här guiden finns tillgänglig på Gist.

Nu är det din tur: Har du utvecklat några Gutenbergblock? Vilka är de största svårigheterna som du har upplevt hittills? Berätta om dina erfarenheter i kommentarerna!

Carlo Daniele Kinsta

Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for over 10 years, also in collaboration with Italian and European universities and educational institutions. He has written dozens of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find Carlo on Twitter and LinkedIn.