本文译自 openstack-horizon 官方文档javascript
从 Kilo 版本开始,Horizon 支持经过主题来定制样式。主题内包含一个 _variables.scss
文件用来覆写颜色,还有一个 _styles.scss
文件用来添加样式,这两个文件在 dashboard 样式以后加载。css
从 Mitaka 版本开始,Horizon 支持配置多个主题给用户选择,经过浏览器 cookie 记录用户设置的主题。默认状况下提供 'default' 和 'material' 两个标准主题。html
主题配置在 local_settings.py
文件的 AVAILABLE_THEMES
变量中,是一个包含 ('name', 'label', 'path')
的元组。java
name
保存在 cookie 中的主题名称python
label
展现在用户界面列表中的主题名称git
path
包含主题的文件夹路径,必须是相对于 openstack_dashboard
目录
的相对路径或者操做系统的绝对路径github
多主题的例子bootstrap
AVAILABLE_THEMES = [ ('default', 'Default', 'themes/default'), ('material', 'Material', 'themes/material'), ]
单主题的例子浏览器
AVAILABLE_THEMES = [ ('default', 'Default', 'themes/default'), ]
Dashboard 自定义变量和 Bootstrap 变量均可以被覆写。在openstack_dashboard/static/dashboard/scss/_variables.scss
这个文件查看全部的 SCSS 变量。服务器
一个自定义主题必须包含 _variables.scss
和 _styles.scss
两个文件,其中_variables.scss
必须包含全部的 Bootstrap 变量。
自定义主题必须定义 _variables.scss
and _styles.scss
中全部的 Bootstrap 变量。你能够从已有的 default 主题继承这些变量,只覆写你想要修改的内容,把如下代码放在自定义主题的 _variables.scss
文件中
@import "/themes/default/variables";
修改了样式以后须要从新执行以下命令,从新生成静态文件 ./run_tests.sh -m collectstatic
.
运行 collectstatic
命令时,在 AVAILABLE_THEMES
变量中的全部主题都会从新生成,更新到 static/themes
路径下,这个目标路径也能够经过 local_settings.py
中的THEME_COLLECTION_DIR
变量来指定。
如下是一个引用 material 主题中定义的变量的例子
@import "/themes/material/variables"; @import "/themes/material/styles";
根据自定义的程度不一样,自定义主题的目录能够是不一样的形式,相似 Django 的模板体系同样引用静态文件。能够包含 static
, templates
和 img
三个子目录。
static
目录若是主题目录下包含 static
文件夹,则该文件夹会被当作 主题的静态文件根目录。例如,Horizon 会在该文件夹下查找 _variables.scss 和 _styles.scss 文件。The contents of this folder will also be served up at /static/custom
.
templates
目录若是主题目录下包含 templates
文件夹,则该文件夹的路径会添加到 TEMPLATE_DIRS
元组的前面,这样主题就能够自定义模板。
templates
目录在Horizon中,任何 Django 模板均可以被主题覆写,提供了高度可定制的能力。覆写的模板必须和被覆写的模板保持同样的目录结构。
例如,若是你要自定义 sidebar,必须把在 templates 目录下也新建一个 horizon/_sidebar.html
文件,这样就能够在 { theme_path }/templates/horizon/_sidebar.html
引用中生效。
img
目录若是主题的静态文件根目录下包含 omg
文件夹,则全部用 {% themable_asset %} 模板标签引入的图片都会被覆写,包括 logo.png, splash-logo.png and favicon.ico,但还不支持覆写 dashboard/img
下的被 Heat 组件使用的 SVG/GIF 文件。
若是你想自定义启动界面或顶部导航栏的logo,你须要在主题的 static 根目录下建立一个 img
文件夹,将自定义的 logo.png
和 logo-splash.png
图片放在里面。
若是你的 logo.png
的高度比顶部导航栏的高度更大,图片会被压缩至导航栏的高度。你能够经过 SCSS 变量 $navbar-height
来定制顶部导航栏的高度。 若是图片的高度比顶部导航栏的高度小,那么会垂直居中显示。
Kilo 以前的版本,须要将 Horizon 中的图片替换成你本身的图片,或者把样式表中的图片指向你的图片路径。
若是你想作更多的定制化,能够在主题根目录下添加 templates/header/_brand.html
,而后修改里面的内容。参考:openstack_dashboard/themes/material/templates/header/_brand.html
启动界面也能够定制,经过添加 templates/auth/_splash.html
文件实现。参考:openstack_dashboard/themes/material/templates/auth/_splash.html
从 Liberty 版本发布以来,Horizon 严格遵照着 Bootstrap 设计规范,努力创造更好的响应式网页设计,也减轻将来每次版本改变风格的负担。
如下组件根据版本号排列,充分利用了 Bootstrap 的主题结构
Top Navbar
Side Nav
Pie Charts
Tables
Bar Charts
Login
Tabs
Alerts
Checkboxes
建立品牌化主题的第一步是建立自定义的 Bootstrap 主题。有不少辅助工具,其中包括:
Bootswatchr
Paintstrap
Bootstrap
Bootstrap 使用 LESS 但咱们用 SCSS,以上的工具都会提供 ``variables.less`` 文件,须要手动转换为 ``_variables.scss``
如今的 Horizon 的顶部导航栏用 Bootstrap 原生的 navbar
。在 _variables.scss
文件的 Navbar 区块内查看哪些变量能够自定义。
导航栏用了原生的 Bootstrap dropdowns 组件,也能够自定义其中的变量值,参考 _variables.scss
文件中的 Dropdowns 区块进行自定义。
顶部导航栏能够自适应小屏幕。
侧边栏组件也已经基于原生的 Stacked Pills 元素重构了,参考 _variables.scss
文件中的 Pills 区块进行自定义。
饼图由 SVG 元素构成,SVG 元素能够接受基础的 CSS 的自定义样式。(例如 colors, size)
Bootstrap 中没有饼图的原生元素,因此 Horizon 的图表样式是由主题样式定义。参考 _pie_charts.scss
柱状图能够是 Bootstrap Progress Bar 也能够是 SVG 元素,两种状况都使用了 Bootstrap Progress Bar 的样式。
SVG 实现的柱状图没法自定义高度,因此推荐使用基于 Bootstrap Progress Bar 实现的柱状图。
参考 _variables.scss
文件中的 Progress bars 区块进行自定义样式,SVG 版的在 _bar_charts.scss
里面自定义。
标准的 Django 表格使用了原生的 Bootstrap table 标签,参考 _variables.scss
文件中的 Tables 区块进行自定义。
标准的 Bootstrap 表格是无边框的,若是想要添加边框,以 default
主题为例,参考 openstack_dashboard/themes/default/horizon/components/_tables.scss
文件。
登陆页面使用了标准的 Bootstrap panel 的实现,参考 _variables.scss
文件中的 Panels 区块进行自定义。
登陆弹窗使用了标准的 Bootstrap dialog,参考 _variables.scss
文件中的 Modals 区块进行自定义。
Horizon 使用 icon fonts 来实现 checkboxs,只须要覆写 standard scss 来实现自定义。例如 themes/material/static/horizon/components/_checkboxes.scss
。
Bootswatch
是一系列免费的 Bootstrap 主题。Horizon 包含了另外一个主题 material
,遵循 Google's Material Design
风格,基于 Bootswatch 的 Paper 主题。
Bootswatch 提供了一系列其余的主题,Horizon 是彻底主题化的开发,能够很方便的切换主题、自定义主题。
每次修改主题后,须要手动生成 static
目录里的内容,而后重启服务器。若是你不想每次都重启,能够按以下方式修改 local_settings.py
文件::
COMPRESS_OFFLINE = False
COMPRESS_ENABLED = False
在 local_settings.py
文件添加 SITE_BRANDING
变量来自定义站点标题。
在 local_settings.py
文件添加 SITE_BRANDING_LINK
变量来自定义站点首页连接。
在主题目录下的 template 文件夹添加 _footer.html
以自定义全局页脚,添加 _login_footer.html
以自定义登陆页页脚。
你能够指定一个自定义的 python 模块做为 dashboard 或 panel,常见的站点定制需求以下:
从 dashboard 注册或注销 panels
修改 dashboard 和 panel 的名称
对 panel 进行从新排序
默认加载的 panel 在 openstack_dashboard/enabled/ 目录下,根据文件名顺序排序加载。文件名以 .example 后缀结尾的文件是一些示例。开发者和维护者最好也按照这种方式来组织,请不要胡乱覆写文件和打补丁。
Horizon 使用 Font Awesome 的字体图标。参阅 Font Awesome
_。
使用 icon 属性给表格添加 Action。例如
class CreateSnapshot(tables.LinkAction): name = "snapshot" verbose_name = _("Create Snapshot") icon = "camera"
另外,全站的默认按钮样式修改,能够在 local_settings.py
文件中的 ACTION_CSS_CLASSES
中添加 class 类。
Horizon 能够自定义 dashboard 的样式,基础模板 openstack_dashboard/templates/base.html
中定义的 block 均可以被覆写。
建立一个 dashboard 的 templates 文件夹,从 Horizon 的基础模板继承,例如 openstack_dashboard/dashboards/my_custom_dashboard/templates/my_custom_dashboard/base.html
,而后就能够从新定义这个基础模板中的 block css。(别忘了引入 _stylesheets.html
,它包含了 Horizon 的全部默认样式 )::
{% extends 'base.html' %} {% block css %} {% include "_stylesheets.html" %} {% load compress %} {% compress css %} <link href='{{ STATIC_URL }}my_custom_dashboard/scss/my_custom_dashboard.scss' type='text/scss' media='screen' rel='stylesheet' /> {% endcompress %} {% endblock %}
自定义的样式文件放在 dashboard 的 static
目录下 openstack_dashboard/dashboards/my_custom_dashboard/static/my_custom_dashboard/scss/my_custom_dashboard.scss
.
全部的 template 都必须继承自 dashboard 的基础模板
{% extends 'my_custom_dashboard/base.html' %}
页面全部的 js 文件都在 openstack_dashboard/templates/horizon/_scripts.html
模板中引入,这个模板在 base 模板的 block js
中被引用。
在你的 dashboard 中建立一个 ``openstack_dashboard/dashboards/my_custom_dashboard/
templates/my_custom_dashboard/_scripts.html 模板,继承自
horizon/_scripts.html,在这个模板中覆写
block custom_js_files``,添加你本身的 javascript 文件
{% extends 'horizon/_scripts.html' %} {% block custom_js_files %} <script src='{{ STATIC_URL }}my_custom_dashboard/js/my_custom_js.js' type='text/javascript' charset='utf-8'></script> {% endblock %}
在你本身的 dashboard 的基础模板 openstack_dashboard/dashboards/my_custom_dashboard/templates/my_custom_dashboard/base.html
中覆写 block js
,包含你本身的 _scripts.html
{% block js %} {% include "my_custom_dashboard/_scripts.html" %} {% endblock %}
输出结果是一个包含了 Horizon 和 dashboard 自定义脚本的压缩文件。
另外,有些分析采集脚本须要在 <head> 中加载,这种状况能够在 horizon/_custom_head_js.html
添加。像上文提到的 _scripts.html
作法同样,直接添加连接
<script src='{{ STATIC_URL }}/my_custom_dashboard/js/my_marketing_js.js' type='text/javascript' charset='utf-8'></script>
也能够把脚本直接拷贝到模板里面::
<script type="text/javascript">
//some javascript
</script>
把你自定义的 Meta 添加到 horizon/_custom_meta.html
文件中,此文件的内容将会被插入到页面的 <head> 里。
Bootswatch: http://bootswatch.com
Bootswatchr: http://bootswatchr.com/create#!
Paintstrap: http://paintstrap.com
Bootstrap: http://getbootstrap.com/custo...
Google's Material Design: https://www.google.com/design...
Font Awesome: https://fortawesome.github.io...