Make WordPress Core

Opened 2 months ago

Closed 8 weeks ago

Last modified 8 weeks ago

#60509 closed defect (bug) (fixed)

Font Collection: Font name and description are not translatable

Reported by: wildworks's profile wildworks Owned by: swissspidy's profile swissspidy
Milestone: 6.5 Priority: normal
Severity: normal Version: 6.5
Component: Editor Keywords: has-patch
Focuses: Cc:

Description

My understanding is that font collections are registered via wp_register_font_collection
, and if that data was a JSON file, it would read the name and description fields.

https://github.com/WordPress/wordpress-develop/blob/cb522a3b25a062983e7ba44c2370dbf611a96c67/src/wp-includes/fonts.php#L76-L78

Since these two strings do not exist in the core, I am concerned that they may not be translatable.

Attachments (1)

font-library-modal.png (23.2 KB) - added by wildworks 2 months ago.
Font Library Modal

Download all attachments as: .zip

Change History (43)

@wildworks
2 months ago

Font Library Modal

#1 @swissspidy
2 months ago

  • Component changed from General to Editor
  • Keywords needs-patch added
  • Milestone changed from Awaiting Review to 6.5
  • Version set to trunk

Looks like you're right.

I didn't realize those came from the API.

The categories ("Handwriting", "Display") don't seem to be translatable either.

This definitely needs to be addressed.

cc @youknowriad

#2 @wildworks
2 months ago

Just in case, I would like to explain the problem in a little more detail.

The current font collection is registered here:

https://github.com/WordPress/wordpress-develop/blob/edfdeaa105cdbf9765cbae1c39a6db6926a02abf/src/wp-includes/fonts.php#L199

And this JSON file is being loaded.

https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json

#3 follow-up: @youknowriad
2 months ago

Maybe we can do here something similar to block.json and theme.json translations?

#4 @get_dave
2 months ago

we can do here something similar to block.json and theme.json translations?

Could you point to a code/documentation reference for the method utilised?

It would seem name and description and categories all need to be translatable. What value is there to having these encoded in the JSON and not just provided as an argument in PHP when you call wp_register_font_collection()?

https://github.com/WordPress/wordpress-develop/blob/edfdeaa105cdbf9765cbae1c39a6db6926a02abf/src/wp-includes/fonts.php#L76-L78

#5 @youknowriad
2 months ago

For theme.json we have an i18n's schema that we use to pass the whole theme.json file through translation strings.

More details here https://github.com/WordPress/wordpress-develop/blob/4fe09a2df3a3cd8360228051955f66ebf1033374/src/wp-includes/class-wp-theme-json-resolver.php#L144-L151

---
That said, if the name, categories and description are the only thing that we want to translate, then I agree that we could consider updating the wp_register_font_collection function from this:

wp_register_font_collection( 'google-fonts', 'https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json' );

To this

wp_register_font_collection( 'google-fonts', array( 
  'source' => 'https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json',  // or file
  "name" => __( "Google Fonts" ),
  "description" => __( "Install from Google Fonts. Fonts are copied to and served from your site." ),
  "categories" => [
		[
			"name": __( "Sans Serif" ),
			"slug": "sans-serif"
		]
  ],
) );

Now that I think about it more, I think we should update wp_register_font_collection to accept an array of options as a second argument regardless of how we'll do i18n. The reasons for that are:

  • Consistency with most registration APIs in WordPress
  • Possibility to add new options... in the future, where a string argument won't allow.

#6 in reply to: ↑ 3 @swissspidy
2 months ago

Replying to youknowriad:

Maybe we can do here something similar to block.json and theme.json translations?

But those files are in source control. The font collection file is retrieved from another server and can change any moment. So that doesn't work.

Unless we move this file to version control, I think updating wp_register_font_collection is the only way.

Maybe you can elaborate why this file is loaded from the CDN right now?

#7 @youknowriad
2 months ago

Maybe you can elaborate why this file is loaded from the CDN right now?

I think @mmaattiiaass and @grantmkin would probably have more context here but If I'm understanding properly:

  • Performance: To lazy load the files: only load the fonts on usage, not registration.
  • Update: To be able to update the collections outside the WP update lifecycle.
  • It's also a huge file (2.3m)

#8 @mmaattiiaass
2 months ago

If I'm understanding properly:

  • Performance: To lazy load the files: only load the fonts on usage, not registration.
  • Update: To be able to update the collections outside the WP update lifecycle.
  • It's also a huge file (2.3m)

@youknowriad, yes, those were the main considerations.


Unless we move this file to version control

@swissspidy Would that be possible?

Unless we move this file to version control, I think updating wp_register_font_collection is the only way.

I don't think that updating the function signature as suggested here (https://core.trac.wordpress.org/ticket/60509#comment:5) would solve the problem because, in that case, font family names can't be translated, so the problem persists.


Now that I think about it more, I think we should update wp_register_font_collection to accept an array of options as a second argument regardless of how we'll do i18n.

@youknowriad This is currently working like that. See these 2 examples:

    $my_collection = array(
        'name'          => 'PHP Custom Collection',
        'description'   => __( 'Custom fonts collection' ),
        'font_families' => $font_families,
        'categories'    => $categories
    );
    
    wp_register_font_collection( 'my-collection', $my_collection );

and

wp_resgiter_font_collection( "my-collection", "/path/to/json.json"  );

both are valid.

#9 @swissspidy
2 months ago

Would that be possible?

Sure, why not? I don‘t think the file size is an issue for something (maybe for updates?). Lazy loading can be done with a local file as well.

Of course then you couldn’t update the files outside the release cycle.

font family names can't be translated, so the problem persists.

Do they need to be? Are they typically translated? How do other projects handle that?

#10 @wildworks
2 months ago

My understanding is that this JSON file is generated via the Google Fonts API: https://github.com/WordPress/google-fonts-to-wordpress-collection/blob/d6b5d580cfdba1c57f9f14bcca3fb398166786ce/src/constants.js#L2-L3

Also, looking at the API documentation, it appears that there is no way to localize font names: https://developers.google.com/fonts/docs/developer_api

Furthermore, even if you change the browser language to something other than English and access https://fonts.google.com/, the font names and category names will remain in English.

Therefore, at least for Google fonts, localized names for font names and categories may not officially exist. However, I am concerned that if these are not localized, there will be inconsistencies, especially if the language of the WordPress site is changed to an RTL language.

#11 @swissspidy
2 months ago

@mmaattiiaass @wildworks Are font names typically translated? How do other projects handle that? Are font names translated in Google Docs or MS Office?

If we want to translate all font names from Google Fonts, we would need to do it ourselves. But asking polyglots to translate 1600 (!) font names is a lot! We would need to create a separate translation project for this on translate.wordpress.org (like continents & cities), update language packs, update WP-CLI, etc. I don't think this is feasible for 6.5.

For the sake of this ticket I'd suggest focusing on collection name & description for now. Translating font names is a whole different beast and would warrant its own ticket due to the increased scope.


Now that I think about it more, I think we should update wp_register_font_collection to accept an array of options as a second argument regardless of how we'll do i18n.

This is currently working like that. See these 2 examples:

But it's not possible to provide a JSON file AND options, which is what Riad suggested.

#12 @NekoJonez
2 months ago

Polyglot for Dutch and Flemish here. We dont translate font names. Since some font names are brandnames and copyright protected.

Also, afaik... Office doesnt translate font names either.

I went to various plugins and as far as I can see... Other locales dont translate font names either. See examples here: https://translate.wordpress.org/projects/wp-plugins/mailpoet/dev/nl-be/default/?filters%5Bterm%5D=Font+family&filters%5Bterm_scope%5D=scope_any&filters%5Bstatus%5D=either&filters%5Buser_login%5D=&filter=Apply+Filters&sort%5Bby%5D=translation_date_modified&sort%5Bhow%5D=desc

Also, if you look up a font like Comic Sans on Wikipedia, you notice that only one locale translated it: https://nl.m.wikipedia.org/wiki/Comic_Sans#/languages

I'll throw this in #polyglots but font names arent usually translated afaik.

This ticket was mentioned in Slack in #polyglots by nekojonez. View the logs.


2 months ago

#14 @swissspidy
2 months ago

@youknowriad @mmaattiiaass @grantmkin This one needs an owner to shepherd a fix during beta. Any volunteers?

I don't think we really want to put this in version control, so the more viable option is to provide a URL _and_ name + description separately.

To prevent devs from forgetting this and have untranslated strings, I suggest to change the function signature for registering fonts as follows:

