Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fonts API] How to handle duplicate font variations #40288

Closed
zaguiini opened this issue Apr 13, 2022 · 4 comments
Closed

[Fonts API] How to handle duplicate font variations #40288

zaguiini opened this issue Apr 13, 2022 · 4 comments

Comments

@zaguiini
Copy link
Member

zaguiini commented Apr 13, 2022

Part of #41479.

What problem does this address?

It's not clear to the end-user how the Fonts API will behave regarding the registration and enqueueing of duplicated font variations.

Only enqueued fonts are added as inline styles in the front-end.

API scenarios

Trying to register a font face that was already registered
wp_register_fonts(
	array(
		'Roboto' => array(
			'font-family'  => 'Roboto',
			'font-style'   => 'regular',
			'font-stretch' => 'normal',
			'font-weight'  => '400',
			'provider'     => 'google',
		),
	)
);

wp_register_fonts(
	array(
		'Roboto' => array(
			'font-family'  => 'Roboto',
			'font-style'   => 'regular',
			'font-stretch' => 'normal',
			'font-weight'  => '400',
			'provider'     => 'local',
		),
	)
);

Which one should take precedence? The one that already exists, or the one that they're trying to re-register?


Trying to register a font-family that was already enqueued
wp_register_fonts(
	array(
		'Roboto' => array(
			'font-family'  => 'Roboto',
			'font-style'   => 'regular',
			'font-stretch' => 'normal',
			'font-weight'  => '400',
			'provider'     => 'google',
		),
	)
);

wp_enqueue_fonts( array 'Roboto' ) );

wp_register_fonts(
	array(
		'Roboto' => array(
			'font-family'  => 'Roboto',
			'font-style'   => 'regular',
			'font-stretch' => 'normal',
			'font-weight'  => '400',
			'provider'     => 'local',
		),
	)
);

What should happen?

  • Should we dequeue the enqueued font and add the newly registered font to the registered fonts list?
  • Should we just ignore the re-registration attempt?
  • Should we keep the enqueued face there and add the newly registered font to the registered list?

Scenarios including theme.json

After #39988 gets merged, new scenarios will come up now that we're considering theme.json as the source of truth for themes that are using this file.

Trying to register and enqueue, through theme.json, a font face that was registered programmatically

In PHP:

wp_register_webfont(
  array(
    'font-family'  => 'Roboto',
    'font-style'   => 'regular',
    'font-stretch' => 'normal',
    'font-weight'  => '400',
    'provider'     => 'google',
  ),
);

In theme.json:

{
  "fontFamily": "Roboto",
  "slug": "roboto",
  "name": "Roboto",
  "provider": "local",
  "fontFaces": [
    {
      "fontFamily": "Roboto",
      "fontWeight": "400",
      "fontStyle": "regular",
      "src": "file:./assets/fonts/Roboto-Regular.ttf"
    }
  ]
}

Should we de-register/override the programmatically registered font face? Remember that we're trying to make theme.json the source of truth.

Current behavior in #39988: both are added to the registered list.

However, the programmatically registered webfont is the one that gets enqueued. That's because it's found first when looking for registered font faces to enqueue and their attributes are equal (the provider is not taken into account in the comparison).


Trying to register and enqueue, through theme.json, a font face that was enqueued programmatically

In PHP:

wp_register_webfont(
  array(
    'font-family'  => 'Roboto',
    'font-style'   => 'regular',
    'font-stretch' => 'normal',
    'font-weight'  => '400',
    'provider'     => 'google',
  ),
);

wp_enqueue_webfont( 'Roboto' );

In theme.json:

{
  "fontFamily": "Roboto",
  "slug": "roboto",
  "name": "Roboto",
  "provider": "local",
  "fontFaces": [
    {
      "fontFamily": "Roboto",
      "fontWeight": "400",
      "fontStyle": "regular",
      "src": "file:./assets/fonts/Roboto-Regular.ttf"
    }
  ]
}

Should we dequeue the programmatically enqueued and instead register + enqueue the theme.json face?

Current behavior in #39988: both are enqueued.

Additional information

This problem is not a blocker for #39988 since that PR addresses a different matter. The above-mentioned behavior is already happening in trunk and #39988 is not the appropriate place to fix it.

@zaguiini zaguiini added [Priority] High Used to indicate top priority items that need quick attention [Feature] Webfonts labels Apr 13, 2022
@zaguiini zaguiini self-assigned this Apr 13, 2022
@zaguiini
Copy link
Member Author

Would definitely like some input here.

cc @creativecoder @jeyip @mattwiebe @Addison-Stavlo @hellofromtonya @mtias @aristath

@desrosj
Copy link
Contributor

desrosj commented Apr 18, 2022

I've been thinking about this a bit today. Here are some thoughts!

First, I agree that this is important and a high priority to solve. However, I think that I would not necessarily classify this as a blocker for including this in WordPress 6.0 provided only the fonts used are enqueued and there are no significant performance pitfalls.

It's not clear to the end-user how the Webfonts API will behave regarding the registration and enqueueing of duplicated font faces.

I don't think the end-user should ever need to be aware of the Webfonts API, or what's happening behind the scenes. The API itself should make the best decisions it can based on the information provided when fonts are registered through the API. If a user selects a font through the site editor, it should load based on the logic defined in the API. I think that the fonts API should behave similarly to the scripts/styles APIs in a number of ways, and the user not having to be aware of what's going on is one.

For registering scripts, once a script is registered all subsequent wp_register_script() calls have no effect. This eliminates the questions around which script is used. Scripts registered by Core get first priority, and then they are added first come, first serve. The fonts API is a bit different because one font can have multiple variations. But only unique variations should be registered. I'm thinking that we could decide on a set of arguments to use for comparing variations and determining when an "identical" one is registered. For example, maybe font-family, font-style, and font-weight are used and when a variation is already registered with matching values, the new one being registered to wp_register_webfont() is not added.

If this logic is used, then wp_deregister_webfont() would need to be added as a way to override fonts registered by other plugins/themes. I think there's also value in adding this function regardless (maybe a site wants to use a plugin that happens to register a font family that they want to remove as an option entirely).

In the scenarios described above, fonts defined within a theme's theme.json file should always be registered first. Then others can be registered on a first come first serve basis, or a plugin can override them by unregistering.

@hellofromtonya hellofromtonya removed the [Priority] High Used to indicate top priority items that need quick attention label Jun 23, 2022
@spacedragn
Copy link

spacedragn commented Aug 17, 2022

I disagree – this is a High Priority need.

After testing this feature, I’m stuck with multiple registered and enqueued webfonts that point to dead links. As an experienced dev, I have no clue how to remove these from the frontend. I’ve spent over 5 hours pouring over docs and issues here to discover this one ticket. Others must be facing this same frustration.

Is there any workaround to purge this old data?

@hellofromtonya hellofromtonya changed the title Webfonts API: registration and enqueueing ambiguity [Fonts API] How to handle duplicate font variations Apr 5, 2023
@hellofromtonya
Copy link
Contributor

Update:

This issue is no longer valid for the Fonts API once the Font Library is merged.

Why?

As shared in Ongoing Roadmap update #41479 (comment), the Fonts API's role changes to :

Generate and print the @font-face styles for all theme defined and user activated fonts.

Font families and variations will no longer be "registered" or "enqueued" into the Fonts API. Rather, the font management through the Font Library will handle the user workflow. The decision making will no longer be in the Fonts API.

Instead, the Fonts API will get / pull the fonts to be processed from Theme JSON merged data layer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants