WordPress.org

Make WordPress Core

Opened 2 years ago

Last modified 5 months ago

#25671 new enhancement

get_theme_mods does not have a filter

Reported by: scottsweb Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Themes Keywords: has-patch reporter-feedback
Focuses: Cc:

Description

I am making use of the Theme Modifications API for the first time and using it to store theme customisation options controlled via the theme customiser.

I hit an issue when previewing customisation changes using the refresh transport. The theme modifications functions are not aware of the $_POST'd changes coming from the theme customiser.

Let's say a user has changed a heading colour from red to blue and not yet hit save. The get_theme_mod('heading_colour') function is still returning red in the preview panel. This bug does not overly concern me (it may be that way by design) but to get around it it would be handy to be able to filter get_theme_mods (see patch).

For now I have gone higher up in the API and used a filter on get_option:

add_filter( 'option_theme_mods_' . $theme_slug)

Attachments (2)

theme_mods.diff (450 bytes) - added by scottsweb 2 years ago.
Initial patch with added filter
25671.1.patch (891 bytes) - added by spacedmonkey 5 months ago.

Download all attachments as: .zip

Change History (12)

@scottsweb
2 years ago

Initial patch with added filter

#1 @mark-k
2 years ago

  • Keywords close added

yes, you have to filter the option itself, but what is wrong with that? What you suggest is just a code bloat which doesn't add any value and is not doing enough to be a "sweetener". And if you truly think this kind of filter is needed then you need to supply another 3 for get,set and delete.

This is just too much work with almost zero added value.

#2 @scottsweb
2 years ago

No problem. But seeing there is a filter on get_theme_mod, it made sense to me for there to be one on get_theme_mods too. I guess it depends on how standalone / complete each API should be.

#3 @rmccue
2 years ago

  • Keywords close removed

+1 on this. We should avoid needing to use option_ filters where possible in these higher APIs.

#4 follow-up: @mark-k
2 years ago

The way I see it, get_theme_mods is an internal function used by *_theme_mod functions. The only reason to call it directly is in a misguided attempt in early optimization or for debugging.

I think it is just need to be documented as internal, otherwise its functionality should match performing multiple calls to get_them_mod and to do that you will need to have a loop that applies the relevant filter to each mod name.

Otherwise, if a new filter will be added like in the patch a plugin that wants to change a specific theme mod will have to hook on both filters.

#5 @mark-k
2 years ago

related #24844

#6 in reply to: ↑ 4 @johnbillion
2 years ago

Replying to mark-k:

The way I see it, get_theme_mods is an internal function used by *_theme_mod functions. The only reason to call it directly is in a misguided attempt in early optimization or for debugging.

I think you're misunderstanding the problem. get_theme_mods() is called internally whenever get_theme_mod() is called by the theme. The resulting output is not aware of POST changes made by the theme customiser. If you want to make your theme preview aware of changes made in the theme customiser you need to filter the option return value. As rmmcue said, there should be a higher level filter to abstract it from the storage mechanism.

#7 follow-up: @mark-k
2 years ago

If you want to make your theme preview aware of changes made in the theme customiser you need to filter the option return value

then why not use the theme_mod_$name filter?, what is the advantage of having a new filter?

#8 in reply to: ↑ 7 @nacin
2 years ago

  • Component changed from General to Themes
  • Keywords reporter-feedback added

Replying to mark-k:

If you want to make your theme preview aware of changes made in the theme customiser you need to filter the option return value

then why not use the theme_mod_$name filter?, what is the advantage of having a new filter?

I have the same question. Perhaps the customized (for example) is using get_theme_mods() directly? I don't think it is. But seems like the right filter is already in place.

#9 follow-up: @spacedmonkey
5 months ago

There should also be a pre filter at the top of the function. At the moment, the get_theme_mods function is not cached at all. Something I have mentioned in #33628 . It makes two calls to get_options, every time the function is call, which is ALOT.

This filter would run before the two uncached get_options calls. This filter could be used to cache theme mods in memory or to populated from another source, such as a file.

#10 in reply to: ↑ 9 @markkaplun
5 months ago

Replying to spacedmonkey:

There should also be a pre filter at the top of the function. At the moment, the get_theme_mods function is not cached at all. Something I have mentioned in #33628 . It makes two calls to get_options, every time the function is call, which is ALOT.

Unless misused, get_option is a very efficient function that reads a value from the memory and attempting to avoid a call to it will bring a very minute gain in performance, probably something you will find hard to measure at all.

In case you misunderstand how the options API work - on boot all options are read from the DB in one SQL query and then stored in the memory. any get_option will check first the memory and only if the option is not already in the memory it will issue a request to the DB. The exception are non autoloading options, but in proper use there should not be any non autoloading option used on the front end.

Note: See TracTickets for help on using tickets.