Skip to content

Font Library: revised API design #57616

@creativecoder

Description

@creativecoder

Companion issue to #55278

This issue outlines a proposed design for font management REST API endpoints.

Font Family

A font family with the settings used in theme.json format. A font family may have child font faces that are part of the family.

GET wp/v2/font-families

List the installed font families.

Font family theme.json properties are nested in font_family_settings to keep camel-cased properties out of the root level of the response, where snake-casing is required.

Request:

GET wp/v2/font-families

Response:

[
    {
        // ID of wp_font_family post
        "id": 1,
        "theme_json_version": 2,
        // Array of child font face ids
        "font_faces": [ 1007, 1008 ],
        // theme.json settings used under `settings.typography.fontFamilies`
        "font_family_settings": {
            "name": "Piazzolla",
            "fontFamily": "Piazzolla, serif",
            "slug": "piazzolla",
            "preview": "https://my-wp-site.com/wp-content/fonts/previews/piazzolla-400-normal.svg"
        },
        // See below for example `_links`
        "_links": { ... }
    },
    {
        "id": 2,
        "theme_json_version": 2,
        "font_faces": [ 1009, 1010 ],
        "font_family_settings": {
            "name": "Lobster",
            "fontFamily": "Lobster, sans-serif",
            "slug": "lobster",
            "preview": "https://my-wp-site.com/wp-content/fonts/previews/lobster-400-normal.svg"
        },
        "_links": { ... }
    },
    ...
]

GET wp/v2/font-families/<id>

Get a font family by id.

Request:

GET wp/v2/font-families/1

Response:

{
    "id": 1,
    "theme_json_version": 2,
    "font_faces": [ 258 ],
    "font_family_settings": {
        "name": "Piazzolla",
        "fontFamily": "Piazzolla, serif",
        "slug": "piazzolla"
    },
    "_links": {
        "self": [{
            "href": "https://my-wp-site.com/wp-json/wp/v2/font-families/1"
        }],
        "collection": [{
            "href": "https://my-wp-site.com/wp-json/wp/v2/font-families"
        }],
        "font_faces": [{
            "embeddable": true,
            "href": "https://my-wp-site.com/wp-json/wp/v2/font-families/1/font-faces"
        }]
    }
}

Using embeddings to get font face information, as well.

Request:

GET wp/v2/font-families/1?_embed=true
GET wp/v2/font-families/1?_embed=font_faces

Response:

{
    "id": 1,
    "theme_json_version": 2,
    "font_faces": [ 258 ],
    "font_family_settings": {
        "name": "Piazzolla",
        "fontFamily": "Piazzolla, serif",
        "slug": "piazzolla",
        "preview": "https://my-wp-site.com/wp-content/fonts/previews/piazzolla-400-normal.svg"
    },
    "_links": { ... },
    "_embedded": {
        "font_faces": [
            {
                "id": 258,
                "theme_json_version": 2,
                "parent": "1",
                "font_face_settings": {
                    "fontStyle": "normal",
                    "fontWeight":  "400",
                    "fontFamily": "Piazzolla",
                    "src": [
                         "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.ttf",
                         "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.woff2"
                    ],
                    "preview": "https://my-wp-site.com/wp-content/fonts/previews/piazzolla-400-normal.svg"
                }
            }
        ]
    }
}

POST wp/v2/font-families

Create a new font family.

Request:

POST wp/v2/font-families

{
    "theme_json_version": 2,
    "font_family_settings": {
        "name": "Piazzolla",
        "fontFamily": "Piazzolla, serif",
        "slug": "piazzolla"
    }
}

Response:

{
    "id": 1,
    "theme_json_version": 2,
    "font_faces": [],
    "font_family_settings": {
        "name": "Piazzolla",
        "fontFamily": "Piazzolla, serif",
        "slug": "piazzolla",
        "preview"
    },
    "_links": { ... }
}

POST wp/v2/font-families/<id>

Update font family by id. It merges the received data with the existing data in the font family post (the same way the wp/v2/posts endpoint works).

Request:

POST wp/v2/font-families/1

{
    "font_family_settings": {
        "fontFamily": "Piazzolla, times, serif",
    }
}

Response:

{
    "id": 1,
    "theme_json_version": 2,
    "font_faces": [ 258 ],
    "font_family_settings": {
        "name": "Piazzolla",
        "fontFamily": "Piazzolla, times, serif",
        "slug": "piazzolla"
    },
    "_links": { ... }
}

DELETE wp/v2/font-families/<id>