wp_register_font_collection(
  $slug: string,
  $data: array<{ url?: string, name: string, description?: string, font_families?: array, categories?: array}>

So for core it would be:

wp_register_font_collection(
'google-fonts',
array(
  'url' => 'https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json',
  'name' => __( 'Google Fonts' ),
  'description' => __( 'Install from Google Fonts. Fonts are copied to and served from your site.' ), 
),

But plugins could do:

wp_register_font_collection(
'google-fonts',
array(
  'font_families' => [...],
  'categories' => [...],
  'name' => __( '...', 'foo-plugin' ),
  'description' => __( '...', 'foo-plugin' ), 
),

Definitely want to prevent the wp_register_font_collection( 'xyz', 'url...' ) use case with that.

What do you think?


Aside: why is the Gutenberg version in the https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json URL, shouldn't that be the WordPress version?

#15 @youknowriad
2 months ago

Yes, that's similar to my suggestion above https://core.trac.wordpress.org/ticket/60509#comment:5

@mmaattiiaass Is this something you can work on?

#16 @mmaattiiaass
2 months ago

wp_register_font_collection(
  $slug: string,
  $data: array<{ url?: string, name: string, description?: string, font_families?: array, categories?: array}>

This looks good, but, using this format the extenders could provide url and font-families at the same time. That would require extra checking and could be confusing.

What do you think of removing url and make font_families accept both a string (an URL to a json file) or an array (a list of font families)?

wp_register_font_collection(
  $slug: string,
  $data: array<{ name: string, description?: string, font_families: array|string, categories?: array}>
Last edited 2 months ago by mmaattiiaass (previous) (diff)

#17 @swissspidy
2 months ago

But the JSON file/URL right contains both families and categories, not just families. Would you change that?
If not, I don‘t think a little extra check & documentation is bad.

#18 @grantmkin
2 months ago

But the JSON file/URL right contains both families and categories, not just families.

I think it's important to translate category names, as well, since those are used in the UI for filtering which fonts in the collection are displayed.

#19 @swissspidy
2 months ago

I think we've already established that those need to be translated. My comment was just about the data format / type.

Anyhow, I'm currently looking into this and trying to whip up a quick proof of concept to fix this issue.

This ticket was mentioned in PR #6130 on WordPress/wordpress-develop by @swissspidy.


2 months ago
#20

  • Keywords has-patch has-unit-tests added; needs-patch removed

Changes the data format as per the suggestion on the ticket.

In practice not really a fan of using _doing_it_wrong() everywhere instead of using proper exceptions, but alas.

Trac ticket: https://core.trac.wordpress.org/ticket/60509

@swissspidy commented on PR #6130:


2 months ago
#21

cc @matiasbenedetto

#22 @swissspidy
2 months ago

  • Keywords needs-patch added; has-patch has-unit-tests removed

@mmaattiiaass commented on PR #6130:


2 months ago
#23

I noticed one could indicate both categories and src without warning. I think that can be confusing.

Thinking it again that check is unwanted because it will prevent us provide categories to a list of fonts coming from a JSON file.

Let us remove this check and add the categories for translation in the PHP code.

$categories = array(
    array(
        "name" => __( 'Sans Serif' ),
        "slug" => "sans-serif"
    ),
    array(
        "name" => __( 'Display' ),
        "slug" => "display"
    ),
    array(
        "name" => __( 'Serif' ),
        "slug" => "serif"
    ),
    array(
        "name" => __( 'Handwriting' ),
        "slug" => "handwriting"
    ),
    array(
        "name" => __( 'Monospace' ),
        "slug" => "monospace"
    )
);

#24 @grantmkin
2 months ago

I think we've already established that those need to be translated. My comment was just about the data format / type.

Sorry to be unclear @swissspidy . My intended point was that since category names need to be translated, it seems that we should remove categories from the font collection json schema (and the Google fonts collection json file), and have categories only be provided in PHP. That way category names can always be translated.

@mmaattiiaass commented on PR #6130:


2 months ago
#25

Noting that after this PR lands we need to update the font-collection JSON schema: https://github.com/WordPress/gutenberg/blob/trunk/schemas/json/font-collection.json

@swissspidy commented on PR #6130:


2 months ago
#26

Noting that after this PR lands we need to update the font-collection JSON schema: WordPress/gutenberg@`trunk`/schemas/json/font-collection.json

Speaking of schema, the code references https://schemas.wp.org/trunk/font-collection.json but that doesn't actually exist yet.

@grantmkin commented on PR #6130:


2 months ago
#27

Speaking of schema, the code references https://schemas.wp.org/trunk/font-collection.json but that doesn't actually exist yet.

The schema is present at https://github.com/WordPress/gutenberg/blob/trunk/schemas/json/font-collection.json, but it seems the redirect isn't working correctly for that one. Both block.json and theme.json schemas redirect from schemas.wp.org/* to raw.githubusercontent.com/WordPress/gutenberg/*

@grantmkin commented on PR #6130:


2 months ago
#28

Given how this is evolving, potentially trimming down the collection json file to only contain font_families, I wonder if it makes sense to have font_families as a separate parameter:

wp_register_font_collection( $slug, $font_families, $args ), where $font_families is an array of font families, or a path/url to a json file. The main benefit I see is that it helps highlight that defining the font_families is the most important part of the collection data, and makes it more visible that there are 2 possible formats (PHP array or json) with it not nested next to the other collection info.

@youknowriad commented on PR #6130:


2 months ago
#29

wp_register_font_collection( $slug, $font_families, $args ), where $font_families is an array of font families, or a path/url to a json file. The main benefit I see is that it helps highlight that defining the font_families is the most important part of the collection data, and makes it more visible that there are 2 possible formats (PHP array or json) with it not nested next to the other collection info.

@swissspidy commented on PR #6130:


2 months ago
#30

So, who can help update the JSON file, the schema, and fix the schema redirect?

@mmaattiiaass commented on PR #6130:


2 months ago
#31

So, who can help update the JSON file, the schema, and fix the schema redirect?

I requested the schema redirect here: https://meta.trac.wordpress.org/ticket/7476#ticket

@mmaattiiaass commented on PR #6130:


2 months ago
#32

Personally, I think we should stick with wp_register_font_collection( $slug, $args ) for consistency with all the registration APIs in core. I don't mind if the font_families key is either a url or a static collection.

OK, so the signature of the function will be like this, right?

wp_register_font_collection(
  $slug: string,
  $data: array<{
     name: string,
     description?: string,
     font_families: array|string,
     categories?: array
 }>

Both of these use cases will be allowed.

  1. Provide the font families as a JSON file URL or path.
$categories = array(
    array(
        "name" => __( 'Sans Serif' ),
        "slug" => "sans-serif"
    ),
);

wp_register_font_collection(
        'google-fonts',
        array(
                'src'         => 'https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json',
                'name'        => __( 'Google Fonts' ),
                'description' => __( 'Install from Google Fonts. Fonts are copied to and served from your site.' ),
                'categories'  => $categories,
        )
);
  1. Provide font families as a PHP array:
    $ubuntu = array(
        'fontFamily' => 'Ubuntu, system-ui',
        'name'        => 'Ubuntu',
        'slug'          => 'ubuntu',
    );
    
    wp_register_font_collection(
            'google-fonts',
            array(
                    'src' => 'https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json',
                    'name' => __( 'Google Fonts' ),
                    'description' => __( 'Install from Google Fonts. Fonts are copied to and served from your site.' ),
                    'categories' => $categories,
                    'font_families' => [ $ubuntu ],
            )
    );
    

@mmaattiiaass commented on PR #6130:


2 months ago
#33

So, who can help update the JSON file, the schema, and fix the schema redirect?

@swissspidy you can find an updated version of the file in this PR: https://github.com/WordPress/google-fonts-to-wordpress-collection/pull/21. To test, these changes, you are able to link the PR version of that JSON file https://raw.githubusercontent.com/WordPress/google-fonts-to-wordpress-collection/e9037d48ec56988dbaa7036186619415ef6761f7/releases/core-6.5.beta/google-fonts-with-preview.json.

@swissspidy commented on PR #6130:


2 months ago
#34

Thanks for the help!

The signature

wp_register_font_collection(
  $slug: string,
  $data: array<{
     name: string,
     description?: string,
     font_families: array|string,
     categories?: array
 }>

sounds good to me 👍

I just updated the PR accordingly.

It uses https://raw.githubusercontent.com/WordPress/google-fonts-to-wordpress-collection/e9037d48ec56988dbaa7036186619415ef6761f7/releases/core-6.5.beta/google-fonts-with-preview.json for testing, but since the data structure is still the same as https://s.w.org/images/fonts/17.7/collections/google-fonts-with-preview.json, just with fewer keys, I should be able to just change it back with no issues. So nicely backward compatible.

@swissspidy commented on PR #6130:


2 months ago
#35

@matiasbenedetto @youknowriad @creativecoder I think this is now ready

#36 @swissspidy
2 months ago

  • Keywords has-patch added; needs-patch removed
  • Owner set to swissspidy
  • Status changed from new to assigned

@mmaattiiaass commented on PR #6130:


2 months ago
#37

This is testing well on my end.
I think it's ready to be merged.

cc. @youknowriad

@youknowriad commented on PR #6130:


8 weeks ago
#38

Once this is committed, let's also make sure to synchronize the Gutenberg plugin properly. Thanks all for addressing this one.

#40 @swissspidy
8 weeks ago

  • Resolution set to fixed
  • Status changed from assigned to closed

Fixed in [57686]

@mmaattiiaass commented on PR #6130:


8 weeks ago
#41

Porting the changes from this PR to Gutenberg: https://github.com/WordPress/gutenberg/pull/59256

#42 @get_dave
8 weeks ago

Thanks to everyone for shepherding this through.

Note: See TracTickets for help on using tickets.