Make WordPress Core

Opened 8 months ago

Closed 6 months ago

Last modified 6 months ago

#61021 closed enhancement (fixed)

REST API: Add stylesheet_uri and template_uri fields to themes endpoint

Reported by: andrewserong's profile andrewserong Owned by: timothyblynjacobs's profile TimothyBlynJacobs
Milestone: 6.6 Priority: normal
Severity: normal Version: 6.6
Component: REST API Keywords: has-patch has-unit-tests
Focuses: Cc:

Description

The themes REST API endpoint response currently does not contain the base urls for the installed theme (or its template if it's a child theme). This means that it isn't possible to use the REST API in order to construct relative paths to a theme's directory.

For block editor based features, such as working with background images, it would be useful to be able to grab the current theme's base URL in order to be able to construct theme-relative urls.

One neat way to do this is if the response when requesting a particular theme via the REST API endpoint also included the following:

  • stylesheet_uri – the URI to the current theme's directory
  • template_uri — the URI to the parent theme's directory (if a child theme)

In this way, if someone knows a theme relative path such as assets/background-texture.jpg, within the block editor, the full URI could be constructed via prepending the stylesheet_uri from the REST API response.

Note: this enhancement request is not to be confused with the existing theme_uri field. That field points to where the theme can be downloaded from the theme directory, for example, whereas this ticket is proposing exposing the installed path for the theme as it exists on the hosted site.

Change History (20)

#1 @andrewserong
8 months ago

For reference to a WIP block editor feature where this would be a useful enhancement, see: https://github.com/WordPress/gutenberg/pull/60578

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


8 months ago
#2

  • Keywords has-patch added

Based on an idea from @ramonjd and @noisysocks in https://github.com/WordPress/gutenberg/pull/60578/, this PR explores adding stylesheet_uri and template_uri fields to the API response for the themes endpoint. The goal being to expose the URI of the directory for a theme (or its parent theme when dealing with child themes) so that theme relative URIs can be constructed by consumers of this endpoint. An example use case is in https://github.com/WordPress/gutenberg/pull/60578/

Note: I have not updated tests yet. For now, I thought I'd put up this PR in order to gather feedback on the idea. Happy to add tests / tweak as needed based on feedback.

A quick way to test this is to apply the PR and then open up the post editor and run the following from the console:

wp.apiFetch( { path: '/wp/v2/themes/twentytwentyfour' } );

In the API response, you should see stylesheet and template uris in the response:

https://github.com/WordPress/wordpress-develop/assets/14988353/fe845714-0d9c-42de-aa4c-0b9e2c117f21

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

@andrewserong commented on PR #6399:


8 months ago
#3

I've updated and added tests. A few questions for anyone reviewing:

  • These two fields refer to the directory, should that be in the name as well, or is stylesheet_uri and template_uri straightforward enough?
  • Other fields have raw and rendered versions of the URI (i.e. author_uri and theme_uri are objects with raw and rendered keys). Should we do that for these, too? My assumption is that since these new fields are meant to be used to construct URIs rather than to be displayed, the answer would be no. But for consistency it might be confusing if these are just strings.
  • Are these values safe to expose in this way? I.e. if you have permission to get all the other data from this endpoint, is this extra data consistent with the current permissions / capabilities?

@TimothyBlynJacobs commented on PR #6399:


8 months ago
#4

It seems unexpected that this is not applying the stylesheet_directory_uri because it isn't using the global get_stylesheet_directory_uri function. We probably need to alter how the response is prepared if it's the current theme or not. See the is_same_theme helper.

@andrewserong commented on PR #6399:


8 months ago
#5

Thanks for the review @TimothyBJacobs!

It seems unexpected that this is not applying the stylesheet_directory_uri because it isn't using the global get_stylesheet_directory_uri function

Good catch! I've updated the logic in https://github.com/WordPress/wordpress-develop/pull/6399/commits/b1dd7ff35e3da3adc786ded589bd99d66bcd643e so that it calls the global functions for both the template directory uri and the stylesheet directory uri if the current theme matches the requested theme, so I believe this should hook into those filters now. I'm not very familiar with this part of the code base, though, so do let me know if there's anything off with this approach.

Thanks!

@noisysocks commented on PR #6399:


8 months ago
#6

Gave this for a spin locally by checking the branch out and creating a child theme of TT4 called tt4-child:

wordpress-develop % http -a "admin:password" GET http://localhost:8889/wp-json/wp/v2/themes | jq '.[] | { stylesheet, status, template_uri, stylesheet_uri }'
{
  "stylesheet": "tt4-child",
  "status": "active",
  "template_uri": "http://localhost:8889/wp-content/themes/twentytwentyfour",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/tt4-child"
}
{
  "stylesheet": "twentyeleven",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentyeleven",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentyeleven"
}
{
  "stylesheet": "twentyfifteen",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentyfifteen",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentyfifteen"
}
{
  "stylesheet": "twentyfourteen",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentyfourteen",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentyfourteen"
}
{
  "stylesheet": "twentynineteen",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentynineteen",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentynineteen"
}
{
  "stylesheet": "twentyseventeen",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentyseventeen",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentyseventeen"
}
{
  "stylesheet": "twentysixteen",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentysixteen",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentysixteen"
}
{
  "stylesheet": "twentyten",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentyten",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentyten"
}
{
  "stylesheet": "twentythirteen",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentythirteen",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentythirteen"
}
{
  "stylesheet": "twentytwelve",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentytwelve",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentytwelve"
}
{
  "stylesheet": "twentytwenty",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentytwenty",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentytwenty"
}
{
  "stylesheet": "twentytwentyfour",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentytwentyfour",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentytwentyfour"
}
{
  "stylesheet": "twentytwentyone",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentytwentyone",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentytwentyone"
}
{
  "stylesheet": "twentytwentythree",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentytwentythree",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentytwentythree"
}
{
  "stylesheet": "twentytwentytwo",
  "status": "inactive",
  "template_uri": "http://localhost:8889/wp-content/themes/twentytwentytwo",
  "stylesheet_uri": "http://localhost:8889/wp-content/themes/twentytwentytwo"
}

@ramonopoly commented on PR #6399:


8 months ago
#7

Thanks for working on this 🙇🏻 LGTM!

@andrewserong commented on PR #6399:


8 months ago
#8

Thanks for all the reviews, everyone! I'll be AFK over the next week, so in case there's any further feedback, I won't be able to get to it until the week after. In the meantime, feel free to commit to this branch if anyone would like to make changes, (or commit the changeset if this feels like it's in a good enough place). Cheers!

