Bisher ist es teilweise (sehr) frustrierend gewesen, einzelne Block-Optionen im Editor zu konfigurieren oder zu deaktivieren. Wollten wir etwa, dass für unterschiedliche Blöcke unterschiedliche Farbpaletten zur Verfügung stehen, müssten wir einige Umwege in Kauf nehmen. Und um zum Beispiel die Ausgabe der Initialbuchstabe-Option beim Absatz-Block zu deaktivieren, half nur das Ausblenden mit CSS, das auch nicht so einfach ist, weil die meisten Optionen nur sehr generische Klassen haben (zum Beispiel die Initiale-Option …).

Doch mit WordPress 5.8 erscheint, als Retterin in der Not: die theme.json.

Update vom 15. Juli 2021: Ich habe den Artikel aktualisiert, sodass er das Format und die Möglichkeiten der theme.json behandelt, die in WordPress 5.8 enthalten sind.

Was die theme.json kann

Alles! Na gut, das ist ein wenig übertrieben. Aber sie kann sehr viel, und mit WordPress 5.8 kommt die Funktion voraussichtlich am 20. Juli 2021 endlich in den WordPress-Core. Damit können wir eine theme.json in das oberste Verzeichnis eines Themes legen und mit der Konfiguration des Block-Editors beginnen. Eine Auflistung aller Möglichkeiten gibt es auf einer Handbook-Seite zur theme.json.

Zusammenfassend können in der Datei sowohl Einstellungen vorgenommen werden, wie die Definition der Farben für Farbpaletten oder das Aktivieren und Deaktivieren von bestimmten Block-Optionen, als auch Standard-Styles für einige fest definierte Eigenschaften festgelegt werden – und das alles sowohl für alle Blöcke als auch nur für einzelne.

Dieses standardisierte Format einer JSON-Datei ermöglicht es WordPress auch, möglichst wenig Styles zu laden, wenn eine Angabe in der theme.json einen Core-Style überschreibt oder, in einer zukünftigen Version von WordPress mit dem Full-Site-Editor, vom User Styles in diesem Editor angepasst werden.

Erstellung einer theme.json

Mit WordPress 5.8 werden auf oberster Ebene erst mal die Einträge version, settings und styles verfügbar sein:

{
  "version": 1,
  "settings": {},
  "styles": {}
}Code-Sprache: JSON / JSON mit Kommentaren (json)

In settings und styles sind sowohl globale Angaben möglich, als auch solche, die nur bestimmte Blöcke betreffen.

Die »settings« der theme.json

Bevor wir ein paar praktische Beispiele durchgehen, schauen wir uns an, welche Möglichkeiten uns die theme.json alle mit WordPress 5.8 bietet, und wir starten dabei mit dem settings-Abschnitt. Um es etwas übersichtlicher zu halten, ist hier kein Beispiel für die Veränderung eines spezifischen Blocks mit abgebildet (der Code ist leicht verändert von der Handbook-Seite übernommen):

{
  "version": 1,
  "settings": {
    "color": {
      "custom": true,
      "customDuotone": true,
      "customGradient": true,
      "duotone": [],
      "gradients": [],
      "palette": [],
      "link": false
    },
    "custom": {},
    "layout": {
      "contentSize": "702px",
      "wideSize": "1002px"
    },
    "spacing": {
      "customMargin": false,
      "customPadding": false,
      "units": [
        "px",
        "em",
        "rem",
        "vh",
        "vw"
      ]
    },
    "typography": {
      "customFontSize": true,
      "customLineHeight": false,
      "dropCap": true,
      "fontSizes": []
    }
  }
}Code-Sprache: JSON / JSON mit Kommentaren (json)

Die »styles« der theme.json

Gehen wir jetzt noch den styles-Abschnitt durch, bevor wir zu den Beispielen kommen. Auch hier habe ich mich auf die oberste Ebene beschränkt, später zeige ich Code, um einzelne Blöcke anzusprechen – auch dieses Beispiel ist leicht abgewandelt von der theme.json-Handbuchseite übernommen.

{
  "version": 1,
  "styles": {
    "color": {
      "background": "value",
      "gradient": "value",
      "text": "value"
    },
    "spacing": {
      "margin": {
        "top": "value",
        "right": "value",
        "bottom": "value",
        "left": "value"
      },
      "padding": {
        "top": "value",
        "right": "value",
        "bottom": "value",
        "left": "value"
      }
    },
    "typography": {
      "fontSize": "value",
      "lineHeight": "value"
    },
    "elements": {
      "link": {
        "color": {},
        "spacing": {},
        "typography": {}
      },
      "h1": {},
      "h2": {},
      "h3": {},
      "h4": {},
      "h5": {},
      "h6": {}
    }
  }
}Code-Sprache: JSON / JSON mit Kommentaren (json)

Hier können wir jetzt statt der für den User verfügbaren Werte die Standard-Werte festlegen, die dann von WordPress in Styles umgewandelt und eingebunden werden und um die sich das Theme nicht mehr kümmern muss. Als Werte bieten sich hier die CSS-Variablen an, die durch unsere settings-Angaben erzeugt wurden.

Beispiele

