Skip to content

[Fonts API] Proposal: classic themes define fonts in a theme.json file #51714

@hellofromtonya

Description

@hellofromtonya

Part of #41479

Reference: See the "Update 19 Jun 2023" comment.

Within the fonts management system and Font Library, the Fonts API register, deregister, and enqueue functionality are no longer "publicly" needed. Plugins will directly interact with the Font Library (when that capability is available).

What about classic themes? How could they get their fonts into the Fonts API for server-side dynamic generation and printing of @font-face styles?

Previously before the Font Library, they would programmatically register and enqueue their fonts using wp_register_fonts() and wp_enqueue_fonts(). This made sense when the Fonts API was designed to allow plugins to introduce their fonts.

Now with the new fonts management / Font Library, these functions are no longer needed for plugins. For all theme.json powered sites, these public-facing functions / methods will be disabled or removed.

If those global functions did not exist, how would a classic theme, such as Twenty Twenty-One (TT1), get their fonts into the Fonts API? See the proposal.

Proposal for Classic Themes

This proposal proposes adopting the theme.json convention for classic themes to define their fonts for the Fonts API to generate and print the @font-face styles.

Classic themes, such as Twenty Twenty-One (TT1), will define their fonts by adding a theme.json file to their theme and defining only the fontFamilies section.

Here's an example:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 2,
	"settings": {
		"typography": {
			"fontFamilies": [
				{
					"fontFace": [
						{
							"fontFamily": "DM Sans",
							"fontStretch": "normal",
							"fontStyle": "normal",
							"fontWeight": "400",
							"src": [
								"file:./assets/fonts/dm-sans/DMSans-Regular.woff2"
							]
						},
						{
							"fontFamily": "DM Sans",
							"fontStretch": "normal",
							"fontStyle": "italic",
							"fontWeight": "400",
							"src": [
								"file:./assets/fonts/dm-sans/DMSans-Regular-Italic.woff2"
							]
						},
						{
							"fontFamily": "DM Sans",
							"fontStretch": "normal",
							"fontStyle": "normal",
							"fontWeight": "700",
							"src": [
								"file:./assets/fonts/dm-sans/DMSans-Bold.woff2"
							]
						},
						{
							"fontFamily": "DM Sans",
							"fontStretch": "normal",
							"fontStyle": "italic",
							"fontWeight": "700",
							"src": [
								"file:./assets/fonts/dm-sans/DMSans-Bold-Italic.woff2"
							]
						}
					],
					"fontFamily": "\"DM Sans\", sans-serif",
					"name": "DM Sans",
					"slug": "dm-sans"
				},
				{
					"fontFace": [
						{
							"fontDisplay": "block",
							"fontFamily": "IBM Plex Mono",
							"fontStretch": "normal",
							"fontStyle": "normal",
							"fontWeight": "300",
							"src": [
								"file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Light.woff2"
							]
						},
						{
							"fontDisplay": "block",
							"fontFamily": "IBM Plex Mono",
							"fontStretch": "normal",
							"fontStyle": "normal",
							"fontWeight": "400",
							"src": [
								"file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Regular.woff2"
							]
						},
						{
							"fontDisplay": "block",
							"fontFamily": "IBM Plex Mono",
							"fontStretch": "normal",
							"fontStyle": "italic",
							"fontWeight": "400",
							"src": [
								"file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Italic.woff2"
							]
						},
						{
							"fontDisplay": "block",
							"fontFamily": "IBM Plex Mono",
							"fontStretch": "normal",
							"fontStyle": "normal",
							"fontWeight": "700",
							"src": [
								"file:./assets/fonts/ibm-plex-mono/IBMPlexMono-Bold.woff2"
							]
						}
					],
					"fontFamily": "'IBM Plex Mono', monospace",
					"name": "IBM Plex Mono",
					"slug": "ibm-plex-mono"
				},
				{
					"fontFace": [
						{
							"fontFamily": "Inter",
							"fontStretch": "normal",
							"fontStyle": "normal",
							"fontWeight": "200 900",
							"src": [
								"file:./assets/fonts/inter/Inter-VariableFont_slnt,wght.ttf"
							]
						}
					],
					"fontFamily": "\"Inter\", sans-serif",
					"name": "Inter",
					"slug": "inter"
				},
				{
					"fontFamily": "-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen-Sans,Ubuntu,Cantarell,\"Helvetica Neue\",sans-serif",
					"name": "System Font",
					"slug": "system-font"
				},
				{
					"fontFace": [
						{
							"fontFamily": "Source Serif Pro",
							"fontStretch": "normal",
							"fontStyle": "normal",
							"fontWeight": "200 900",
							"src": [
								"file:./assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2"
							]
						},
						{
							"fontFamily": "Source Serif Pro",
							"fontStretch": "normal",
							"fontStyle": "italic",
							"fontWeight": "200 900",
							"src": [
								"file:./assets/fonts/source-serif-pro/SourceSerif4Variable-Italic.ttf.woff2"
							]
						}
					],
					"fontFamily": "\"Source Serif Pro\", serif",
					"name": "Source Serif Pro",
					"slug": "source-serif-pro"
				}
			]
		}
	}
}

The Benefits of This Approach

Without this approach, classic themes would need access to wp_register_fonts() and wp_enqueue_fonts(), meaning these public facing functions need logic to disable them for theme.json themes and logic to enable them for classic themes.

With this approach, all public facing functionality except for "printing" can either be removed or hidden as interworkings.

The benefits are:

  • No logic is needed to disable or enable the public facing register, deregister, enqueue, etc functionality.
  • WP_Dependencies is no longer needed as the basis of the architecture as it's overkill for its needs, given that a bulk of the functionality would need to be disabled.
  • Significantly less BC risks.
  • Less code.
  • Less complexity.

Does it work?

YES!

I tested a copy of TT1 where I added the font assets and a theme.json file to it. Here are the testing instructions for how I did it.

Yes, it works as expected:

  • The @font-face styles were generated and printed ✅
  • The theme was recognized to use Customizer instead of Site Editor ✅

Next steps

Consensus to move forward with adopting the theme.json approach for classic themes.

Metadata

Metadata

Labels

[Status] In discussionUsed to indicate that an issue is in the process of being discussed[Type] DiscussionFor issues that are high-level and not yet ready to implement.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions