Creating new Themes with Foundation and SCSS
Table of Contents
Creating the Theme
Directory Layout
themes/THEME Base folder of the theme | +---theme.css the theme's SCSS-built CSS style sheet +---style.css the theme's additional CSS (optional) +---eden.min.css css.cfg-built, minified CSS (includes the two above) +---*.css any additional injectable CSS (s3.stylesheets) | +---foundation The theme's Foundation base CSS style sheets (SCSS-built) | | | +---app.css the theme's Foundation base style sheet for Left-to-Right writing direction | +---app.rtl.css the theme's Foundation base style sheet for Right-to-Left writing direction | +---app.min.css minified versions of the above | +---app.rtl.min.css " | +---scss The SCSS environment of the theme | | | +---_settings.scss the theme's Foundation SCSS settings (required) | +---app.scss the theme's Foundation SCSS imports (Foundation SCSS modules) | +---app.rtl.scss the theme's Foundation SCSS RTL overrides | +---theme.scss the theme's SCSS imports (Sahana SCSS modules) | +---config.rb the build configuration for Compass | | | +---theme/ The theme's SCSS sources | | | +---_*.scss the individual SCSS sources (=> fall back to the corresponding default/scss/theme/_*.scss) | +---img Image folder of the theme +---js Script folder of the theme (injected scripts) +---favicon.ico The bookmark icon of the theme
Copying from Skeleton
To start a default-based theme with Foundation and SCSS, copy the static/themes/skeleton/scss
folder.
This folder contains the directory structure described above, except for the CSS targets which will be created when building the theme for the first time.
SCSS
CSS can be converted to SCSS using: https://css2sass.herokuapp.com
Foundation Components
Foundation components ("modules") are configured in THEME/scss/foundation.scss
. This configuration is also used for the right-to-left variant of the foundation base styles.
Theme Settings
Styles in themes derived from default/scss can be controlled by configuration settings.
Foundation base styles are configured in themes/THEME/scss/_settings.scss
. These settings control the colors and other parameters of Foundation elements, e.g. menus, buttons, etc.
Sahana-specific styles are configured in themes/THEME/scss/theme/_config.scss
. These settings control the colors and parameters of Sahana-specific UI elements, e.g. data tables/lists, rheader tabs, S3 form widgets etc.
There is naturally some overlap between Sahana-specific elements and Foundation elements (e.g. some Sahana widgets using Foundation elements). In such cases, Sahana-specific styles will apply Foundation settings, unless overridden in _config.scss
.
Modifying Styles
To modify Sahana styles, simply copy the respective SCSS file from themes/default/scss/theme
into themes/THEME/scss/theme
, and then modify the copy. The build process will then automatically use the modified copy instead of the corresponding default source.
To add new styles without copying+modifying a default SCSS source, one can simply create another _*.scss
in the THEME/scss/theme folder, and then add an @import
statement for it to THEME/scss/theme.scss.
Changing the Default Theme
Note that modifying any of the SCSS configurations or sources in default/scss
would require to rebuild all themes based on it (including default itself, of course), in order to propagate the changes.
While this is a good way to let all themes benefit from fixes and enhancements developed for the default theme, major changes in the default theme could also conflict with the design of derivative themes. In some cases, such conflicts can perhaps be resolved by introducing additional settings in _config.scss
- but over time, enforced backwards-compatibility could lead to undesirably complex SCSS that becomes hard to maintain.
To not let this kind of dependencies prevent future development of the default theme, they can be resolved by simply copying the affected, original SCSS source from default/scss
into the dependent theme's THEME/scss
, before changing the SCSS in default.
In the same way, a theme can be made entirely independent of default SCSS by simply copying all remaining SCSS sources from default/scss
into THEME/scss
, before changing the SCSS in default.
Building the Theme
Debug Versions
The theme can be built using compass
:
cd static/themes/THEME/scss compass compile
This will rebuild the following CSS style sheets as/when required:
- foundation/app.css
- foundation/app.rtl.css
- theme.css
For longer development sessions, it can be convenient to let compass
automatically rebuild the theme:
cd static/themes/THEME/scss compass watch
This runs continuously, watching the file system, and will automatically run compass compile
whenever a source changes.
Production
To rebuild the minified versions of the foundation base stylesheets:
- foundation/app.min.css
- foundation/app.rtl.min.css
...we need to tell compass
to build for the production environment:
cd static/themes/THEME/scss compass compile -e production
Note that this only needs to be done after changing THEME/scss/_settings.scss
or THEME/scss/foundation.scss
, not routinely.
The eden.min.css can be rebuild as usual with the build.sahana.py
script.
Using the Theme in a Template
Adding Foundation to layout.html
Base Styles
Foundation-based themes must include the Foundation base stylesheets, ahead of any Sahana style sheets:
- static/themes/THEME/foundation/app.css
- static/themes/THEME/foundation/app.rtl.css
Note that only one of app.css
or app.rtl.css
is loaded, depending on the writing direction for the current UI language (Left-To-Right or Right-To-Left).
The sequence to include Foundation base styles is encoded in a view template views/foundation.css.html
, so it can easily be added to layout.html
:
... {{for sheet in s3.external_stylesheets:}} <link href="{{=sheet}}" rel="stylesheet" type="text/css" media="screen" charset="utf-8" /> {{pass}} {{include "foundation.css.html"}} <--- Foundation base styles are loaded here {{for sheet in s3.stylesheets:}} <link href="/{{=appname}}/static/styles/{{=sheet}}" rel="stylesheet" type="text/css" media="screen" charset="utf-8" /> {{pass}} {{if s3.debug:}}{{=s3base.s3_include_debug_css()}}{{else:}} {{# Built by /static/scripts/tools/build.sahana.py }} <link href="/{{=appname}}/static/themes/{{=theme}}/eden.min.css" rel="stylesheet" type="text/css" /> {{pass}} ...
Scripts
Additionally, Foundation requires loading and initialization of some scripts at the end of the <body>
. The corresponding sequence is also encoded in a view template views/foundation.js.html
, so it can easily be added to layout.html
:
... {{include "foundation.js.html"}} <--- this loads and initializes Foundation scripts </body> </html>
Adding Theme Styles to css.cfg
The SCSS-built theme.css
style sheet is included at the end of css.cfg
:
... ../themes/THEME/theme.css #../themes/THEME/style.css # Final line required for parsing
It can be followed by an optional THEME/style.css
to add CSS for template-specific elements as well as final overrides. The style.css
style sheet is not built from SCSS, so it can be edited directly.