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