Re-work static_settings to clean up

This patch reduces duplication arbitrary directory choices for
xstatic package locations in the static directory.

It moves the xstatic configuration from the library into the
settings file, and the supporting functions move to
the openstack_dashboard.utils.settings module. Having the xstatic
module list in settings allows deployers to add new modules.

It standardises the paths the files are served from, reducing
potential conflicts.

It simplifies the interaction with the xstatic modules, and also uses
the new MAIN variable if present to determine the entry points used.

Since some of the xstatic packages were installed into special
snowflakes directories (not following a pattern) the references to
those (bootstrap_scss and font_awesome) have been fixed.

Change-Id: Ia5be0e96fff1a4ddd6058d6b030ddf96da4b46e7
This commit is contained in:
Richard Jones 2015-07-22 11:15:45 -06:00 committed by Timur Sufiev
parent aacd4fb5b4
commit 348069364c
16 changed files with 235 additions and 304 deletions

View File

@ -8,24 +8,15 @@
window.STATIC_URL = '/static/';
window.WEBROOT = '/';
</script>
<script src="{% url 'horizon:jsi18n' 'horizon' %}"></script>
<script src="{{ STATIC_URL }}horizon/lib/jasmine/jasmine.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/jasmine/jasmine-html.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/jasmine/boot.js"></script>
<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/spin.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/spin.jquery.js'></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular-route.js"></script>
{% for file in HORIZON_CONFIG.xstatic_lib_files %}
<script src="{{ STATIC_URL }}{{ file }}"></script>
{% endfor %}
<script src="{{ STATIC_URL }}horizon/lib/angular/angular-mocks.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular-cookies.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular-bootstrap.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular-gettext.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular-sanitize.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/smart-table.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/lrdragndrop.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/ng-file-upload-all.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/d3.js"></script>
<script src="{{ STATIC_URL }}horizon/js/horizon.js"></script>
<script type="text/javascript">

View File

@ -19,9 +19,7 @@
import os
import socket
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
STATICFILES_DIRS = get_staticfiles_dirs()
from openstack_dashboard.utils import settings as settings_utils
socket.setdefaulttimeout(1)
@ -127,6 +125,10 @@ HORIZON_CONFIG = {
'help_url': "http://example.com",
}
STATICFILES_DIRS = settings_utils.get_xstatic_dirs(
settings_utils.BASE_XSTATIC_MODULES, HORIZON_CONFIG
)
COMPRESS_ENABLED = True
COMPRESS_OFFLINE = False
COMPRESS_ROOT = "/tmp/"

View File