#9 @TimothyBlynJacobs
8 months ago

  • Milestone changed from Awaiting Review to 6.6
  • Owner set to TimothyBlynJacobs
  • Status changed from new to accepted

This ticket was mentioned in Slack in #core-editor by bph. View the logs.


8 months ago

#11 @oglekler
7 months ago

  • Keywords needs-testing added

This ticket was mentioned in Slack in #core by nhrrob. View the logs.


7 months ago

#13 @hellofromTonya
7 months ago

  • Keywords has-unit-tests added

Patch: https://github.com/WordPress/wordpress-develop/pull/6399

Has an update to the unit tests.

This ticket was mentioned in Slack in #core-test by umeshsingla. View the logs.


7 months ago

#15 @Dharm1025
6 months ago

  • Keywords needs-testing removed

Test Report

Description

Thanks for working on this @andrewserong, the patch works as expected.

Patch tested: https://github.com/WordPress/wordpress-develop/pull/6399

Environment

  • WordPress: 6.6-alpha-57778-src
  • PHP: 8.2.19
  • Server: nginx/1.27.0
  • Database: mysqli (Server: 8.0.37 / Client: mysqlnd 8.2.19)
  • Browser: Chrome 125.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Four Child 1.0
  • MU Plugins: None activated
  • Plugins:
    • Test Reports 1.1.0

Actual Results

  1. ✅ The template_uri and stylesheet_uri fields are added to the response and work as expected for both child and parent themes.
  2. ✅ The stylesheet_directory_uri filter works for the active theme
  3. ✅ The template_directory_uri filter works for the active theme

#16 @TimothyBlynJacobs
6 months ago

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

In 58282:

REST API: Add stylesheet and template URI fields to the Themes API.

Props andrewserong, timothyblynjacobs, noisysocks, ramonopoly, peterwilsoncc, Dharm1025.
Fixes #61021.

@TimothyBlynJacobs commented on PR #6399:


6 months ago
#17

Merged in r58282.

@ramonopoly commented on PR #6399:


6 months ago
#18

Should we also sync these changes to Gutenberg?

There's currently no feature that relies on these properties, but maybe it should be synced to compat/6.6 in case that changes between now and 6.9 (when support for 6.6 is dropped in the plugin).

It's likely these properties will be needed to resolve relative asset paths in template/pattern files.

I'd already synced the REST change for a previous experiment so I threw up a PR just in case:

@andrewserong commented on PR #6399:


6 months ago
#19

Good idea @ramonjd — yes, even though there are no features depending on it, I think it'd be good to have parity for the feature in Gutenberg to make it easier to use if need be.

#20 @desrosj
6 months ago

In 58408:

Coding Standards: Apply changes after running composer format.

This applies several formatting related changes made while running composer format.

Follow up to [55720], [58171], [58271], [58282], [58283], [58292], [58299], [58303], [58332].
See #51857, #60719, #60895, #61021, #61118, #61228, #61276, #61324.

Note: See TracTickets for help on using tickets.