Die wenigstmöglichen Optionen

Gehen wir davon aus, dass wir den Nutzerinnen und Nutzern unseres Themes möglichst wenig Möglichkeiten geben möchten, Dinge zu verstellen, weil wir ein sehr schlichtes und einheitliches Design gebaut haben, das ohne verschiedene Farben und ähnliches auskommt.

{
  "version": 1,
  "settings": {
    "color": {
      "custom": false,
      "customDuotone": false,
      "customGradient": false,
      "duotone": [],
      "gradients": [],
      "palette": [],
      "link": false
    },
    "layout": {
      "contentSize": "702px",
      "wideSize": "1002px"
    },
    "spacing": {
      "customMargin": false,
      "customPadding": false
    },
    "typography": {
      "customFontSize": false,
      "customLineHeight": false,
      "fontSizes": [],
      "dropCap": false
    }
  }
}Code-Sprache: JSON / JSON mit Kommentaren (json)

Mit dieser theme.json werden die folgenden Optionen entfernt:

Übrig bleibt eine sehr aufgeräumte Block-Sidebar.

Eine globale Farbpalette und eine eigene für den Gruppen-Block

Wir arbeiten mit dem Code aus dem ersten Beispiel weiter und verändern es ein wenig, um eine Farbpalette für alle unterstützenden Blöcke zu definieren und sie für den Gruppen-Block um eine Farbe zu erweitern:

{
  "version": 1,
  "settings": {
    "color": {
      "custom": false,
      "customDuotone": false,
      "customGradient": false,
      "duotone": [],
      "gradients": [],
      "palette": [
        {
          "name": "Dark",
          "slug": "dark",
          "color": "hsl(208.2, 67.1%, 14.3%)"
        },
        {
          "name": "Light",
          "slug": "light",
          "color": "hsl(208.2, 34.4%, 87.5%)"
        }
      ],
      "link": false
    },
    "layout": {
      "contentSize": "702px",
      "wideSize": "1002px"
    },
    "spacing": {
      "customMargin": false,
      "customPadding": false
    },
    "typography": {
      "customFontSize": false,
      "customLineHeight": false,
      "fontSizes": [],
      "dropCap": false
    },
    "blocks": {
      "core/group": {
        "color": {
          "palette": [
            {
              "name": "Dark",
              "slug": "dark",
              "color": "hsl(208.2, 67.1%, 14.3%)"
            },
            {
              "name": "Light",
              "slug": "light",
              "color": "hsl(208.2, 34.4%, 87.5%)"
            },
            {
              "name": "White",
              "slug": "white",
              "color": "#fff"
            }
          ]
        }
      }
    }
  }
}Code-Sprache: JSON / JSON mit Kommentaren (json)

WordPress generiert daraus das folgende CSS, sodass die gewählten Farben sowohl im Backend als auch im Frontend direkt angezeigt werden:

body {
  --wp--preset--color--dark: hsl(208.2, 67.1%, 14.3%);
  --wp--preset--color--light: hsl(208.2, 34.4%, 87.5%);
}
.wp-block-group {
  --wp--preset--color--dark: hsl(208.2, 67.1%, 14.3%);
  --wp--preset--color--light: hsl(208.2, 34.4%, 87.5%);
  --wp--preset--color--white: #fff;
}
.has-dark-color {
  color: var(--wp--preset--color--dark) !important;
}
.has-light-color {
  color: var(--wp--preset--color--light) !important;
}
.has-dark-background-color {
  background-color: var(--wp--preset--color--dark) !important;
}
.has-light-background-color {
  background-color: var(--wp--preset--color--light) !important;
}
.wp-block-group.has-dark-color {
  color: var(--wp--preset--color--dark) !important;
}
.wp-block-group.has-light-color {
  color: var(--wp--preset--color--light) !important;
}
.wp-block-group.has-white-color {
  color: var(--wp--preset--color--white) !important;
}
.wp-block-group.has-dark-background-color {
  background-color: var(--wp--preset--color--dark) !important;
}
.wp-block-group.has-light-background-color {
  background-color: var(--wp--preset--color--light) !important;
}
.wp-block-group.has-white-background-color {
  background-color: var(--wp--preset--color--white) !important;
}Code-Sprache: CSS (css)

Standard-Styles für Blöcke festlegen

Das Farbpalettenbeispiel können wir in einem abschließenden Beispiel nutzen, um Standard-Styles für Blöcke zu definieren. Nehmen wir an, wir möchten Gruppen-Blöcken ohne spezifische Farbeinstellung immer die dunkle Farbe als Hintergrund und die helle als Textfarbe mitgeben.

