/ Meteor

Custom CSS at a template level in Meteor

This is a problem that I am going to face often and hence it is probably a good idea for me to figure out the solution.

Problem

I lean towards using standard UI templates for most coding. The traditional method was to dump all the UI files (css or less) into the client directory and they would get picked up and minified automatically.

However, the flexibility is lost here. I seem to often need Template level CSS without necessarily using the main app styling for certain specific pages (mainly landing, marketing, pricing, etc).

Again, my goto approach here is use a template of choice for creating these specific pages without necessarly screwing up the entire application!

Solution

I was able to solve this problem as follows:

  • Remove twbs:bootstrap from the meteor app
  • Install the npm version of bootstrap using meteor npm install [email protected] -S
  • Copy the bootstrap files from node_modules to imports/client/stylesheets/
  • Create a namespaced verison of bootstrap as follows

Create tw-bs.less with the following code:

.tw-bs { 
  @import "./bootstrap/less/bootstrap.less";
}

This less file reference the original bootstrap.less file with a namespace

Create the compiled css file using lessc tw-bs.less tw-bs.css

IMPORTANT: REPLACE .tw-bs html in the generated css file manually to html. It other words, except html tags .. everything else is namespaced with .tw-bs

  • Create a namespaced verison of theme styling file as follows

Create main.less with the following code so that it references the root styling file of the theme ... in my case it is style.less.

.tw-bs { 
  @import "./style.less";
}

Compile to main.css using: lessc main.less main.css

  • Created a layout file used by the router to leverage this combination of namespaced bootstrap and namespaced theme.

The layout file in my case, used by iron:router is called blank-layout. The code for these files are as following (and self-explanatory):

blank-layout.html

<template name="blankLayout">
  <div class="tw-bs">
    <div class="color-line"></div>

    <!-- Main Wrapper -->
    {{> yield}}
  </div>
</template>

blank-layout.js


import 'bootstrap/dist/js/bootstrap.min.js'

// import 'bootstrap/dist/css/bootstrap.css'
import '/imports/client/stylesheets/tw-bs.css';
import '/imports/client/stylesheets/main.css';


Template.blankLayout.onRendered(function () {
    $('body').addClass('blank');
    $('html').addClass('tw-bs');
});

Template.blankLayout.onDestroyed(function () {
    $('body').removeClass('blank');
});

NOTE: The bootstrap.min.js file is explictly referenced here.
NOTE: The namespaced bootstrap file is explictly referenced here.
NOTE: The namespaced theme file is explictly referenced here.

FINALLY, note that the html tag has .tw-bs added explicitly for the whole plot to work using $('html').addClass('tw-bs');

For other templates that need to leverage a different styling, simply create alternate namespaced versions of HTML and accordingly import the appropriate css and js files. Used a customized router, to leverage the appropriate customized layout file to use the different styling!

My router configuration is as follows for blankLayout and can be modified for the new layout template as required!

Router.configure({
    layoutTemplate: 'blankLayout',
    notFoundTemplate: 'notFound'
});

Good fun! Seems to work fine!

Pardon all grammatical and writing errors ... unedited version for now!

UI-Kits

References