Jekyll One

Fulltext Search

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:

  1. The visitor clicks a theme name in the theme menu.

  2. The Themer writes the name of the theme and the path of its CSS file into the J1 user state cookie.

  3. The current page is reloaded.

  4. While the page loads, the J1 theme adapter reads the cookie and adds the CSS file of the selected theme to the page.

  5. 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 (F​lash o​f u​nstyled c​ontent): 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:

Structure of the J1 Themer application tree (base components)
  ├───assets
  │   ├───data
  │   │       themes.json
  │   └───theme
  │       └───j1
  │           ├───adapter
  │           │   └───js
  │           │           themes.js
  │           └───modules
  │               └───bsThemeSwitcher
  │                   └───js
  │                           switcher.js
  │                           switcher.min.js
  └───_data
      └───modules
          │   themes.yml
          └───defaults
                  themes.yml

The 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/defaults contains the default settings, the file under _data/modules contains 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: true

The 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

enabled

false

Enables or disables the Themer module.

debug

false

Enables or disables additional messages in the browser console. Only useful if you want to analyze a problem.

saveToCookie

true

If set to true, the selected theme is saved to the user state cookie and restored automatically on the next visit.

defaultCssFile

/assets/theme/j1/modules/bootstrap/css/bootstrap.css

The CSS file used as a fallback if the configured theme cannot be loaded.

bootswatchApiUrl

https://bootswatch.com/api

The web address (URL) of the Bootswatch API used to load the list of remote themes.

bootswatchApiVersion

5

The version of the Bootswatch API to use. Version 5 returns themes made for Bootstrap V5 — the version used by the J1 Template.

loadFromBootswatch

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.

localThemes

/assets/data/themes.json

The path of the JSON data file that lists all local themes.

excludeBootswatch

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:

  1. Wait until the J1 core system is up and the page content is available.

  2. Hide the page content for a short moment to prevent the FOUC effect (see the section How a theme switch works).

  3. 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.

  4. If the Themer is enabled, configure the switcher plugin with the merged YAML options, so the theme menus can be filled.

  5. 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.

  6. 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 loadFromBootswatch to false. The theme menus then only offer the themes listed in the local theme file themes.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: true

cookieThemeName

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: 365

cookiePath

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');