Themer is a switcher tool based on jQuery to select themes provided by Bootswatch or loaded from local stored theme files.
The Themer allows automatically populating the names of themes available at Bootswatch in a menu to switch a theme easily. A selected theme is saved to a cookie and loaded automatically on the next visit.
10-15 Minutes to read
| The Themer is based on the jQuery plugin Bootstrap Theme Switcher written by Joseph Guadagno. The version shipped with the J1 Template is a modified version of the original plugin: it works together with the J1 mobile menu and stores the selected theme in the central J1 user state cookie. For that reason, the original plugin cannot be used as a replacement for the version shipped with the template. |
Getting started
The J1 Themer is a theme switcher for the J1 Template, inspired by the jQuery plugin Bootstrap Theme Switcher written by Joseph Guadagno. The version shipped with J1 Template is a modified version of the original plugin: it works together with the J1 MMenu, and it stores the selected theme in the central J1 user state cookie instead of separate plugin cookies.
With the Themer enabled, your visitors can change the look of the whole website with a single click. All available themes are listed in a menu — on desktop screens as a dropdown menu in the navigation bar, on mobile devices as part of the mobile (slide-in) menu. When a visitor selects a theme, the page is reloaded and all pages are displayed using the new styles. The selected theme is remembered: on the next visit, the site automatically starts with the theme the visitor has chosen before.
Where the themes come from
The Themer can offer themes from two different sources:
- Remote themes (Bootswatch)
-
Bootswatch is a free collection of open source themes for Bootstrap. The Themer loads the list of all available themes directly from the Bootswatch website (the Bootswatch API) when a page is opened. This way, the theme list is always up to date — without changing anything in your site.
- Local themes
-
Local themes are stored as CSS files inside your website. The J1 Template ships with three local themes: UnoLight (the default light theme), UnoDark (a dark theme), and Bootstrap (the plain Bootstrap standard look). The list of local themes is read from the JSON data file
/assets/data/themes.json.
How a theme switch works
You do not need to know the technical details to use the Themer, but it helps to understand what happens behind the scenes. A theme switch runs in a few simple steps:
-
The visitor clicks a theme name in the theme menu.
-
The Themer writes the name of the theme and the path of its CSS file into the J1 user state cookie.
-
The current page is reloaded.
-
While the page loads, the J1 theme adapter reads the cookie and adds the CSS file of the selected theme to the page.
-
As soon as the theme styles are fully loaded, the page is displayed.
| During a theme switch, the page content is hidden for a very short moment while the new CSS file is loaded. This prevents the so-called FOUC effect (Flash of unstyled content): without this trick, the visitor would see an unstyled page flickering before the new theme is applied. |
How the Themer is used in J1 Template
Good news first: you do not need to write any JavaScript code to use the Themer in the J1 Template. The template ships with a ready-to-use integration, and the module is configured by simple settings in a YAML configuration file.
The integration consists of four building blocks:
- The switcher plugin (
switcher.js) -
The (modified) jQuery plugin that does the real work: it loads the list of themes, fills the theme menus, switches a theme when a name is clicked, and saves the selection to the user state cookie. The plugin is described in detail in the section Programming Interface of this manual.
- The J1 adapter (
themes.js) -
A small piece of JavaScript, called an adapter, that connects the switcher plugin with the J1 Template. The adapter reads your YAML settings, loads the CSS file of the current theme at page load, and falls back to the default theme if the configured theme cannot be loaded.
- The YAML configuration (
themes.yml) -
All settings of the Themer live in YAML configuration files. Here you enable or disable the module, select the theme sources, and control details like cookies or excluded themes. See the section Configuration for all details.
- The theme data file (
themes.json) -
A JSON data file that lists all local themes with their names and the paths of their CSS files. The file is generated by the site build, so the correct CSS files are used automatically for development and production.
J1 Integration
The Themer is fully integrated in the J1 Template. The template creates the theme menus for you (a dropdown menu on desktop screens and a menu section in the mobile menu), loads the CSS file of the current theme on every page, and remembers the visitor’s choice in a cookie.
The only thing you have to do is to enable the module in the YAML configuration. All other settings are optional and come with useful default values.
Module sources
The sources for the Themer are stored within the asset path of the J1 Template. You’ll find the switcher plugin under /assets/theme/j1/modules/bsThemeSwitcher:
├───assets
│ ├───data
│ │ themes.json
│ └───theme
│ └───j1
│ ├───adapter
│ │ └───js
│ │ themes.js
│ └───modules
│ └───bsThemeSwitcher
│ └───js
│ switcher.js
│ switcher.min.js
└───_data
└───modules
│ themes.yml
└───defaults
themes.ymlThe parts of the module have the following jobs:
switcher.js-
The (modified) jQuery plugin Bootstrap Theme Switcher. It loads the theme list, fills the theme menus, and switches themes.
themes.js-
The J1 adapter for the Themer. It reads the YAML settings, loads the CSS file of the current theme at page load, and configures the switcher plugin.
themes.json-
The JSON data file that lists all local themes and the paths of their CSS files.
themes.yml(two files)-
The YAML configuration of the module. The file under
_data/modules/defaultscontains the default settings, the file under_data/modulescontains your user settings.
Configuration
The Themer is configured by two YAML files. The default settings live in _data/modules/defaults/themes.yml — this file documents all available options and should not be changed. Your personal user settings live in _data/modules/themes.yml. At build time, both files are merged: every option you set in the user file overwrites the default value.
By default, the Themer is disabled. To activate the module, set the option enabled to true in your user configuration:
settings:
enabled: trueThe most important options are listed below. You’ll find the full list, including all cookie-related options, in the (well documented) defaults file _data/modules/defaults/themes.yml:
| Option | Default | Description |
|---|---|---|
| false | Enables or disables the Themer module. |
| false | Enables or disables additional messages in the browser console. Only useful if you want to analyze a problem. |
| true | If set to true, the selected theme is saved to the user state cookie and restored automatically on the next visit. |
| /assets/theme/j1/modules/bootstrap/css/bootstrap.css | The CSS file used as a fallback if the configured theme cannot be loaded. |
| The web address (URL) of the Bootswatch API used to load the list of remote themes. | |
| 5 | The version of the Bootswatch API to use. Version |
| true | If set to true, the theme CSS files are loaded from the Bootswatch servers (CDN). If set to false, the CSS files given by the local theme list are used. |
| /assets/data/themes.json | The path of the JSON data file that lists all local themes. |
| Default, default, Lux, Sketchy | A comma-separated list of theme names that should not be offered in the theme menus. |
Initialization
The Themer is initialized automatically on every page load by the J1 adapter themes.js — you do not need to add any code to your pages. The adapter runs the following steps:
-
Wait until the J1 core system is up and the page content is available.
-
Hide the page content for a short moment to prevent the FOUC effect (see the section How a theme switch works).
-
Read the current theme (name and CSS file) from the J1 user state cookie. If no theme is found in the cookie, the default theme of the site is stored to the cookie and used instead.
-
If the Themer is enabled, configure the switcher plugin with the merged YAML options, so the theme menus can be filled.
-
Check if the CSS file of the current theme really exists. If yes, the file is added to the page. If not, the adapter falls back to the default theme and reloads the page.
-
As soon as the theme styles are fully loaded, the page is displayed.
Customization
The most common customizations can be done by simple settings in your user configuration _data/modules/themes.yml:
- Offer local themes only
-
If you do not want to load any themes from the Bootswatch servers, set the option
loadFromBootswatchto false. The theme menus then only offer the themes listed in the local theme filethemes.json— and no data is loaded from external servers. - Remove themes from the menus
-
If some Bootswatch themes do not fit the design of your site, add their names to the option
excludeBootswatch. The listed themes are removed from the theme menus. - Add your own theme
-
You can add your own theme by placing its CSS file inside your site and adding a new entry (name and CSS path) to the local theme file
/assets/data/themes.json. The new theme is offered in the theme menus like any other local theme.
Programming Interface
The Themer is implemented as a jQuery plugin named ThemeSwitcher. The plugin populates a ul (list) or select element with the names of all available themes, switches the theme when a name is selected, and saves the selection to a cookie. In the J1 Template, you normally do not call the plugin yourself — the J1 adapter does all the work for you. The sections below describe the plugin interface for users who want to use the switcher standalone or want to understand the integration in detail.
The plugin offers the following core features:
- Dynamically Load Theme Name
-
The plugin will pull in a list of the latest themes from Bootswatch.
- Switch the Bootstrap Theme
-
The dynamically loaded themes will automatically switch the theme when chosen.
- Load and Save theme to a cookie
-
Takes the selected theme information and saves it to a cookie to reload on later access.
Initialization
To use the switcher standalone (outside of the J1 integration), three steps are needed: load the CSS of an initial (start) theme, load the required JavaScript files, and initialize the plugin on a ul or select element that should show the theme list.
CSS load
The switcher plugin itself needs no stylesheet. What is loaded (and later replaced on a theme switch) is the theme CSS — a full Bootstrap stylesheet. Add a link element for the start theme to the head section of your page. The id of this element must match the plugin option cssThemeLink, so the plugin can find and replace the stylesheet on a switch:
<link rel="stylesheet" id="bootstrapTheme"
href="/assets/theme/j1/modules/bootstrap/css/bootstrap.min.css"
type="text/css">JS load
The plugin requires jQuery and a cookie library to be loaded first. Load the switcher script after its dependencies at the end of the body section of your page:
<script src="/assets/js/jquery.min.js"></script>
<script src="/assets/js/js.cookie.min.js"></script>
<script src="/assets/theme/j1/modules/bsThemeSwitcher/js/switcher.min.js"></script>JS initialization
The plugin is initialized on the element that should offer the theme list — a ul or a select element. All options are passed as a plain JavaScript object. On initialization, the plugin loads the theme list (from the local feed or from the Bootswatch API) and fills the element with the theme names:
$('#theme_selector').ThemeSwitcher({
localFeed: '/assets/data/themes.json',
excludeBootswatch: 'Default, Lux, Sketchy'
});Options
The Theme Switcher can be set globally by setting the $.fn.ThemeSwitcher.defaults object or individually for each call to $(selector).ThemeSwitcher() by passing a plain object to the options argument. Per-call options overwrite the default options.
In the J1 integration, all options are set from the merged YAML configuration by the adapter — the option names below map one-to-one to the YAML keys described in the section Configuration.
cssThemeLink
The ID used for the bootstrap theme css file:
cssThemeLink: 'bootstrapTheme'saveToCookie
If true, a cookie will be saved with the currently selected theme
aveToCookie: truecookieThemeName
The name of the cookie to be used to store the theme name
bootstrapTheme.name
cookieThemeCss
The name of the cookie to be used to store the css file used for the theme
cookieThemeCss: 'bootstrapTheme.css'cookieExpiration
The number of days after which the cookie expires. The J1 integration stores the selected theme for 365 days.
cookieExpiration: 365cookiePath
The path the cookie should be stored
cookiePath: '/'defaultCssFile
The default CSS file the plugin should use if it can not load the themes from Bootswatch. The J1 integration uses the (local) Bootstrap standard stylesheet shipped with the template.
defaultCssFile: '/assets/theme/j1/modules/bootstrap/css/bootstrap.css'bootswatchApiUrl
The web address (URL) of the Bootswatch API used to load the list of remote themes.
bootswatchApiUrl: 'https://bootswatch.com/api'bootswatchApiVersion
The version of the Bootswatch API to use. Version 5 returns themes made for Bootstrap V5 — the version used by the J1 Template.
bootswatchApiVersion: '5'localFeed
The path of a JSON file that contains the (local) themes you want to use. If this option is set, the theme list is loaded from this file and no request is made to the Bootswatch API. The J1 Template ships a ready-to-use theme file at /assets/data/themes.json.
localFeed: ''excludeBootswatch
Comma-separated list of Bootswatch theme names (e.g. Slate, Yeti) that should be excluded from the rendered ul or select element.
excludeBootswatch: ''Callbacks
No callbacks or events available.
| The J1-modified version of the plugin sends an (internal) J1 message to the J1 Navigator module when a theme menu has been loaded. This mechanism is used by the template only and is not a public callback interface. |
Methods
All methods of the plugin are called using the jQuery plugin pattern: the name of the method is passed as the first (string) argument, followed by the arguments of the method (if any). The methods operate on the element the plugin was initialized on.
Clear
Empties (removes) the theme names loaded to the ul or select element.
$(selector).ThemeSwitcher('clear');Destroy
Removes any reference to the ThemeSwitcher, empties the loaded control and removes the events.
$(selector).ThemeSwitcher('destroy');LoadThemeFromCookies
Checks for the presence of the theme (user state) cookie and loads the theme found. An options object can be passed in to change the default cookie settings, path, etc.
$(selector).ThemeSwitcher('loadThemeFromCookie');switchTheme
Activates the theme themeName with the given cssFile. If cssFile is undefined, the default CSS file (option defaultCssFile) is used. You can use this method to load your own custom theme.
In the J1 integration, switchTheme writes the new theme to the user state cookie and reloads the current page. The theme CSS is then loaded by the J1 adapter on the page reload.
$(selector).ThemeSwitcher('switchTheme', themeName, cssFile);Update
Reloads (refreshes) the theme list for the element given by selector.
$(selector).ThemeSwitcher('update');addTheme
Adds a new theme with the given name and cssFile to the theme list and refreshes the control. Two optional arguments start and deleteCount control where the new theme is inserted in the list (default: at the top) and how many existing entries are replaced (default: none).
$(selector).ThemeSwitcher('addTheme', name, cssFile);themes
Reads or sets the theme list of the switcher. If newThemeList is undefined, the method returns the current theme list. Otherwise, the given list replaces the current theme list.
$(selector).ThemeSwitcher('themes', newThemeList);Examples
Set up a ul or select element with the id theme_selector and fill it with the list of themes:
// Setup the theme selector
$('#theme_selector').ThemeSwitcher();Change the current theme to the (local) theme UnoDark:
// Change the theme
$('#theme_selector').ThemeSwitcher('switchTheme', 'UnoDark',
'/assets/theme/j1/core/css/themes/unodark/bootstrap.min.css');Load the previously saved theme from the site cookie:
// Load the previously selected theme from the cookie
$('#theme_selector').ThemeSwitcher('loadThemeFromCookie');