Horizon Themes should support and house easy Template Overrides
Themers need an easy way to maninpulate existing templates. Django provides a very easy method for custom overloads via prepending a Theme located template directory to the existing TEMPLATE_DIRS tuple located in the settings.py. The new template directory needs to maintain the same directory structure as the overridden templates. Also, the entire theme directory was being served out at /static/custom, but it is not needed to statically serve up the Django templates. This new functionality now supports having more granular control over what is statically served from /static/custom by specifying a 'static' subfolder within your theme. If no sub folder is found, then the legacy functionality is the fall back, and the entire folder is served. Since the Blue theme was provided as a way to showcase the extensibility of Horizon themes, I have provided an examle of what a template override would look like and how it would be used. The Blue theme now includes an entirely Bootstrap Compliant top navbar experience that is responsive, but without losing any of the underlying Django functionality, values or translations. Implements: blueprint horizon-theme-templates Change-Id: I40a744d5439ee5138337a7cdb1c0a937b5107836
This commit is contained in:
parent
eff59ac2dd
commit
7020bf3cb9
@ -401,11 +401,15 @@ This example sorts flavors by vcpus in descending order::
|
||||
Default: ``"static/themes/default"``
|
||||
|
||||
This setting allows Horizon to use a custom theme. The theme folder
|
||||
should contains one _variables.scss file and one _styles.scss file.
|
||||
should contain one _variables.scss file and one _styles.scss file.
|
||||
_variables.scss contains all the bootstrap and horizon specific variables
|
||||
which are used to style the GUI. Whereas _styles.scss contains extra styling.
|
||||
For example themes, see: /horizon/openstack_dashboard/static/themes/
|
||||
|
||||
If the static theme folder also contains a sub-folder 'templates', then
|
||||
the path to that sub-folder will be prepended to TEMPLATE_DIRS tuple
|
||||
to allow for theme specific template customizations.
|
||||
|
||||
``DROPDOWN_MAX_ITEMS``
|
||||
----------------------
|
||||
|
||||
|
@ -283,6 +283,19 @@ STATIC_URL = WEBROOT + 'static/'
|
||||
STATICFILES_DIRS = get_staticfiles_dirs(WEBROOT)
|
||||
|
||||
CUSTOM_THEME = os.path.join(ROOT_PATH, CUSTOM_THEME_PATH)
|
||||
|
||||
# If a custom template directory exists within our custom theme, then prepend
|
||||
# it to our first-come, first-serve TEMPLATE_DIRS
|
||||
if os.path.exists(os.path.join(CUSTOM_THEME, 'templates')):
|
||||
TEMPLATE_DIRS = \
|
||||
(os.path.join(CUSTOM_THEME_PATH, 'templates'),) + TEMPLATE_DIRS
|
||||
|
||||
# Only expose the subdirectory 'static' if it exists from a custom theme,
|
||||
# allowing other logic to live with a theme that we might not want to expose
|
||||
# statically
|
||||
if os.path.exists(os.path.join(CUSTOM_THEME, 'static')):
|
||||
CUSTOM_THEME = os.path.join(CUSTOM_THEME, 'static')
|
||||
|
||||
STATICFILES_DIRS.append(
|
||||
('custom', CUSTOM_THEME),
|
||||
)
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,71 @@
|
||||
{% load branding i18n %}
|
||||
{% load url from future %}
|
||||
{% load context_selection %}
|
||||
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container-fluid">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse">
|
||||
<span class="sr-only">{% trans "Toggle navigation" %}</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{% site_branding_link %}">
|
||||
<span class="openstack-logo"></span>
|
||||
{% site_branding %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||
{% show_overview %}
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
{% show_domain_list %}
|
||||
{% show_project_list %}
|
||||
{% show_region_list %}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% include "horizon/common/_region_selector.html" %}
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||
<span class="fa fa-user"></span>
|
||||
{{ request.user.username }}
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul id="editor_list" class="dropdown-menu">
|
||||
<li>
|
||||
<a href="{% url 'horizon:settings:user:index' %}">
|
||||
<span class="fa fa-cog"></span>
|
||||
{% trans "Settings" %}
|
||||
</a>
|
||||
</li>
|
||||
{% if HORIZON_CONFIG.help_url %}
|
||||
<li>
|
||||
<a href="{{ HORIZON_CONFIG.help_url }}" target="_blank">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
{% trans "Help" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="divider"></li>
|
||||
<li>
|
||||
<a href="{% url 'logout' %}">
|
||||
<span class="fa fa-sign-out"></span>
|
||||
{% trans "Sign Out" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div><!-- /.navbar-collapse -->
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
@ -0,0 +1,12 @@
|
||||
<span class="fa fa-list-alt"></span>
|
||||
<span class="context-overview">
|
||||
{% if domain_supported %}
|
||||
<span>{{ domain_name }}</span>
|
||||
<strong>·</strong>
|
||||
{% endif %}
|
||||
<span>{{ project_name }}</span>
|
||||
{% if multi_region %}
|
||||
<strong>·</strong>
|
||||
<span>{{ region_name }}</span>
|
||||
{% endif %}
|
||||
</span>
|
@ -0,0 +1,18 @@
|
||||
{% load i18n %}
|
||||
{% load url from future %}
|
||||
|
||||
{% with dashboard_url=request.horizon.dashboard.get_absolute_url %}
|
||||
<ul class="dropdown-menu">
|
||||
<li class="dropdown-header">{% trans "Projects:" %}</li>
|
||||
{% for project in projects %}
|
||||
<li>
|
||||
<a href="{% url 'switch_tenants' project.id %}?next={{ dashboard_url }}">
|
||||
{{ project.name }}
|
||||
{% if project.enabled and project.id == project_id %}
|
||||
<span class="fa fa-check"></span>
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endwith %}
|
Loading…
x
Reference in New Issue
Block a user