{
  "version": 1,
  "settings": {
    "color": {
      "custom": false,
      "customDuotone": false,
      "customGradient": false,
      "duotone": [],
      "gradients": [],
      "palette": [
        {
          "name": "Dark",
          "slug": "dark",
          "color": "hsl(208.2, 67.1%, 14.3%)"
        },
        {
          "name": "Light",
          "slug": "light",
          "color": "hsl(208.2, 34.4%, 87.5%)"
        }
      ],
      "link": false
    },
    "layout": {
      "contentSize": "702px",
      "wideSize": "1002px"
    },
    "spacing": {
      "customMargin": false,
      "customPadding": false
    },
    "typography": {
      "customFontSize": false,
      "customLineHeight": false,
      "fontSizes": [],
      "dropCap": false
    },
    "blocks": {
      "core/group": {
        "color": {
          "palette": [
            {
              "name": "Dark",
              "slug": "dark",
              "color": "hsl(208.2, 67.1%, 14.3%)"
            },
            {
              "name": "Light",
              "slug": "light",
              "color": "hsl(208.2, 34.4%, 87.5%)"
            },
            {
              "name": "White",
              "slug": "white",
              "color": "#fff"
            }
          ]
        }
      }
    }
  },
  "styles": {
    "blocks": {
      "core/group": {
        "color": {
          "text": "var(--wp--preset--color--light)",
          "background": "var(--wp--preset--color--dark)"
        }
      }
    }
  }
}Code-Sprache: JSON / JSON mit Kommentaren (json)

Das wird von WordPress in die folgende zusätzliche CSS-Regel umgewandelt:

.wp-block-group {
  background-color: var(--wp--preset--color--dark);
  color: var(--wp--preset--color--light);
}Code-Sprache: CSS (css)

Und damit bekommen Gruppen-Blöcke sowohl im Backend als auch im Frontend standardmäßig den dunklen Hintergrund und die helle Textfarbe.

Dieses Muster des Überschreibens von Optionen und Styles für einzelne Blöcke lässt sich auf die anderen Settings und Style-Möglichkeiten übertragen. Auf der Doku-Seite zur theme.json findet ihr noch ein paar weitere Beispiele.

Was ist mit meinen add_theme_support()-Aufrufen für Farbpaletten und Co?

Vielleicht fragt ihr euch, wie das mit den add_theme_support()-Aufrufen zusammenpasst, mit denen bisher beispielsweise Farbpaletten definiert werden konnten. Die funktionieren weiter wie bisher und werden auf die entsprechenden Werte der theme.json gemappt, das heißt beispielsweise, add_theme_support( 'disable-custom-colors' ) ist dasselbe wie settings.color.custom auf false zu setzen. Ihr müsst also nicht auf eine theme.json umsteigen, wenn ihr bisher zufrieden mit den Konfigurationsmöglichkeiten seid.

Wenn ihr eine theme.json erstellt habt und gleichzeitig add_theme_support()-Aufrufe vorhanden sind, überschreibt die JSON-Datei die Angaben von add_theme_support().

Können auch Nicht-Core-Blöcke über die theme.json konfiguriert werden?

Ja, sofern sie Unterstützung dafür mitbringen. Am einfachsten ist das, wenn die Blöcke eine block.json-Datei für die Metadaten nutzen und in PHP mit register_block_type() registriert werden, wobei als ersten Parameter der Verzeichnispfad zur block.json angegeben wird, wie in der Doku zur block.json beschrieben.

In dieser block.json könnt ihr mit supports angeben, welche Optionen der Block unterstützen soll, zum Beispiel Farbpaletten oder Schriftgrößen. WordPress rendert dann automatisch die Optionen im Editor und diese können wie oben beschrieben für euren eigenen Block in der theme.json angepasst werden.

Wenn ihr andere Dinge im Block über die theme.json anpassen wollt, gibt es den useSetting-Hook, mit dem Blöcke auf die Einstellungen aus der theme.json zurückgreifen können. Ein kleines Beispiel dazu gibt es im Make-Beitrag zur theme.json.

Den neuen Template-Editor deaktivieren

Standardmäßig wird der in WordPress 5.8 neue Template-Editor aktiviert, wenn ein Theme eine theme.json beinhaltet. Falls ihr das nicht möchtet, könnt ihr ihn mit remove_theme_support( 'block-templates' ); deaktivieren.

Was bei der theme.json noch geplant und in Arbeit ist

Im »Settings«- und »Styles«-Abschnitt der theme.json-Doku gibt es je ein Code-Beispiel, das zwischen der Ansicht WordPress und Gutenberg umgeschaltet werden kann. Da ist zu sehen, dass im Gutenberg-Plugin aktuell schon einige Sachen mehr möglich sind:

Außerdem gibt es in der Version des Gutenberg-Plugins einen Abschnitt customTemplates, in dem Block-Themes die Templates auflisten können, die sie im block-templates-Ordner mitbringen. Da werden dann der interne Name, der Titel und optional die unterstützten Inhaltstypen angegeben. Darüber hinaus gibt es einen templateParts-Eintrag, in dem das Theme seine Template-Teile auflisten kann, wie den Header und den Footer.

Fazit

Für mich persönlich ist die theme.json das Highlight von WordPress 5.8. Endlich können nicht genutzte Funktionen einfach deaktiviert und andere Optionen auf Block-Ebene angepasst werden. Hoffentlich werden auch Drittanbieter von Blöcken ihre Blöcke so anpassen, dass sie über die theme.json konfiguriert werden können, damit sich das nicht nur auf die Core-Blöcke beschränkt.

Was haltet ihr von den neuen Möglichkeiten, die die theme.json bietet?