In diesem Beitrag wird ausführlich erläutert, wie Sie Farbeinstellungen zu Ihrem benutzerdefinierten WordPress-Gutenberg-Block hinzufügen. Wir werden lernen, wie man dieselbe Farbeinstellungskomponente hinzufügt, die die Auswahl aus Palettenfarben und benutzerdefinierten Farben bietet, wie viele der Standardblöcke von WordPress.
Folgendes werden wir zu unserem benutzerdefinierten Block hinzufügen:
Durch die Verwendung von Gutenbergs Komponenten können wir diese Palette/Farbsektion sehr einfach in unseren eigenen benutzerdefinierten Block implementieren. Sie können die Farbeinstellungen definieren, um jede gewünschte Farbe zu beeinflussen; Hintergrund, Textfarbe, Rahmenfarbe oder was auch immer. Sie können in diesem Bedienfeld auch so viele Farbeinstellungen hinzufügen, wie Sie möchten.
Bevor wir in den Code eintauchen, gibt es einige Dinge, die Sie beachten müssen. Springen Sie nicht zum Code, da der nächste Abschnitt ausführlich erklärt, warum der Code dies so tun muss, wie er es tut.
Was Sie zuerst wissen müssen
Die Komponenten zum Implementieren von Paletten-/Farbeinstellungen sind PanelColorSettings
und withColors
aus dem wp.blockEditor
Paket. Die Komponente withColors
ist eine sogenannte Komponente höherer Ordnung und muss etwas anders implementiert werden, als einfach eine normale Komponente auszugeben. Ich gehe später noch etwas detaillierter darauf ein. Aber zuerst müssen wir uns der Grundlagen bewusst sein, wie Gutenberg mit Blockfarbeinstellungen umgeht.
Wie Gutenberg-Blöcke mit Farbeinstellungen umgehen
Es gibt bestimmte Regeln dafür, wie Gutenberg mit Farbeinstellungen in Blöcken umgeht. Wenn Sie schon einmal ein von Gutenberg unterstütztes Design gestaltet haben, sind Sie wahrscheinlich bereits mit diesen Regeln vertraut. Wir werden sie trotzdem schnell durchgehen, weil wir dies in unserem Blockcode behandeln müssen.
- Wenn eine Palettenfarbe ausgewählt wird, erhält das Knotenblockelement eine Klasse eines bestimmten Musters. Die Klasse beginnt mit „
has-
“, und dann folgt der Slug der Palette. Das Ende hängt davon ab, auf welches Element die Farbe wirken soll. Bei Textfarbe endet es mit „-color
“. Bei Hintergrundfarbe endet es mit „-background-color
“. Als Beispiel erhält ein Block mit einer Palettenfarbe „rot” als Hintergrundfarbe die Klasse „has-red-background-color
“. - Wenn eine benutzerdefinierte Farbe ausgewählt wird (aus der Farbauswahl), erhält das Knotenblockelement einen Inline-Stil mit dem Hex-Code. Beispielsweise erhält eine benutzerdefinierte Farbe #DD0000, die als Hintergrundfarbe ausgewählt wurde, das Attribut „
style="background-color: #DD0000;
“.
Wenn wir Farbeinstellungen für unseren Block implementieren, müssen wir die richtige Klasse und den richtigen Inline-Stil implementieren. Das machen wir am Ende dieses Tutorials.
Wie man damit arbeitetwithColors
Wie bereits erwähnt, withColors
ist eine Komponente höherer Ordnung. Das bedeutet im Grunde, dass es sich um eine Komponente handelt, die eine Komponente nimmt und eine neue Komponente zurückgibt. In der zurückgegebenen Komponente erhalten wir nützliche Requisiten von der Komponente höherer Ordnung. Um es einfach auszudrücken, werden wir verwenden withColors
, um unsere eigene Komponente für unseren benutzerdefinierten Block zurückzugeben. Unsere Blockkomponente erhält die notwendigen Requisiten für die Arbeit mit Farben aus withColors
.
Die Komponente withColors
behandelt den Zustand und viele Funktionen für die Arbeit mit Farben. Und wir bekommen in diesem Prozess viel Automatisierung. Dies ist sehr praktisch, um herauszufinden, ob die gewählte Farbe eine Palettenfarbe (wir müssen eine Klasse hinzufügen) oder eine benutzerdefinierte Farbe (wir müssen einen Inline-Stil hinzufügen) ist. withColors
Vereinfachen Sie einen Großteil des Prozesses des Speicherns der gewählten Farbe, was auch immer es ist, in den Attributen unseres Blocks. Apropos Attribute..
Attribute uwithColors
Offensichtlich benötigt Ihr Block Attribute, um die gewählte Farbe zu speichern. Um von der Automatisierung von withColor zum Speichern der korrekten Farbe zu profitieren, müssen Sie tatsächlich zwei Attribute für jede Farbeinstellung definieren. Eine zum Speichern des Slugs der Palettenfarbe und eine andere zum Speichern des Hex-Codes. Es gibt jedoch einige Regeln.
Angenommen, Sie möchten eine Farbeinstellung für die Textfarbe des Blocks hinzufügen – also entscheiden Sie sich, ein Attribut mit dem treffenden Namen „ textColor
” zu definieren. Sie müssen dann ein weiteres Attribut im Muster „ customYourOriginalAttribute
” definieren. In diesem Beispiel muss das zweite Attribut „ customTextColor
” heißen. Achten Sie hier auf das camelCase (Großschreibung). Nach diesem Muster withColors
wird automatisch:
- Wenn eine Palettenfarbe ausgewählt wurde,
textColor
enthält das Attribut „ ” den Slug der Palette. - Wenn eine benutzerdefinierte Farbe ausgewählt wurde, wird „
customTextColor
” mit dem Hex-Code ausgefüllt.
Diese beiden arbeiten zusammen. Wenn eine benutzerdefinierte Farbe ausgewählt textColor
wird, ist automatisch undefined
und umgekehrt.
Und zum Schluss noch eine letzte Sache, an die Sie sich erinnern sollten: Sie müssen nicht verwenden, setAttributes()
um Ihre Farbattribute zu aktualisieren! Die bereitgestellten Requisiten von withColors
enthalten eine Funktion, die Ihre Attribute automatisch für Sie aktualisiert. Alles, was Sie tun müssen, ist, diese Funktion an das onChange
Ereignis an die PanelColorSettings
Komponente zu übergeben, und Ihre Attribute werden automatisch aktualisiert.
Ok, es ist Zeit, all dies in der Praxis zu sehen!
Implementieren von Farbeinstellungen in einem benutzerdefinierten Block
Zu Beginn habe ich einen ziemlich nutzlosen benutzerdefinierten Block, der nichts anderes tut, als einen fest codierten Text anzuzeigen. Dies macht es einfach zu trennen, was wir zum Hinzufügen von Farbeinstellungen codieren müssen. Ich habe eine Tutorial-Serie zum Erstellen eigener benutzerdefinierter Blöcke, wenn Sie daran interessiert sind, mehr zu erfahren.
Hinweis: Ich schreibe den gesamten Code in ES6/ESNext. Dazu gehören Pfeilfunktionen, die in Ihrem Babel/Webpack-Setup besondere Sorgfalt erfordern. Wenn Sie bei einigen der folgenden Codes Fehler erhalten, folgen Sie meiner Anleitung zum Einrichten von Webpack und Babel für ES6/ESNext oder passen Sie den Code so an, dass keine „experimentellen Syntaxen” verwendet werden.
Dies ist mein grundlegender benutzerdefinierter Block, bevor ich irgendetwas mit Farbeinstellungen mache:
const { registerBlockType } = wp.blocks;
const { __ } = wp.i18n;
const BlockWithColorSettings = (props) => {
return(
<div>
PanelColorSettings Demo
</div>
);
}
registerBlockType('awp/colorsettings', {
title: __('Color Settings Demo'),
icon: 'carrot',
category: 'common',
edit: BlockWithColorSettings,
save: (props) => {
return(
<div>
PanelColorSettings Demo
</div>
);
}
});
Es ist ziemlich einfach. Beachten Sie, dass die edit
Funktion einfach auf eine separate Komponente verweist BlockWithColorSettings
, anstatt sie inline zu schreiben. Das erleichtert die withColors
spätere Umsetzung.
Okay, Zeit, Farbeinstellungen für unseren Block zu implementieren! Als Beispiel möchte ich die Textfarbe einrichten.
Attribute hinzufügen
Wie bereits erwähnt, müssen wir für jede Farbeinstellung zwei Attribute definieren. Und wir müssen bei ihrer Benennung besonders vorsichtig sein. Ich möchte ein Textfarbattribut hinzufügen, also nenne ich das Attribut textColor
. Das heißt, ich werde auch ein Attribut hinzufügen customTextColor
. Beide sollten vom Typ string sein.
...
registerBlockType('awp/colorsettings', {
title: __('Color Settings Demo'),
icon: 'carrot',
category: 'common',
attributes: {
textColor: {
type: 'string'
},
customTextColor: {
type: 'string'
},
},
edit: BlockWithColorSettings,
save: (props) => {
...
Unsere Attribute sind bereit, die Textfarbeinstellung des Blocks zu speichern. Jetzt geht es an die Umsetzung withColors
und PanelColorSettings
.
ImplementierenwithColors
Wie bereits erwähnt withColors
, handelt es sich um eine Komponente höherer Ordnung, die eine Komponente zurückgeben sollte. Wir möchten natürlich, dass unsere Bearbeitungskomponente zurückgegeben wird, BlockWithColorSettings
. Aber als Parameter withColors
liefern wir ein Objekt.
In dem übergebenen Objekt withColors
müssen wir angeben, withColors
welches Attribut wir zum Speichern der Farbe verwenden möchten und welche Art von Element es färben soll (in unserem Fall Textfarbe, was CSS-Regel „Farbe” bedeutet). Die Information über die CSS-Regel stellt sicher, dass die zurückgegebenen Klassennamen korrekt sind. Da dies eine Textfarbe ist, wollen wir Klassennamen wie „has–color”.
Zuerst etwas Destrukturierung an der Spitze. withColors
befindet sich im wp.blockEditor
Paket.
const { withColors } = wp.blockEditor;
Wir ändern die edit
Funktion in:
...
attributes: {
...
},
edit: withColors({textColor: 'color'})(BlockWithColorSettings),
save: (props) => {
...
BlockWithColorSettings
Mit diesem Code erhält unsere Komponente einige zusätzliche Props:
props.textColor
: Ist ein Objekt, das alle Informationen über die gewählte Farbe enthält. Wenn eine Palettenfarbe ausgewählt wurde, werden Eigenschaften für Hex-Code, Paletten-Slug, Klassennamen und mehr gespeichert. Wenn eine benutzerdefinierte Farbe ausgewählt wurde, enthält das Objekt den Hex-Code. Der Hex-Code steht immer in der Eigenschaftcolor
. Und der Klassenname (nur wenn eine Palettenfarbe gewählt wurde) wird in der Eigenschaft gesetztclass
.props.setTextColor
: Eine Funktion, die unsere Attribute für uns aktualisiert. Wir stellen dies für das Ereignis der Farbeinstellungen bereitonChange
, wie wir später sehen werden. Die Funktion aktualisiert sowohltextColor
als auchcustomTextColor
Attribute. Da wir die Benennungsregeln befolgt haben, wird es automatisch aktualisiertcustomTextColor
, obwohl wir diesen Attributnamen nie angegeben haben.
Beachten Sie, dass die als Prop bereitgestellte „set”-Funktion der Regel folgt: „ setYourAttributeName
“. Da wir bereitgestellt textColor
haben, heißt die Funktion setTextColor
. Wenn wir stattdessen unser Attribut benennen awesomeColor
und dieses im withColors
Objekt bereitstellen würden, würde die Set-Funktion heißen setAwesomeColor()
.
ImplementierenPanelColorSettings
Der nächste Schritt ist die Implementierung des eigentlichen Inspector-Abschnitts. Dazu fügen wir PanelColorSettings
eine InspectorControls
Komponente ein. Da React erfordert, dass sich alles in einem Root-Knoten befindet, verwenden wir auch Fragment
(from wp.elements
), um alles darin einzuschließen.
Zuerst etwas Destrukturierung am Anfang der Datei:
const { Fragment } = wp.element;
const { InspectorControls, PanelColorSettings, withColors } = wp.blockEditor;
Und wir aktualisieren unsere BlockWithColorSettings
Komponente in etwa so:
const BlockWithColorSettings = (props) => {
const { textColor, setTextColor } = props; // Props received from withColors
return(
<Fragment>
<InspectorControls>
<PanelColorSettings
title={__('Color settings')}
colorSettings={[
{
value: textColor.color,
onChange: setTextColor,
label: __('Text color')
},
]}
/>
</InspectorControls>
<div>
PanelColorSettings Demo
</div>
</Fragment>
);
}
Wie Sie in der Zeile sehen können, destrukturieren wir die von, und #2
erhaltenen Requisiten. Denken Sie daran, dass dies das von erhaltene Objekt und das Attribut ist. Wir müssen uns jedoch nicht auf das Attribut beziehen.withColors``textColor``setTextColor``props.textColor``withColors``props.attributes.textColor
Als Requisiten für die Komponente PanelColorSettings
können wir einen Titel für den Abschnitt bereitstellen (Titel in der zusammenklappbaren Box im Inspektor). Das Wichtigste hier ist die Requisite colorSettings
, bei der wir eine Reihe von Farbeinstellungsobjekten bereitstellen müssen. Für jede Farbeinstellung (wir haben derzeit nur eine) müssen wir einige Eigenschaften angeben. Die Eigenschaft value
erwartet den aktuell gewählten Hex-Code (auch wenn eine Palettenfarbe gewählt wurde). Dies wird uns in der textColor
Requisite auf dem Grundstück zur Verfügung gestellt color
. Für die onChange
Eigenschaft stellen wir einfach die „set”-Funktion bereit, die von, bereitgestellt withColors
wird setTextColor
. Und schließlich sollten wir ein geben label
, damit der Benutzer weiß, auf welches Element sich diese Farbe auswirkt. Es erscheint direkt über dem Bereich zum Auswählen einer Farbe.
So erscheint unsere Komponente im Moment im Gutenberg-Editor:
Es aktualisiert jetzt erfolgreich unsere Attribute bei der Auswahl von Farben. Sie können sehen, dass es sich beim Speichern des Beitrags an Ihre Farbauswahl erinnert.
Beim Farbwechsel passiert aber optisch nichts. Die Farbauswahl wird in den Attributen gespeichert, aber weder im Editor noch bei der Vorschau des Beitrags findet eine Farbänderung statt. Dies liegt daran, dass wir Code für die Klassen und Stile des Blocks hinzufügen müssen. Wir müssen dies sowohl für die edit
Funktion (für den Editor) als auch für die save
Funktion (Frontend) tun. Das ist der nächste Schritt.
Handhabung von Klassen- und Inline-Stilen inedit
Wir müssen die Knotenklassen- und Stilattribute des Blocks gemäß der gewählten Farbeinstellung erstellen. Glücklicherweise withColors
erhalten wir dabei eine gewisse Automatisierung. Denken Sie daran, dass dies props.textColor
ein Objekt ist, das alle Informationen enthält, die wir benötigen, einschließlich des Klassennamens.
Wir könnten so etwas tun:
...
const BlockWithColorSettings = (props) => {
const { textColor, setTextColor } = props; // Props received from withColors
let divClass;
let divStyles = {};
if (textColor != undefined) {
if (textColor.class != undefined) {
divClass = textColor.class;
} else {
divStyles.color = textColor.color;
}
}
return(
<Fragment>
<InspectorControls>
...
</InspectorControls>
<div className={divClass} style={divStyles}>
PanelColorSettings Demo
</div>
...
An der Zeile #20
wenden wir die kritische Klasse und den Inline-Stil auf den Wurzelknoten unseres Blocks an. Davor bauen wir die Klasse und das Inline-Stilattribut, indem wir das props.textColor
Objekt überprüfen.
Nach dieser Änderung sollte Ihr benutzerdefinierter Block jetzt im Editor voll funktionsfähig sein. Immer wenn Sie die Farbe wechseln, ändert der Block die Textfarbe. Genial! Der letzte Schritt macht dies save
auch für die Funktion, sodass wir diese Klassen und Stile auch im Frontend erhalten.
Handhabung von Klassen- und Inline-Stilen insave
Das Konzept, die Klassen- und Inline-Stile zu erstellen und sie auf den Stammknoten anzuwenden, ist das gleiche save
wie in edit
. Aber es gibt einen entscheidenden Unterschied. In save
haben wir nicht die von bereitgestellten Requisiten withColors
. Und wir können der save
Funktion keine Komponenten höherer Ordnung hinzufügen. In der save
Funktion sind also alle Informationen, die wir haben, die Attribute.
Es ist eine gute Faustregel, hartcodierte „has-“-Klassennamen zu vermeiden. Was ist, wenn WordPress beschließt, diese Regel in Zukunft zu ändern? Glücklicherweise haben wir eine Funktion, die uns helfen kann, die richtigen Klassennamen für uns zu generieren: getColorClassName()
.
Bevor wir es vergessen, lass es uns destrukturieren. Es ist auch im wp.blockEditor
Paket.
const { InspectorControls, PanelColorSettings, withColors, getColorClassName } = wp.blockEditor;
Die Verwendung der getColorClassName()
Funktion erfordert zwei Parameter. Zuerst ein String für die CSS-Regel. Da unsere Farbeinstellung für die Textfarbe gilt, geben wir „ color
” an. Dies teilt der Funktion mit, dass sie beispielsweise einen Klassennamen von „hat-etwas-Farbe” und nicht „hat-etwas-Hintergrundfarbe” zurückgeben soll. Als zweiten Parameter müssen wir den Wert des Attributs angeben.
Das style-Attribut wird einfach erstellt, indem „color” auf den Wert des Attributs gesetzt wird customTextColor
, falls es definiert ist.
save: (props) => {
const { textColor, customTextColor } = props.attributes;
let divClass;
let divStyles = {};
if (textColor != undefined) {
divClass = getColorClassName('color', textColor);
}
if (customTextColor != undefined) {
divStyles.color = customTextColor;
}
return(
<div className={divClass} style={divStyles}>
PanelColorSettings Demo
</div>
);
}
Und vergessen Sie natürlich nicht, die Klasse und den Stil auf den Wurzelknoten Ihres Blocks anzuwenden; wie an der Reihe #12
.
PS: Wenn Sie Ihren Block im Editor testen, während Sie diesen Code schreiben, erhalten Sie jetzt einen Blockfehler. Dies geschieht, weil wir jetzt die Ausgabe für die save
Funktion geändert haben und alles, was Sie zuvor gespeichert haben, in Konflikt steht. Sie müssen den Block entfernen und erneut hinzufügen.
Nach dieser Änderung sollte Ihr Block nun auch im Frontend die gewählte Textfarbe korrekt anwenden.
Und das ist es! Sie haben jetzt erfolgreich Farbeinstellungen für Ihren Block implementiert. Wenn Sie daran interessiert sind, mehrere Farbeinstellungen (nicht nur Textfarbe) hinzuzufügen, lesen Sie weiter.
Ein Hinweis zu mehreren Farbeinstellungen
Inzwischen sollten Sie in der Lage sein, mehrere Farbeinstellungen zu implementieren. Möglicherweise möchten Sie Ihrem Block Einstellungen für Hintergrundfarbe, Textfarbe, Randfarbe oder was auch immer hinzufügen. In diesem Abschnitt gebe ich einen kurzen Überblick darüber, was wir tun müssen, um mehrere Farbeinstellungen zu implementieren.
Nehmen wir an, ich möchte meinem Block auch eine Hintergrundfarbe hinzufügen.
Zuerst muss ich ein neues Attribut mit dem kreativen Namen definieren backgroundColor
. Ich definiere auch ein anderes Attribut customBackgroundColor
.
In der edit
Funktion ändere ich das bereitgestellte Objekt withColors
als solches:
withColors({textColor: 'color', backgroundColor: 'background-color'})
Dies sagt withColors
, dass mein textColor
Attribut für die CSS-Regel „ color
” (für Textfarbe) und das Attribut backgroundColor
für die CSS-Regel „ background-color
” ist. withColors
erkennt und aktualisiert auch automatisch die customTextColor
Attribute customBackgroundColor
und .
In der PanelColorSettings
Komponente stelle ich dem Array ein weiteres Objekt zur Stütze bereit colorSettings
. So:
<PanelColorSettings
title={__('Color settings')}
colorSettings={[
{
value: textColor.color,
onChange: setTextColor,
label: __('Text color')
},
{
value: backgroundColor.color,
onChange: setBackgroundColor,
label: __('Background color')
},
]}
/>
Damit sollten Sie zwei separate Farbeinstellungen im Inspektorfeld für Farbeinstellungen erhalten.
Der letzte Schritt besteht darin, die entsprechenden Klassennamen und -stile in edit
und zu erstellen save
. Dies ist ein ziemlich einfacher Schritt, da es nur darum geht, ein Zeichenfolgen- oder Stilobjekt korrekt zu erstellen. Denken Sie daran, dass Ihr Klassenname mehrere Farbklassen unterstützen muss (z. B. wenn sowohl Textfarbe als auch Hintergrundfarbe ausgewählt wurden). Fügen Sie einfach ein Leerzeichen zwischen jedem Klassennamen ein.
PS: Wenn Sie viele Klassennamen für Ihren Block verarbeiten müssen, können Sie von der Installation des classnames
Pakets profitieren. So ziemlich alle Komponenten in Gutenberg verwenden diese Bibliothek, um Klassennamen einfacher zu kombinieren.
Fazit und vollständiger Code
Sie sollten jetzt gelernt haben, wie Sie Farbeinstellungen in Ihrem benutzerdefinierten Block implementieren. Ich hoffe, das hat dir etwas geholfen! Ich musste diese Funktion zu meinem Projekt hinzufügen und konnte wirklich keine Informationen oder gute Dokumentation finden. Dies ist also das Ergebnis der Konsolidierung von allem, was ich über dieses Thema gelernt habe, nach viel Versuch und Irrtum.
Hier ist der endgültige Code für den benutzerdefinierten Beispielblock mit Textfarbeinstellung:
const { registerBlockType } = wp.blocks;
const { __ } = wp.i18n;
const { Fragment } = wp.element;
const { InspectorControls, PanelColorSettings, withColors, getColorClassName } = wp.blockEditor;
const BlockWithColorSettings = (props) => {
const { textColor, setTextColor } = props; // Props received from withColors
let divClass;
let divStyles = {};
if (textColor != undefined) {
if (textColor.class != undefined) {
divClass = textColor.class;
} else {
divStyles.color = textColor.color;
}
}
return(
<Fragment>
<InspectorControls>
<PanelColorSettings
title={__('Color settings')}
colorSettings={[
{
value: textColor.color,
onChange: setTextColor,
label: __('Text color')
},
]}
/>
</InspectorControls>
<div className={divClass} style={divStyles}>
PanelColorSettings Demo
</div>
</Fragment>
);
}
registerBlockType('awp/colorsettings', {
title: __('Color Settings Demo'),
icon: 'carrot',
category: 'common',
attributes: {
textColor: {
type: 'string'
},
customTextColor: {
type: 'string'
},
},
edit: withColors({textColor: 'color'})(BlockWithColorSettings),
save: (props) => {
const { textColor, customTextColor } = props.attributes;
let divClass;
let divStyles = {};
if (textColor != undefined) {
divClass = getColorClassName('color', textColor);
}
if (customTextColor != undefined) {
divStyles.color = customTextColor;
}
return(
<div className={divClass} style={divStyles}>
PanelColorSettings Demo
</div>
);
}
});