Currently themes machinery works in such way that if we rely on default theme in our branded theme, we have to include them both into AVAILABLE_THEMES setting, otherwise default theme assets will be unavailable and the branded theme assets compilation will fail. On the other hand, mentioning them both leads to theme picker being shown - which we would like to avoid (per marketing wish). SELECTABLE_THEMES setting was added to allow limiting the user facing themes by configuration. Closes-bug: #1564543 Co-Authored-By: Ivan Kolodyazhny <e0ne@e0ne.info> Change-Id: Ic00a9201d2d352685b1089a37a25987b75d6636d
7.6 KiB
Themes
As of the Kilo release, styling for the OpenStack Dashboard can be
altered through the use of a theme. A theme is a directory containing a
_variables.scss
file to override the color codes used
throughout the SCSS and a _styles.scss
file with additional
styles to load after dashboard styles have loaded.
As of the Mitaka release, Horizon can be configured to run with multiple themes available at run time. It uses a browser cookie to allow users to toggle between the configured themes. By default, Horizon is configured with the two standard themes available: 'default' and 'material'.
To configure or alter the available themes, set
AVAILABLE_THEMES
in local_settings.py
to a
list of tuples, such that ('name', 'label', 'path')
name
-
The key by which the theme value is stored within the cookie
label
-
The label shown in the theme toggle under the User Menu
path
-
The directory location for the theme. The path must be relative to the
openstack_dashboard
directory or an absolute path to an accessible location on the file system
To use a custom theme, set AVAILABLE_THEMES
in
local_settings.py
to a list of themes. If you wish to run
in a mode similar to legacy Horizon, set AVAILABLE_THEMES
with a single tuple, and the theme toggle will not be available at all
through the application to allow user configuration themes.
For example, a configuration with multiple themes:
AVAILABLE_THEMES = [
('default', 'Default', 'themes/default'),
('material', 'Material', 'themes/material'),
]
A configuration with a single theme:
AVAILABLE_THEMES = [
('default', 'Default', 'themes/default'),
]
Both the Dashboard custom variables and Bootstrap variables can be
overridden. For a full list of the Dashboard SCSS variables that can be
changed, see the variables file at
openstack_dashboard/static/dashboard/scss/_variables.scss
.
In order to build a custom theme, both _variables.scss
and _styles.scss
are required and
_variables.scss
must provide all the default Bootstrap
variables.
Inherit from an Existing Theme
Custom themes must implement all of the Bootstrap variables required
by Horizon in _variables.scss
and
_styles.scss
. To make this easier, you can inherit the
variables needed in the default theme and only override those that you
need to customize. To inherit from the default theme, put this in your
theme's _variables.scss
:
@import "/themes/default/variables";
- Once you have made your changes you must re-generate the static files with
-
tox -e manage -- collectstatic
.
By default, all of the themes configured by
AVAILABLE_THEMES
setting are collected by horizon during
the collectstatic process. By default,
the themes are collected into the dynamic static/themes directory, but this location can
be customized via the local_settings.py
variable:
THEME_COLLECTION_DIR
Once collected, any theme configured via
AVAILABLE_THEMES
is available to inherit from by importing
its variables and styles from its collection directory. The following is
an example of inheriting from the material theme:
@import "/themes/material/variables";
@import "/themes/material/styles";
All themes will need to be configured in
AVAILABLE_THEMES
to allow inheritance. If you wish to
inherit from a theme, but not show that theme as a selectable option in
the theme picker widget, then simply configure the
SELECTABLE_THEMES
to exclude the parent theme.
SELECTABLE_THEMES
must be of the same format as
AVAILABLE_THEMES
. It defaults to
AVAILABLE_THEMES
if it is not set explicitly.
Bootswatch
Horizon packages the Bootswatch SCSS files for use with its
material
theme. Because of this, it is simple to use an
existing Bootswatch theme as a base. This is due to the fact that
Bootswatch is loaded as a 3rd party static asset, and therefore is
automatically collected into the static
directory in /horizon/lib/. The following
is an example of how to inherit from Bootswatch's darkly
theme:
@import "/horizon/lib/bootswatch/darkly/variables";
@import "/horizon/lib/bootswatch/darkly/bootswatch";
Organizing Your Theme Directory
A custom theme directory can be organized differently, depending on
the level of customization that is desired, as it can include static
files as well as Django templates. It can include special subdirectories
that will be used differently: static
,
templates
and img
.
The static
Folder
If the theme folder contains a sub-folder called static
,
then that sub folder will be used as the static root of the
theme. I.e., Horizon will look in that sub-folder for the
_variables.scss and _styles.scss files. The contents of this folder will
also be served up at /static/custom
.
The templates
Folder
If the theme folder contains a sub-folder templates
,
then the path to that sub-folder will be prepended to the
TEMPLATE_DIRS
tuple to allow for theme specific template
customizations.
Using the templates
Folder
Any Django template that is used in Horizon can be overridden through a theme. This allows highly customized user experiences to exist within the scope of different themes. Any template that is overridden must adhere to the same directory structure that the extending template expects.
For example, if you wish to customize the sidebar, Horizon expects
the template to live at horizon/_sidebar.html
. You would
need to duplicate that directory structure under your templates
directory, such that your override would live at
{ theme_path }/templates/horizon/_sidebar.html
.
The img
Folder
If the static root of the theme folder contains an img
directory, then all images that make use of the {% themable_asset %}
templatetag can be overridden.
These assets include logo.svg, splash-logo.svg and favicon.ico, however overriding the SVG/GIF assets used by Heat within the dashboard/img folder is not currently supported.
Customizing the Logo
Simple
If you wish to customize the logo that is used on the splash screen
or in the top navigation bar, then you need to create an
img
directory under your theme's static root directory and
place your custom logo.svg
or logo-splash.svg
within it.
If you wish to override the logo.svg
using the previous
method, and if the image used is larger than the height of the top
navigation, then the image will be constrained to fit within the height
of nav. You can customize the height of the top navigation bar by
customizing the SCSS variable: $navbar-height
. If the
image's height is smaller than the navbar height, then the image will
retain its original resolution and size, and simply be centered
vertically in the available space.
Prior to the Kilo release the images files inside of Horizon needed to be replaced by your images files or the Horizon stylesheets needed to be altered to point to the location of your image.
Advanced
If you need to do more to customize the logo than simply replacing
the existing PNG, then you can also override the _brand.html through a
custom theme. To use this technique, simply add a
templates/header/_brand.html
to the root of your custom
theme, and add markup directly to the file. For an example of how to do
this, see
openstack_dashboard/themes/material/templates/header/_brand.html
.
The splash / login panel can also be customized by adding
templates/auth/_splash.html
. See
openstack_dashboard/themes/material/templates/auth/_splash.html
for an example.