WordPress.org

Make WordPress Core

Opened 4 years ago

Last modified 12 months ago

#33123 new enhancement

Filter on theme mod default value

Reported by: greenshady Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.3
Component: Themes Keywords:
Focuses: Cc:

Description

For those of us using theme mods for storing theme settings, we often need a method for modifying the default theme mod when building child themes. For example, I might build a Christmas-styled child theme and modify the parent theme's default "primary" color to green. The only way this is possible is if the parent theme does something like this:

$primary = get_theme_mod( 'color_primary', '' );

add_filter( 'theme_mod_color_primary', 'parent_color_primary',   99 );

function parent_color_primary( $hex ) {
	return $hex ? $hex : '#00000';
}

Then, the Christmas child theme can hook in earlier and modify this if needing to change the default like so:

add_filter( 'theme_mod_color_primary', 'child_color_primary', 10 );

function child_color_primary( $hex ) {
	return $hex ? $hex : '#cc0000';
}

That's kind of a janky way to do things. It'd be far easier to have a filter on the default passed into get_theme_mod( $mod, $default ). Something like:

$default = apply_filters( "theme_mod_{$mod}_default", $default );

In this scenario, the parent theme merely needs to do this:

$primary = get_theme_mod( 'color_primary', '#000000' );

And, the child theme:

add_filter( 'theme_mod_color_primary_default', 'child_color_primary' );

function child_color_primary() {
	return '#cc0000';
}

I'm attaching a patch that will provide this filter hook.

Attachments (1)

theme-mod-default.patch (876 bytes) - added by greenshady 4 years ago.

Download all attachments as: .zip

Change History (4)

#1 @greenshady
4 years ago

  • Type changed from defect (bug) to enhancement

#2 follow-up: @joyously
14 months ago

The example given is not the only way to filter default values, and it wouldn't even work correctly, because the theme_mod_{$name} filter is applied to both the db value and the default value. That filter is what is used by the Customizer to make the temporary changes work for the preview.

Another way to filter default values is for the theme to provide a single function that supplies defaults, and to filter the result so that child themes can modify or add defaults. Then the result of that function is passed in to the get_theme_mod() call. So, the default is filtered before the call, not during. This way there is one filter for one function, that modifies an array, instead of one filter function for each theme mod.

There is some merit to having a filter for the default value inside the get_theme_mod function, in order to mirror the way individual options have the default_option_{$option} filter, but changing the filters in there could cause side effects in existing themes. The way the patch is filtering the default twice probably won't get the same result.

#3 in reply to: ↑ 2 @greenshady
12 months ago

Replying to joyously:

The example given is not the only way to filter default values, and it wouldn't even work correctly, because the theme_mod_{$name} filter is applied to both the db value and the default value.

Like I said, it is a janky way to do it. However, it absolutely does work.

Another way to filter default values is for the theme to provide a single function that supplies defaults, and to filter the result so that child themes can modify or add defaults. Then the result of that function is passed in to the get_theme_mod() call. So, the default is filtered before the call, not during. This way there is one filter for one function, that modifies an array, instead of one filter function for each theme mod.

Of course, that puts the onus on theme authors to build a custom system rather than having a shared system in WP that everyone can use. It's better for the review team, theme authors, and DIY users to have a standard.

There is some merit to having a filter for the default value inside the get_theme_mod function, in order to mirror the way individual options have the default_option_{$option} filter, but changing the filters in there could cause side effects in existing themes. The way the patch is filtering the default twice probably won't get the same result.

If you have some use cases where there might be side effects, present those cases.

Not sure what you mean by filtering the default twice in the patch. There's only a single filter in the patch I put forward.

The patch works as intended (or it did when I first submitted it). I thoroughly tested it with existing themes. I've been running my own custom get_theme_mod() function for years that does the exact same thing the proposed patch does. I think it'd be cool if other theme authors had the same feature that I have.

Note: See TracTickets for help on using tickets.