Hey,
I was inspired by @WebDragon’s post over here to actually sit down and try to figure out how to do selectable color-schemes in Sage9.
I have a client that has a small network of sites (non-multisite) with largely the same theme, and different colors. Up until now I’ve been manually merging updates across each of the sites as changes are made. This will let me keep a single copy of the theme and pull it in as a dependency, then change the “scheme” per site. Pretty cool.
Here’s what I came up with:
First we alter config.json
to generate more stylesheets for us:
theme-name/resources/assets/config.json
{
"entry": {
"main": [
"./scripts/main.js",
"./styles/main.scss"
],
"light": [
"./styles/light.scss"
],
"dark": [
"./styles/dark.scss"
],
"customizer": [
"./scripts/customizer.js"
]
},
"publicPath": "/app/themes/theme-name",
"devUrl": "http://mysite.dev",
"proxyUrl": "http://localhost:3000",
"cacheBusting": "[name]_[hash:8]",
"watch": [
"app/**/*.php",
"config/**/*.php",
"resources/controllers/**/*.php",
"resources/views/**/*.php"
]
}
Each of these .scss
files should be fully stand-alone, including all the styles necessary for the site. An example:
theme-name/resources/assets/styles/light.scss
@import "~bootstrap/scss/functions";
@import "common/variables-light";
@import "~bootstrap/scss/variables";
/** Import everything from autoload */
@import "./autoload/**/*";
/**
* Import npm dependencies
*
* Prefix your imports with `~` to grab from node_modules/
* @see https://github.com/webpack-contrib/sass-loader#imports
*/
// @import "~some-node-module";
/** Import theme styles */
@import "common/global";
@import "components/buttons";
@import "components/comments";
@import "components/forms";
@import "components/wp-classes";
@import "layouts/header";
@import "layouts/sidebar";
@import "layouts/footer";
@import "layouts/pages";
@import "layouts/posts";
@import "layouts/tinymce";
Then let’s register a Customizer setting to select the sub-theme:
theme-name/app/customizer.php
<?php
namespace App;
add_action( 'customize_register', function() {
global $wp_customize;
// Theme variation setting
class Select_Control extends \WP_Customize_Control {
public $type = 'select';
public function render_content() {
$themes = array(
'light' => 'Light',
'dark' => 'Dark',
);
?>
<label>
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
<select <?php $this->link(); ?>>
<?php foreach($themes as $theme => $name) { ?>
<option value="<?=$theme?>" <?php if($this->value() == $theme) echo 'selected="selected"'; ?>><?=$name?></option>
<?php } ?>
</select>
</label>
<?php
} //render_content()
} //Select_Control()
$wp_customize->add_section('theme_colors', array('title'=>'Sub Theme'));
$wp_customize->add_setting('subtheme_setting', array('default'=>'light'));
$wp_customize->add_control( new Select_Control($wp_customize, 'subtheme_setting', array(
'label' => 'Color scheme',
'section' => 'theme_colors',
'setting' => 'subtheme_setting'
) ) );
});
Don’t forget to add customizer
to the includes array in functions.php
Finally let’s edit setup.php
to include our selected sub-theme’s stylesheet rather than the default:
theme-name/app/setup.php
/**
* Theme assets
*/
add_action('wp_enqueue_scripts', function () {
wp_enqueue_style('sage/main.css', asset_path('styles/' . get_theme_mod( 'subtheme_setting' ) . '.css'), false, null);
wp_enqueue_script('sage/main.js', asset_path('scripts/main.js'), ['jquery'], null, true);
}, 100);
Now just go to Customizer and select the sub-theme you want to use!
I hope some of you find this helpful.