User Selectable Theme with Meteor Kitchen

Posted by {"display_name"=>"greg", "login"=>"greg", "email"=>"greg@udon.org", "url"=>""} on April 20, 2016 · 3 mins read

Meteor Kitchen is a great tool for quickly creating Meteor apps and it supports Bootstrap and Bootswatch themes. The Bootswatch theme can be selected by the developer in the json file. In this post, I'm going to show how to allow the user to select among the Bootwatch themes.

This post was motivated by a Meteor Kitchen Github issue I raised and the response from the developer as well as a Stackoverflow post on this subject.

Setup Session Variable with Themes Object

I'm going to start by storing an object with a list of the available themes in a session variable. To do that, I need to import the Meteor Session module under the Applications / packages section of the json:

"packages": { "meteor": [ "session" ] }

I'm then going to define the session variable in a client startup file. First, reference the file under application / client_startup_source_file:

"client_startup_source_file": "clientStart.js",

Here's the contents of the clientStart.js file to set the themes session variable:

var themeList = [ "amelia", "cerulean", "cosmo", "cyborg", "darkly", "flatly", "journal", "lumen", "paper", "readable", "sandstone", "simplex", "slate", "spacelab", "superhero", "united", "yeti" ];
Session.set("themeList", themeList);

var themes = {};
themeList.forEach(function(name) {
 themes[name] = '//bootswatch.com/' + name + '/bootstrap.min.css';
});
Session.set("themes", themes);

Set Default Theme After Login

Now, go to the first page after your user logs in and let's set the theme that will be used once the user logs in. In this case, I'm going to hard code a default theme but you'd probably want to load the user has selected from their users profile.

Under the pages component for my home_private page I'm going to set the template_rendered_code to add the stylesheet from the themes session object:

"template_rendered_code": " var existingtheme = $('.theme-css'); console.log('existing theme: ' + existingtheme.length); if (!existingtheme.length) { var themes=Session.get('themes'); var themesheet = $('<link href=\"'+themes['slate']+'\" rel=\"stylesheet\" class=\"theme-css\" />'); themesheet.appendTo('head'); } ",

I tested out the changes at this point to make sure that the theme changed from the default toslate when the user logs in.

User Theme Selection

Now, on my user profile page, I want to create a select item with a list of the themes for the user to choose from and immediately change the theme for the site. In this case, my select field is named profile.theme and it has a list of the available themes:

{ "name": "profile.theme", "title": "Theme", "input": "select", "input_items": [ "amelia", "cerulean", "cosmo", "cyborg", "darkly", "flatly", "journal", "lumen", "paper", "readable", "sandstone", "simplex", "slate", "spacelab", "superhero", "united", "yeti" ] },

This code will run when the user selects a new theme.

"events_code": "\"change select[name='profile.theme']\": function (e,t) { console.log(\"theme: \", $(e.target).val()); var themes=Session.get('themes'); var themeurl = themes[$(e.target).val()]; var themesheet = $('.theme-css'); themesheet.attr('href',themeurl); }",

When the user chooses a theme, the events_code immediately updates the link to the selected Bootswatch theme.