@ -25,9 +25,8 @@ from django.utils.translation import pgettext_lazy
from django.utils.translation import ugettext_lazy as _
from openstack_dashboard import exceptions
from openstack_dashboard.static_settings import find_static_files # noqa
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
from openstack_dashboard import theme_settings
from openstack_dashboard.utils import settings as settings_utils
from horizon.utils.escape import monkeypatch_escape
@ -299,6 +298,8 @@ CSRF_COOKIE_AGE = None
COMPRESS_OFFLINE_CONTEXT = 'horizon.themes.offline_context'
# Notice all customizable configurations should be above this line
XSTATIC_MODULES = settings_utils.BASE_XSTATIC_MODULES
try:
from local.local_settings import * # noqa
except ImportError:
@ -360,12 +361,6 @@ AVAILABLE_THEMES, DEFAULT_THEME = theme_settings.get_available_themes(
DEFAULT_THEME
)
STATICFILES_DIRS = get_staticfiles_dirs(STATIC_URL) + \
theme_settings.get_theme_static_dirs(
AVAILABLE_THEMES,
THEME_COLLECTION_DIR,
ROOT_PATH)
if CUSTOM_THEME_PATH is not None:
logging.warning("CUSTOM_THEME_PATH has been deprecated. Please convert "
"your settings to make use of AVAILABLE_THEMES.")
@ -374,10 +369,12 @@ if DEFAULT_THEME_PATH is not None:
logging.warning("DEFAULT_THEME_PATH has been deprecated. Please convert "
"your settings to make use of AVAILABLE_THEMES.")
# populate HORIZON_CONFIG with auto-discovered JavaScript sources, mock files,
# specs files and external templates.
find_static_files(HORIZON_CONFIG, AVAILABLE_THEMES,
THEME_COLLECTION_DIR, ROOT_PATH)
# Discover all the directories that contain static files; at the same time
# discover all the xstatic module entry points to embed in our HTML
STATICFILES_DIRS = settings_utils.get_xstatic_dirs(
XSTATIC_MODULES, HORIZON_CONFIG)
STATICFILES_DIRS += theme_settings.get_theme_static_dirs(
AVAILABLE_THEMES, THEME_COLLECTION_DIR, ROOT_PATH)
# Ensure that we always have a SECRET_KEY set, even when no local_settings.py
# file is present. See local_settings.py.example for full documentation on the
@ -391,13 +388,18 @@ if not SECRET_KEY:
SECRET_KEY = secret_key.generate_or_read_from_file(os.path.join(LOCAL_PATH,
'.secret_key_store'))
# populate HORIZON_CONFIG with auto-discovered JavaScript sources, mock files,
# specs files and external templates.
settings_utils.find_static_files(HORIZON_CONFIG, AVAILABLE_THEMES,
THEME_COLLECTION_DIR, ROOT_PATH)
# Load the pluggable dashboard settings
import openstack_dashboard.enabled
import openstack_dashboard.local.enabled
from openstack_dashboard.utils import settings
INSTALLED_APPS = list(INSTALLED_APPS) # Make sure it's mutable
settings.update_dashboards(
settings_utils.update_dashboards(
[
openstack_dashboard.enabled,
openstack_dashboard.local.enabled,

View File

@ -1,5 +1,5 @@
/* Some utility classes useful everywhere */
@import "/bootstrap/scss/bootstrap/mixins";
@import "/horizon/lib/bootstrap_scss/scss/bootstrap/mixins";
.row .horizontal-center,
.horizontal-center {

View File

@ -40,7 +40,7 @@ $rbrowser-footer-background-color: #f1f1f1;
// .table-striped-datatable styles.
// Font-awesome path to the icon fonts
$fa-font-path: $static_url + "horizon/lib/font-awesome/fonts";
$fa-font-path: $static_url + "horizon/lib/font_awesome/fonts";
/* Charts */

View File

@ -1,5 +1,5 @@
@import '/horizon/lib/font-awesome/scss/variables';
@import '/horizon/lib/font-awesome/scss/mixins';
@import '/horizon/lib/font_awesome/scss/variables';
@import '/horizon/lib/font_awesome/scss/mixins';
//
// Checkboxes

View File

@ -1,5 +1,5 @@
@import '/horizon/lib/font-awesome/scss/variables';
@import '/horizon/lib/font-awesome/scss/mixins';
@import '/horizon/lib/font_awesome/scss/variables';
@import '/horizon/lib/font_awesome/scss/mixins';
//
// Radio Buttons

View File

@ -8,8 +8,8 @@
@import "util";
// Vendor Components
@import "/bootstrap/scss/bootstrap";
@import "/horizon/lib/font-awesome/scss/font-awesome.scss";
@import "/horizon/lib/bootstrap_scss/scss/bootstrap";
@import "/horizon/lib/font_awesome/scss/font-awesome.scss";
// Main Page Layout
@import "layout";

View File

@ -1,228 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
This file contains configuration for the locations of all the static file
libraries, such as JavaScript and CSS libraries. Packagers for individual
distributions can edit or replace this file, in order to change the paths
to match their distribution's standards.
"""
import os
import xstatic.main
import xstatic.pkg.angular
import xstatic.pkg.angular_bootstrap
import xstatic.pkg.angular_fileupload
import xstatic.pkg.angular_gettext
import xstatic.pkg.angular_lrdragndrop
import xstatic.pkg.angular_schema_form
import xstatic.pkg.angular_smart_table
import xstatic.pkg.bootstrap_datepicker
import xstatic.pkg.bootstrap_scss
import xstatic.pkg.bootswatch
import xstatic.pkg.d3
import xstatic.pkg.font_awesome
import xstatic.pkg.hogan
import xstatic.pkg.jasmine
import xstatic.pkg.jquery
import xstatic.pkg.jquery_migrate
import xstatic.pkg.jquery_quicksearch
import xstatic.pkg.jquery_tablesorter
import xstatic.pkg.jquery_ui
import xstatic.pkg.jsencrypt
import xstatic.pkg.mdi
import xstatic.pkg.objectpath
import xstatic.pkg.rickshaw
import xstatic.pkg.roboto_fontface
import xstatic.pkg.spin
import xstatic.pkg.termjs
import xstatic.pkg.tv4
from horizon.utils import file_discovery
from openstack_dashboard import theme_settings
def get_staticfiles_dirs(webroot='/'):
STATICFILES_DIRS = [
('horizon/lib/angular',
xstatic.main.XStatic(xstatic.pkg.angular,
root_url=webroot).base_dir),
('horizon/lib/angular',
xstatic.main.XStatic(xstatic.pkg.angular_bootstrap,
root_url=webroot).base_dir),
('horizon/lib/angular',
xstatic.main.XStatic(xstatic.pkg.angular_fileupload,
root_url=webroot).base_dir),
('horizon/lib/angular',
xstatic.main.XStatic(xstatic.pkg.angular_gettext,
root_url=webroot).base_dir),
('horizon/lib/angular',
xstatic.main.XStatic(xstatic.pkg.angular_lrdragndrop,
root_url=webroot).base_dir),
('horizon/lib/angular',
xstatic.main.XStatic(xstatic.pkg.angular_schema_form,
root_url=webroot).base_dir),
('horizon/lib/angular',
xstatic.main.XStatic(xstatic.pkg.angular_smart_table,
root_url=webroot).base_dir),
('horizon/lib/bootstrap_datepicker',
xstatic.main.XStatic(xstatic.pkg.bootstrap_datepicker,
root_url=webroot).base_dir),
('bootstrap',
xstatic.main.XStatic(xstatic.pkg.bootstrap_scss,
root_url=webroot).base_dir),
('horizon/lib/bootswatch',
xstatic.main.XStatic(xstatic.pkg.bootswatch,
root_url=webroot).base_dir),
('horizon/lib',
xstatic.main.XStatic(xstatic.pkg.d3,
root_url=webroot).base_dir),
('horizon/lib',
xstatic.main.XStatic(xstatic.pkg.hogan,
root_url=webroot).base_dir),
('horizon/lib/font-awesome',
xstatic.main.XStatic(xstatic.pkg.font_awesome,
root_url=webroot).base_dir),
('horizon/lib/jasmine',
xstatic.main.XStatic(xstatic.pkg.jasmine,
root_url=webroot).base_dir),
('horizon/lib/jquery',
xstatic.main.XStatic(xstatic.pkg.jquery,
root_url=webroot).base_dir),
('horizon/lib/jquery',
xstatic.main.XStatic(xstatic.pkg.jquery_migrate,
root_url=webroot).base_dir),
('horizon/lib/jquery',
xstatic.main.XStatic(xstatic.pkg.jquery_quicksearch,
root_url=webroot).base_dir),
('horizon/lib/jquery',
xstatic.main.XStatic(xstatic.pkg.jquery_tablesorter,
root_url=webroot).base_dir),
('horizon/lib/jsencrypt',
xstatic.main.XStatic(xstatic.pkg.jsencrypt,
root_url=webroot).base_dir),
('horizon/lib/mdi',
xstatic.main.XStatic(xstatic.pkg.mdi,
root_url=webroot).base_dir),
('horizon/lib/objectpath',
xstatic.main.XStatic(xstatic.pkg.objectpath,
root_url=webroot).base_dir),
('horizon/lib',
xstatic.main.XStatic(xstatic.pkg.rickshaw,
root_url=webroot).base_dir),
('horizon/lib/roboto_fontface',
xstatic.main.XStatic(xstatic.pkg.roboto_fontface,
root_url=webroot).base_dir),
('horizon/lib',
xstatic.main.XStatic(xstatic.pkg.spin,
root_url=webroot).base_dir),
('horizon/lib',
xstatic.main.XStatic(xstatic.pkg.termjs,
root_url=webroot).base_dir),
('horizon/lib/tv4',
xstatic.main.XStatic(xstatic.pkg.tv4,
root_url=webroot).base_dir),
]
if xstatic.main.XStatic(xstatic.pkg.jquery_ui,
root_url=webroot).version.startswith('1.10.'):
# The 1.10.x versions already contain the 'ui' directory.
STATICFILES_DIRS.append(
('horizon/lib/jquery-ui',
xstatic.main.XStatic(xstatic.pkg.jquery_ui,
root_url=webroot).base_dir))
else:
# Newer versions dropped the directory, add it to keep the path the
# same.
STATICFILES_DIRS.append(
('horizon/lib/jquery-ui/ui',
xstatic.main.XStatic(xstatic.pkg.jquery_ui,
root_url=webroot).base_dir))
return STATICFILES_DIRS
def find_static_files(
HORIZON_CONFIG,
AVAILABLE_THEMES,
THEME_COLLECTION_DIR,
ROOT_PATH):
import horizon
import openstack_dashboard
os_dashboard_home_dir = openstack_dashboard.__path__[0]
horizon_home_dir = horizon.__path__[0]
# note the path must end in a '/' or the resultant file paths will have a
# leading "/"
file_discovery.populate_horizon_config(
HORIZON_CONFIG,
os.path.join(horizon_home_dir, 'static/')
)
# filter out non-angular javascript code and lib
HORIZON_CONFIG['js_files'] = ([f for f in HORIZON_CONFIG['js_files']
if not f.startswith('horizon/')])
# note the path must end in a '/' or the resultant file paths will have a
# leading "/"
file_discovery.populate_horizon_config(
HORIZON_CONFIG,
os.path.join(os_dashboard_home_dir, 'static/'),
sub_path='app/'
)
# Discover theme static resources, and in particular any
# static HTML (client-side) that the theme overrides
theme_static_files = {}
theme_info = theme_settings.get_theme_static_dirs(
AVAILABLE_THEMES,
THEME_COLLECTION_DIR,
ROOT_PATH)
for url, path in theme_info:
discovered_files = {}
# discover static files provided by the theme
file_discovery.populate_horizon_config(
discovered_files,
path
)
# Get the theme name from the theme url
theme_name = url.split('/')[-1]
# build a dictionary of this theme's static HTML templates.
# For each overridden template, strip off the '/templates/' part of the
# theme filename then use that name as the key, and the location in the
# theme directory as the value. This allows the quick lookup of
# theme path for any file overridden by a theme template
template_overrides = {}
for theme_file in discovered_files['external_templates']:
# Example:
# external_templates_dict[
# 'framework/widgets/help-panel/help-panel.html'
# ] = 'themes/material/templates/framework/widgets/\
# help-panel/help-panel.html'
(templates_part, override_path) = theme_file.split('/templates/')
template_overrides[override_path] = 'themes/' +\
theme_name + theme_file
discovered_files['template_overrides'] = template_overrides
# Save all of the discovered file info for this theme in our
# 'theme_files' object using the theme name as the key
theme_static_files[theme_name] = discovered_files
# Add the theme file info to the horizon config for use by template tags
HORIZON_CONFIG['theme_static_files'] = theme_static_files

View File

@ -3,7 +3,7 @@
{% compress css %}
<link href='{{ STATIC_URL }}horizon/lib/bootstrap_datepicker/datepicker3.css' type='text/css' media='screen' rel='stylesheet' />
<link href='{{ STATIC_URL }}horizon/lib/rickshaw.css' type='text/css' media='screen' rel='stylesheet' />
<link href='{{ STATIC_URL }}horizon/lib/rickshaw/rickshaw.css' type='text/css' media='screen' rel='stylesheet' />
{% endcompress %}

View File

@ -3,13 +3,11 @@
{% datepicker_locale as DATEPICKER_LOCALE %}
{% comment %} Compress 3rd-party (jquery, angular, etc) and top-level Horizon JS. {% endcomment %}
{% compress js %}
<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery.js' type='text/javascript' charset="utf-8"></script>
<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery-migrate.js' type='text/javascript' charset="utf-8"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular-route.js" type="text/javascript" charset="utf-8"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/angular-bootstrap.js" type="text/javascript" charset="utf-8"></script>
{% for file in HORIZON_CONFIG.xstatic_lib_files %}
<script src='{{ STATIC_URL }}{{ file }}'></script>
{% endfor %}
<script src='{{ STATIC_URL }}horizon/js/horizon.js' type='text/javascript' charset='utf-8'></script>
{% endcompress %}

View File

@ -11,28 +11,13 @@
{% include "horizon/_script_i18n.html" %}
{% comment %} Compress jQuery, Angular, Plugins, Bootstrap, Hogan.js and Horizon-specific JS. {% endcomment %}
{% comment %} Compress Horizon-specific JS. {% endcomment %}
{% compress js %}
<script type="text/javascript">
var STATIC_URL = "{{ STATIC_URL }}";
var WEBROOT = "{{ WEBROOT }}";
</script>
<script src='{{ STATIC_URL }}horizon/lib/angular/angular-cookies.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/angular/angular-gettext.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/angular/angular-sanitize.js'></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/lrdragndrop.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/smart-table.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/angular/ng-file-upload-all.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/d3.js"></script>
<script src='{{ STATIC_URL }}horizon/lib/jquery/jquery.quicksearch.js'></script>
<script src="{{ STATIC_URL }}horizon/lib/jquery/jquery.tablesorter.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/spin.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/spin.jquery.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/jquery-ui/ui/jquery-ui.js"></script>
<script src="{{ STATIC_URL }}horizon/lib/jquery/jquery.bootstrap.wizard.js"></script>
<script src="{{ STATIC_URL }}bootstrap/js/bootstrap.js"></script>
<script src='{{ STATIC_URL }}horizon/lib/bootstrap_datepicker/bootstrap-datepicker.js'></script>
<script src="{{ STATIC_URL }}horizon/lib/hogan.js"></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.string.js'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.communication.js'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.datepickers.js'></script>
@ -60,15 +45,10 @@
<script src='{{ STATIC_URL }}horizon/js/horizon.networktopology.js'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.d3piechart.js'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.heattop.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/rickshaw.js'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.d3linechart.js'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.d3barchart.js'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.firewalls.js'></script>
<script src='{{ STATIC_URL }}horizon/js/horizon.volumes.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/jsencrypt/jsencrypt.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/objectpath/ObjectPath.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/tv4/tv4.js'></script>
<script src='{{ STATIC_URL }}horizon/lib/angular/schema-form.js'></script>
{% for file in HORIZON_CONFIG.js_files %}
<script src='{{ STATIC_URL }}{{ file }}'></script>

View File

@ -16,8 +16,6 @@ from django.utils.translation import pgettext_lazy
from horizon.test.settings import * # noqa
from horizon.utils import secret_key
from openstack_dashboard import exceptions
from openstack_dashboard.static_settings import find_static_files # noqa
from openstack_dashboard.static_settings import get_staticfiles_dirs # noqa
from horizon.utils.escape import monkeypatch_escape
@ -25,7 +23,7 @@ from horizon.utils.escape import monkeypatch_escape
# enabling in our test setup to find any issues it might cause
monkeypatch_escape()
STATICFILES_DIRS = get_staticfiles_dirs()
from openstack_dashboard.utils import settings as settings_utils
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_PATH = os.path.abspath(os.path.join(TEST_DIR, ".."))
@ -99,14 +97,19 @@ HORIZON_CONFIG = {
'images_panel': 'legacy',
}
STATICFILES_DIRS = settings_utils.get_xstatic_dirs(
settings_utils.BASE_XSTATIC_MODULES, HORIZON_CONFIG
)
# Load the pluggable dashboard settings
import openstack_dashboard.enabled
from openstack_dashboard.utils import settings
import openstack_dashboard.local.enabled
INSTALLED_APPS = list(INSTALLED_APPS) # Make sure it's mutable
settings.update_dashboards(
settings_utils.update_dashboards(
[
openstack_dashboard.enabled,
openstack_dashboard.local.enabled
],
HORIZON_CONFIG,
INSTALLED_APPS,
@ -116,8 +119,8 @@ settings.update_dashboards(
# the stacks MappingsTests are updated with the new URL path.
HORIZON_CONFIG['swift_panel'] = 'legacy'
find_static_files(HORIZON_CONFIG, AVAILABLE_THEMES,
THEME_COLLECTION_DIR, ROOT_PATH)
settings_utils.find_static_files(HORIZON_CONFIG, AVAILABLE_THEMES,
THEME_COLLECTION_DIR, ROOT_PATH)
# Set to 'legacy' or 'direct' to allow users to upload images to glance via
# Horizon server. When enabled, a file form field will appear on the create

View File

@ -1,7 +1,7 @@
// Based on Paper
// Bootswatch
// -----------------------------------------------------
@import "/bootstrap/scss/bootstrap/mixins/vendor-prefixes";
@import "/horizon/lib/bootstrap_scss/scss/bootstrap/mixins/vendor-prefixes";
@import "/horizon/lib/bootswatch/paper/bootswatch";
@import "/horizon/lib/roboto_fontface/css/roboto-fontface.scss";

View File

@ -17,7 +17,8 @@ import os
import pkgutil
import six
from horizon.utils import file_discovery as fd
from horizon.utils import file_discovery
from openstack_dashboard import theme_settings
def import_submodules(module):
@ -121,7 +122,8 @@ def update_dashboards(modules, horizon_config, installed_apps):
for _app in _apps:
module = import_module(_app)
base_path = os.path.join(module.__path__[0], 'static/')
fd.populate_horizon_config(horizon_config, base_path)
file_discovery.populate_horizon_config(horizon_config,
base_path)
add_exceptions = six.iteritems(config.get('ADD_EXCEPTIONS', {}))
for category, exc_list in add_exceptions:
@ -168,3 +170,173 @@ def update_dashboards(modules, horizon_config, installed_apps):
# so we save the reference to it before we append to installed_apps
horizon_config.setdefault('plugins', []).extend(apps)
installed_apps[0:0] = apps
# Order matters, list the xstatic module name and the entry point file(s) for
# that module (this is often defined as the "main" in bower.json, and
# as the xstatic module MAIN variable in the very few compliant xstatic
# modules). If the xstatic module does define a MAIN then set the files
# list to None.
# This list is to be used as the base list which is potentially added to in
# local_settings.py before being passed to get_xstatic_dirs()
BASE_XSTATIC_MODULES = [
('xstatic.pkg.jquery', ['jquery.js']),
('xstatic.pkg.jquery_migrate', ['jquery-migrate.js']),
('xstatic.pkg.angular', [
'angular.js',
'angular-cookies.js',
'angular-sanitize.js',
'angular-route.js'
]),
('xstatic.pkg.angular_bootstrap', ['angular-bootstrap.js']),
('xstatic.pkg.angular_gettext', ['angular-gettext.js']),
('xstatic.pkg.angular_lrdragndrop', None),
('xstatic.pkg.angular_smart_table', None),
('xstatic.pkg.angular_fileupload', ['ng-file-upload-all.js']),
('xstatic.pkg.d3', ['d3.js']),
('xstatic.pkg.jquery_quicksearch', ['jquery.quicksearch.js']),
('xstatic.pkg.jquery_tablesorter', ['jquery.tablesorter.js']),
('xstatic.pkg.spin', ['spin.js', 'spin.jquery.js']),
('xstatic.pkg.jquery_ui', ['jquery-ui.js']),
('xstatic.pkg.bootstrap_scss', ['js/bootstrap.js']),
('xstatic.pkg.bootstrap_datepicker', ['bootstrap-datepicker.js']),
('xstatic.pkg.hogan', ['hogan.js']),
('xstatic.pkg.rickshaw', ['rickshaw.js']),
('xstatic.pkg.jsencrypt', ['jsencrypt.js']),
('xstatic.pkg.objectpath', ['ObjectPath.js']),
('xstatic.pkg.tv4', ['tv4.js']),
('xstatic.pkg.angular_schema_form', ['schema-form.js']),
# @imported in scss files diectly
('xstatic.pkg.font_awesome', []),
('xstatic.pkg.bootswatch', []),
('xstatic.pkg.roboto_fontface', []),
('xstatic.pkg.mdi', []),
# testing only, not included in application
('xstatic.pkg.jasmine', []),
('xstatic.pkg.termjs', []),
]
def get_xstatic_dirs(XSTATIC_MODULES, HORIZON_CONFIG):
"""Discover static file configuration of the xstatic modules.
For each entry in the XSTATIC_MODULES list we determine the entry
point files (which may come from the xstatic MAIN var) and then
determine where in the Django static tree the xstatic package's contents
should be placed.
For jquery.bootstrap.wizard.js the module name is None the static file is
actually a 3rd-party file but resides in the Horizon source tree and not
an xstatic package.
The xstatic.pkg.jquery_ui package had its contents moved by packagers so
it must be handled as a special case.
"""
STATICFILES_DIRS = []
HORIZON_CONFIG['xstatic_lib_files'] = []
for module_name, files in XSTATIC_MODULES:
module = import_module(module_name)
if module_name == 'xstatic.pkg.jquery_ui':
# determine the correct path for jquery-ui which packagers moved
if module.VERSION.startswith('1.10.'):
# The 1.10.x versions already contain 'ui' directory.
files = ['ui/' + files[0]]
STATICFILES_DIRS.append(
('horizon/lib/' + module.NAME, module.BASE_DIR)
)
# pull the file entry points from the xstatic package MAIN if possible
if hasattr(module, 'MAIN'):
files = module.MAIN
if not isinstance(files, list):
files = [files]
# just the Javascript files, please (don't <script> css, etc
# which is explicitly included in style/themes as appropriate)
files = [file for file in files if file.endswith('.js')]
# add to the list of files to link in the HTML
for file in files:
file = 'horizon/lib/' + module.NAME + '/' + file
HORIZON_CONFIG['xstatic_lib_files'].append(file)
return STATICFILES_DIRS
def find_static_files(
HORIZON_CONFIG,
AVAILABLE_THEMES,
THEME_COLLECTION_DIR,
ROOT_PATH):
import horizon
import openstack_dashboard
os_dashboard_home_dir = openstack_dashboard.__path__[0]
horizon_home_dir = horizon.__path__[0]
# note the path must end in a '/' or the resultant file paths will have a
# leading "/"
file_discovery.populate_horizon_config(
HORIZON_CONFIG,
os.path.join(horizon_home_dir, 'static/')
)
# filter out non-angular javascript code and lib
HORIZON_CONFIG['js_files'] = ([f for f in HORIZON_CONFIG['js_files']
if not f.startswith('horizon/')])
# note the path must end in a '/' or the resultant file paths will have a
# leading "/"
file_discovery.populate_horizon_config(
HORIZON_CONFIG,
os.path.join(os_dashboard_home_dir, 'static/'),
sub_path='app/'
)
# Discover theme static resources, and in particular any
# static HTML (client-side) that the theme overrides
theme_static_files = {}
theme_info = theme_settings.get_theme_static_dirs(
AVAILABLE_THEMES,
THEME_COLLECTION_DIR,
ROOT_PATH)
for url, path in theme_info:
discovered_files = {}
# discover static files provided by the theme
file_discovery.populate_horizon_config(
discovered_files,
path
)
# Get the theme name from the theme url
theme_name = url.split('/')[-1]
# build a dictionary of this theme's static HTML templates.
# For each overridden template, strip off the '/templates/' part of the
# theme filename then use that name as the key, and the location in the
# theme directory as the value. This allows the quick lookup of
# theme path for any file overridden by a theme template
template_overrides = {}
for theme_file in discovered_files['external_templates']:
# Example:
# external_templates_dict[
# 'framework/widgets/help-panel/help-panel.html'
# ] = 'themes/material/templates/framework/widgets/\
# help-panel/help-panel.html'
(templates_part, override_path) = theme_file.split('/templates/')
template_overrides[override_path] = 'themes/' + \
theme_name + theme_file
discovered_files['template_overrides'] = template_overrides
# Save all of the discovered file info for this theme in our
# 'theme_files' object using the theme name as the key
theme_static_files[theme_name] = discovered_files
# Add the theme file info to the horizon config for use by template tags
HORIZON_CONFIG['theme_static_files'] = theme_static_files

View File

@ -0,0 +1,11 @@
---
prelude: >
We now automatically determine the static folder
location for xstatic packages being used by Horizon.
upgrade:
- Many Javascript files have moved to new locations
in the horizon/lib static folder. Previously
the locations of some files were hard-coded but
now the locations are determined automatically
based on the xstatic package name.