Delete font family by id. All child font faces and assets are deleted.

Request:

DELETE wp/v2/font-families/1

Response:

{
    "code": "rest_trash_not_supported",
    "message": "The post does not support trashing. Set 'force=true' to delete.",
    "data": { "status": 501 }
}

Request:

DELETE /font-families/1?force=true

Response:

{
    "deleted": true,
    "previous": {
        "id": 1,
        "theme_json_version": 2,
        "font_faces": [ 258 ],
        "font_family_settings": {
            "name": "Piazzolla",
            "fontFamily": "Piazzolla, times, serif",
            "slug": "piazzolla",
        }
    }
}

Font Face

Font faces that are used within a font family.

Font face theme.json properties are nested in font_face_settings to keep camel-cased properties out of the root level of the response, where snake-casing is required.

The API design uses the wp/v2/posts/<id>/revisions endpoints as a model, since that is also a nested route with a parent/child relationship.

GET wp/v2/font-families/<id>/font-faces

Get all of the font faces for a font family.

Request:

GET wp/v2/font-families/1/font-faces

Response:

[
    {
        // ID of the wp_font_face custom post type
        "id": 1835,
        "theme_json_version": 2,
        // ID of parent wp_font_family post
        "parent": "1",
        // theme.json settings used under `settings.typography.fontFamilies.fontFace`
        "font_face_settings": {
            "fontStyle": "normal",
            "fontWeight":  "400",
            "fontFamily": "Piazzolla",
            // src can be a string for a single font asset, or an array for multiple assets
            "src": [
                 "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.ttf",
                 "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.woff2"
            ],
            "preview": "https://my-wp-site.com/wp-content/fonts/previews/piazzolla-400-normal.svg"
        },
        "_links": { ... }
    },
    ...
]

GET wp/v2/font-families/<id>/font-faces/<id>

Get a single font face for a font family.

Request:

GET wp/v2/font-families/1/font-faces/1835

Response:

{
    "id": 1835,
    "theme_json_version": 2,
    "parent": "1",
    "font_face_settings": {
        "fontStyle": "normal",
        "fontWeight":  "400",
        "fontFamily": "Piazzolla",
        "src": [
             "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.ttf",
             "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.woff2"
        ],
        "preview": "https://my-wp-site.com/wp-content/fonts/previews/piazzolla-400-normal.svg"
    },
    "_links": {
        "self": [{
            "href": "https://my-wp-site.com/wp-json/wp/v2/font-families/1/font-faces/1835"
        }],
        "collection": [{
            "href": "https://my-wp-site.com/wp-json/wp/v2/font-families/1/font-faces"
        }],
        "parent": [{
            "href": "https://my-wp-site.com/wp-json/wp/v2/font-families/1"
        }]
    }
}

POST wp/v2/font-families/<id>/font-faces

Add a font face to an existing font family.

Creates one font face for a font family, stores its asset(s), and creates its preview(s). Currently, the font face assets can be added in 2 ways:

  • Provide a src that points to a binary file included in the request (multipart/form-data)
  • Provide a src property for the font face that points to a (local or remote) URL

The Content-Type is always multipart/form-data with a JSON string for the data, so that file uploads are supported when used.

Upload font face assets attached in the http request:

Request:

POST wp/v2/font-families/1/font-faces
Content-Type: multipart/form-data;

file-0-0 (binary)
file-0-1 (binary)
{
    "theme_json_version": 2,
    "font_face_settings": {
        "fontStyle": "normal",
        "fontWeight": "400",
        "fontFamily": "Piazzolla",
        // ... can include any font face properties in theme.json
        "src": [
            "file-0-0",
            "file-0-1"
        ]
    }
}

Response:

{
    "id": 1835,
    "theme_json_version": 2,
    "parent": "1",
    "font_face_settings": {
        "fontStyle": "normal",
        "fontWeight":  "400",
        "fontFamily": "Piazzolla",
        "src": [
                "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.ttf",
                "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.woff2"
         ],
         "preview": ""
    }
}

Install font definition without processing src:

Request:

POST wp/v2/font-families/1/font-faces
Content-Type: multipart/form-data;

{
    "theme_json_version": 2,
    "font_face_settings": {
        "fontStyle": "normal",
        "fontWeight":  "400",
        "fontFamily": "Piazzolla",
        "src": "https://example.com/fonts/piazzolla-400-normal.ttf"
    }
}

Response:

{
    "id": 1835,
    "parent": "1",
    "theme_json_version": 2,
    "font_face_settings": {
        "fontStyle": "normal",
        "fontWeight":  "400",
        "fontFamily": "Piazzolla",
        "src": "https://example.com/fonts/piazzolla-400-normal.ttf",
        "preview": "https://example.com/fonts/piazzolla-400-normal.ttf"
    }
}

DELETE wp/v2/font-families/<id>/font-faces/<id>

Delete one font face from a font family.

Request:

DELETE wp/v2/font-families/1/font-faces/462?force=true

Response:

{
    "deleted": true,
    "previous" : {
        "id": 462,
        "theme_json_version": 2,
        "parent": 1,
        "font_face_settings": {
            "fontStyle": "normal",
            "fontWeight": "400",
            "fontFamily": "Piazzolla",
            "src": "https://my-wp-site.com/wp-content/fonts/piazzolla-400-normal.ttf",
            "preview": "https://my-wp-site.com/wp-content/fonts/previews/piazzolla-400-normal.ttf"
        }
    }
}

Font Collections

A font collection is a list of font family definitions that can be installed.

GET wp/v2/font-collections

List font collections

Request:

GET wp/v2/font-collections

Response:

[
    {
        "slug": "collection-example",
        "name": "Collection Example",
        "description": "This a Font Collection Example",
        "font_families": [
	    {
                "categories": [ "sans-serif" ],
                    "font_family_settings": {
                    "name": "Roboto",
                    "fontFamily": "Roboto, sans-serif",
                    "slug": "roboto",
                    "category": "sans-serif",
                    "fontFace": [
                        {
                            "src": "https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgWxPKTM1K9nz.ttf",
                            "fontWeight": "400",
                            "fontStyle": "normal",
                            "fontFamily": "Roboto",
                            "preview": "https://s.w.org/images/fonts/16.7/previews/roboto/roboto-400-normal.svg"
                        },
                        {
                            "src": "https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrIzcXLsnzjYk.ttf",
                            "fontWeight": "400",
                            "fontStyle": "italic",
                            "fontFamily": "Roboto",
                            "preview": "https://s.w.org/images/fonts/16.7/previews/roboto/roboto-400-italic.svg"
                        }
                    ]
                }
            }
        ],
        "categories": [
            {
                "slug": "sans-serif",
                "name": "Sans Serif"
            }
        ]
    },
    {
        "slug": "default-font-collection",
        "name": "Google Fonts",
        "description": "Google Fonts collection.",
        "font_families": [
            // font familiy objects
        ]
        "categories": [
            // category objects
        ]
    }
]

GET wp/v2/font-collections/

Get font collection by slug.

Request:

GET wp/v2/font-collections/collection-example

Response:

{
    "slug": "collection-example",
    "name": "Collection Example",
    "description": "Example font collection.",
    "theme_json_version": 2,
    "font_families": [
        {
            "categories": [ "sans-serif" ],
            "font_family_settings": {
                "name": "Roboto",
                "fontFamily": "Roboto, sans-serif",
                "slug": "roboto",
                "category": "sans-serif",
                "fontFace": [
                    {
                        "src": "https://fonts.gstatic.com/s/roboto/v30/KFOkCnqEu92Fr1MmgWxPKTM1K9nz.ttf",
                        "fontWeight": "400",
                        "fontStyle": "normal",
                        "fontFamily": "Roboto",
                        "preview": "https://s.w.org/images/fonts/16.7/previews/roboto/roboto-400-normal.svg"
                    },
                    {
                        "src": "https://fonts.gstatic.com/s/roboto/v30/KFOiCnqEu92Fr1Mu51QrIzcXLsnzjYk.ttf",
                        "fontWeight": "400",
                        "fontStyle": "italic",
                        "fontFamily": "Roboto",
                        "preview": "https://s.w.org/images/fonts/16.7/previews/roboto/roboto-400-italic.svg"
                    },
                ]
            }
        }
    ],
    "categories": [
        {
            "slug": "sans-serif",
            "name": "Sans Serif"
        }
    ]
}

Activating Font Families and Font Faces

Activating a font family and/or font faces is done by directly updating Global Styles using the existing endpoint (wp/v2/global-styles), since adding the fonts to the Global Styles settings is what adds them as typography options for styles across the site.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Global StylesAnything related to the broader Global Styles efforts, including Styles Engine and theme.json[Feature] Font Library[Feature] TypographyFont and typography-related issues and PRs[Type] DiscussionFor issues that are high-level and not yet ready to implement.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions