Skip to content

Store template paths as global variables - #5926

Closed
joemcgill wants to merge 14 commits into
WordPress:trunkfrom
joemcgill:fix/60309
Closed

joemcgill wants to merge 14 commits into
WordPress:trunkfrom
joemcgill:fix/60309

Conversation

@joemcgill

Copy link
Copy Markdown
Member

This change updates locate_template() so that the stylesheet and template paths get stored to a global variable the first time this function is called and resets these globals any time the theme is switched. This memoizes these values similarly to how the previous STYLESHEETPATH and TEMPLATEPATH constants were stored prior to https://core.trac.wordpress.org/changeset/56635, but allows these values to be reset when the theme is switched. However, this avoids changing the template path whenever running in a switch_to_blog context.

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


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

Comment thread src/wp-includes/theme.php Outdated
@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • The Plugin and Theme Directories cannot be accessed within Playground.
  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@felixarntz felixarntz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joemcgill Thanks for opening the PR. I have a few points of feedback.

Most importantly, I think we need to ensure the directories stored in the global are always those of the initial site, which right now may not be the case.

Comment thread src/wp-includes/template.php Outdated
Comment thread src/wp-includes/theme.php Outdated
@joemcgill

Copy link
Copy Markdown
Member Author

Thanks for the quick feedback, @felixarntz. After giving it more thought, I had also come to the same conclusion that moving the memoization of the template paths to load_template() directly is not ideal, since we cannot be sure when in the request lifecycle that function is being called.

Originally, the template constants were set using the wp_templating_constants() function in wp-settings.php (ref), right after the setup_theme action is fired as a first step to loading the active theme. Once those constants were set, several templating functions, including load_template() relied on those stored values for the rest of the lifecycle.

After [56635], those values were instead stored as static variables inside of get_stylesheet_directory() and get_template_directory(), which were initially called before the theme's functions.php file is loaded and any filters provided by the theme were added, which is what caused the initial bugs. By removing that memoization from those functions, we've introduced a new set of issues for the template functions that assumed that relied on the previous constants, as those were immutable (unlike the values returned from the related functions).

As a compromise, I've updated the approach here so that a new function is added, wp_set_template_globals() which sets these global values at the same place where the previous constants were being set. This function is also now used in locate_template() and switch_theme() to ensure globals are properly reset to the currently active theme when needed. We may also need to update other places where the old constants were replaced with the helper functions in the original commit to ensure backwards compatibility.

@joemcgill
joemcgill requested a review from felixarntz January 23, 2024 19:36

@mukeshpanchal27 mukeshpanchal27 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @joemcgill for the PR. Left some initial feedbacks.

Comment thread src/wp-includes/template.php
Comment thread tests/phpunit/tests/theme.php
Comment thread tests/phpunit/tests/theme.php Outdated
Comment thread src/wp-includes/template.php Outdated

@mukeshpanchal27 mukeshpanchal27 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, @joemcgill. It looks good from my perspective.

@WordPress WordPress deleted a comment from moshiajonta Jan 24, 2024
@WordPress WordPress deleted a comment from moshiajonta Jan 24, 2024
@WordPress WordPress deleted a comment from moshiajonta Jan 24, 2024
@joemcgill joemcgill changed the title Cache locate template paths Store template paths as global variables Jan 25, 2024
@joemcgill

Copy link
Copy Markdown
Member Author

After reviewing all of the changes that were originally made in r56635, I believe the only safe way to make this change is to also use of the same globals in all the places where the previous constants were in use. I've applied those changes in the following functions:

@swissspidy swissspidy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just from looking at the code, the changes appear sound to me.

Feels a bit ironic that we end up replacing constants with globals :)

@mukeshpanchal27 mukeshpanchal27 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @joemcgill for the update. LGTM! Left some nit-pick.

Comment thread src/wp-includes/load.php Outdated
Comment thread src/wp-includes/comment-template.php Outdated
@joemcgill

