Theming a multi-homed site

A multi-homed example

This example shows how to create a single site that is themed differently depending on which hostname you use to access to it.

This example assumes you know the basics of creating a customised theme as explained in Customising CSS using SASS.

To prepare for this example, follow the steps in to configure package.json and install the node modules.

Create multiple themes and configure webpack to package them

Create a webpack directory containing an index.js which includes the bootstrap sources:

import 'bootstrap';

For each of your sites, create a <site_name>.scss file in the webpack directory with customised SCSS sources for that site:

sitea.com.scss:

$body-bg: white;
$body-color: black;


$theme-colors: (
        "primary": #0074d9,
        "danger": #ff4136,
        "custom-color": #900
);

$enable-rounded: false;
$enable-shadows: true;

@import "bootstrap";

siteb.com.scss:

$body-bg: black;
$body-color: darkgray;


$theme-colors: (
        "primary": yellow,
        "danger": orange,
        "custom-color": #900
);

$enable-rounded: true;
$enable-shadows: true;

@import "bootstrap";

List all your sites in webpack.config.js:

//https://webpack.js.org/loaders/sass-loader/

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');


module.exports = {
  entry: { 'main': './webpack/index.js',
           'sitea.com': './webpack/sitea.com.scss',
           'siteb.com': './webpack/siteb.com.scss'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
     rules: [
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
    ],
  },
  plugins: [ new MiniCssExtractPlugin({
      filename: '[name].css'
    })],
};

Build your custom SCSS

In your project root, run:

npm run build

This command creates a dist directory which contains the packaged CSS for each of your site’s domain names.

Configure your application to use your customisation

Create a Library which serves the correct CSS file depending on the current hostname in the request:

class CompiledBootstrap(Library):
    def __init__(self, force_theme=None):
        super().__init__('custom')
        self.force_theme = force_theme
        self.egg_name = 'bootstrapsassmultihomed'
        self.shipped_in_package = 'dist'
        self.files = [
                      'sitea.com.css',
                      'siteb.com.css',
                      'main.js'
                      ]

    def files_of_type(self, extension):
        if extension == '.css':
            from reahl.web.fw import Url
            hostname = self.force_theme or Url.get_current_url().hostname
            return ['%s.css' % hostname]
        else:
            return super().files_of_type(extension)

Create configuration that includes all the necessary Reahl libraries as well as your customised library, in the correct order:

from reahl.web.libraries import LibraryIndex, JQuery, JsCookie, JQueryUI, Underscore, HTML5Shiv, IE9, Reahl, Holder, ReahlBootstrap4Additions

from reahl.doc.examples.howtos.bootstrapsassmultihomed.bootstrapsassmultihomed import ThemedUI, CompiledBootstrap


web.site_root = ThemedUI
web.frontend_libraries = LibraryIndex(JQuery(), JsCookie(), JQueryUI(), Underscore(), HTML5Shiv(), IE9(), Reahl(), Holder(),
                         CompiledBootstrap(), ReahlBootstrap4Additions())

Try it out!

Serving your multihomed project on http://localhost:8000 will not match the theme for sitea.com or siteb.com. You have to visit http://sitea.com:8000 or http://siteb.com:8000 for that to work.

However, sitea.com and siteb.com quite likely do not resolve to your development machine.

In order to see the changes in a development environment on http://localhost:8000, you can change web.config.py used in development to force your CompiledBootstrap to display a specific theme by passing force_theme:

CompiledBootstrap(force_theme='sitea.com')

Note

If you are technically minded, you can also add aliases for your localhost to your local hosts file so that http://sitea.com:8000 or http://siteb.com:8000 resolve to http://localhost:8000.