本文譯自 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...