Copy link
Copy Markdown
Member Author

@swissspidy

Feels a bit ironic that we end up replacing constants with globals :)

Agreed, and I feel the same. Essentially, we were using the old constants as a way to store the application state for template paths while the functions that are responsible for getting these values can change after the initial state is set. By keeping them as constants, any functions that relied on the old constants were not testable. However, trying to deprecate the constants in favor of using the functions directly caused several bugs due to the fact that these functions are used throughout the application in different ways than the state stored in the old constants and expect different values.

Perhaps there is a different pattern that would be preferable to using globals in this case, but I didn't want to over-engineer something in order to fix the bugs that have been reported.

@carlomanf

Copy link
Copy Markdown

I didn't want to over-engineer something in order to fix the bugs that have been reported.

It looks over-engineered to me already, and I'd use stronger language than "ironic" to describe the replacement of constants with globals. I just don't see enough evidence that these "bugs" are actually bugs at all. What it looks like to me is the real bugs got coincidentally fixed and a small number of vocal theme/plugin authors complained because they were relying on the bugs and were forced to update their theme/plugin.

By the time this patch gets committed and deployed, which I hope it doesn't, anyone affected will have found other solutions already and it will serve no purpose other than to frustrate many other plugin/theme authors who want functions that behave in simple and consistent ways and are easy to learn. This kind of thing makes people want to stop authoring themes/plugins altogether, and most of them just leave quietly without making their frustrations known.

Some core decisions that I've seen recently have been so perplexing that it made me honestly question whether "shooing" plugin/theme authors is the intention. If so, then go right ahead and commit this, but I'm still perplexed. If not, maybe reflect on why it so often looks that way. It seems there is often too much attention on designing a solution and not enough effort to define the problem.

@metropoliscreative

Copy link
Copy Markdown

@joemcgill Thanks for your time on this PR - I think it works to solve the multisite issues we discussed in ticket #60290 and restores previously expected functionality.

Will this make it into 6.5?

@github-actions

github-actions Bot commented Feb 15, 2024 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props joemcgill, flixos90, mukesh27, swissspidy, manfcarlo, metropolis_john.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@carlomanf

Copy link
Copy Markdown

@metropoliscreative I previously suggested an alternative for you in ticket 60290 that you could use immediately without a core patch. I would be interested to know whether it achieves what you're looking for.

@metropoliscreative

Copy link
Copy Markdown

@metropoliscreative I previously suggested an alternative for you in ticket 60290 that you could use immediately without a core patch. I would be interested to know whether it achieves what you're looking for.

@carlomanf Yes, thanks for your feedback. I understand you have strong opinions about this ticket and PR, but the goal here is to address unintended functionality changes from [56635] related to switch_to_blog(). If you feel this long-standing functionality is in fact a bug, then please open another ticket to address it.

@carlomanf

Copy link
Copy Markdown

@metropoliscreative Let me quote the part I am referring to, in case you missed it:

If I read your code correctly, it looks like you could easily solve the problem by appending user ID's that have posts to an array and calling get_template_part on each of them after you switch back to blog 2.

The point I am making is that 6.5 is more than a month away, a number of core committers above have expressed concern about the design of this patch, and there is potentially a way for you to independently solve the problem you encountered. Maybe you are already doing something like this, but it would assist everyone involved to find a way forward if you could confirm.

joemcgill and others added 3 commits February 21, 2024 12:56
Co-authored-by: Mukesh Panchal <mukeshpanchal27@users.noreply.github.com>
Co-authored-by: Mukesh Panchal <mukeshpanchal27@users.noreply.github.com>
Co-authored-by: Mukesh Panchal <mukeshpanchal27@users.noreply.github.com>
@joemcgill

Copy link
Copy Markdown
Member Author

Merged in https://core.trac.wordpress.org/changeset/57685. Thanks all for the feedback and testing.

@joemcgill joemcgill closed this Feb 21, 2024
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

Successfully merging this pull request may close these issues.

6 participants