Comprehensive theming

This is a squash of 38 commits ending with
5b080f979d692804452400ac5bed9b17c50b001e
This commit is contained in:
David Baumgold
2015-05-14 16:07:09 -04:00
parent 034570b31a
commit 6ebf2515f4
95 changed files with 1436 additions and 491 deletions

View File

@@ -0,0 +1,62 @@
"""
Core logic for Comprehensive Theming.
"""
from django.conf import settings
import edxmako
def comprehensive_theme_changes(theme_dir):
"""
Calculate the set of changes needed to enable a comprehensive theme.
Arguments:
theme_dir (path.path): the full path to the theming directory to use.
Returns:
A dict indicating the changes to make:
* 'settings': a dictionary of settings names and their new values.
* 'mako_paths': a list of directories to prepend to the edxmako
template lookup path.
"""
changes = {
'settings': {},
'mako_paths': [],
}
templates_dir = theme_dir / "lms" / "templates"
if templates_dir.isdir():
changes['settings']['TEMPLATE_DIRS'] = [templates_dir] + settings.TEMPLATE_DIRS
changes['mako_paths'].append(templates_dir)
staticfiles_dir = theme_dir / "lms" / "static"
if staticfiles_dir.isdir():
changes['settings']['STATICFILES_DIRS'] = [staticfiles_dir] + settings.STATICFILES_DIRS
locale_dir = theme_dir / "lms" / "conf" / "locale"
if locale_dir.isdir():
changes['settings']['LOCALE_PATHS'] = [locale_dir] + settings.LOCALE_PATHS
favicon = theme_dir / "lms" / "static" / "images" / "favicon.ico"
if favicon.isfile():
changes['settings']['FAVICON_PATH'] = str(favicon)
return changes
def enable_comprehensive_theme(theme_dir):
"""
Add directories to relevant paths for comprehensive theming.
"""
changes = comprehensive_theme_changes(theme_dir)
# Use the changes
for name, value in changes['settings'].iteritems():
setattr(settings, name, value)
for template_dir in changes['mako_paths']:
edxmako.paths.add_lookup('main', template_dir, prepend=True)

View File

@@ -0,0 +1,13 @@
"""
Startup code for Comprehensive Theming
"""
from django.conf import settings
from .core import enable_comprehensive_theme
def run():
"""Enable comprehensive theming, if we should."""
if settings.COMP_THEME_DIR:
enable_comprehensive_theme(theme_dir=settings.COMP_THEME_DIR)

View File

@@ -0,0 +1,89 @@
"""
Test helpers for Comprehensive Theming.
"""
from functools import wraps
import os
import os.path
from mock import patch
from django.conf import settings
from django.test.utils import override_settings
import edxmako
from .core import comprehensive_theme_changes
def with_comp_theme(theme_dir):
"""
A decorator to run a test with a particular comprehensive theme.
Arguments:
theme_dir (str): the full path to the theme directory to use.
This will likely use `settings.REPO_ROOT` to get the full path.
"""
# This decorator gets the settings changes needed for a theme, and applies
# them using the override_settings and edxmako.paths.add_lookup context
# managers.
changes = comprehensive_theme_changes(theme_dir)
def _decorator(func): # pylint: disable=missing-docstring
@wraps(func)
def _decorated(*args, **kwargs): # pylint: disable=missing-docstring
with override_settings(COMP_THEME_DIR=theme_dir, **changes['settings']):
with edxmako.save_lookups():
for template_dir in changes['mako_paths']:
edxmako.paths.add_lookup('main', template_dir, prepend=True)
return func(*args, **kwargs)
return _decorated
return _decorator
def with_is_edx_domain(is_edx_domain):
"""
A decorator to run a test as if IS_EDX_DOMAIN is true or false.
We are transitioning away from IS_EDX_DOMAIN and are moving toward an edX
theme. This decorator changes both settings to let tests stay isolated
from the details.
Arguments:
is_edx_domain (bool): are we an edX domain or not?
"""
# This is weird, it's a decorator that conditionally applies other
# decorators, which is confusing.
def _decorator(func): # pylint: disable=missing-docstring
if is_edx_domain:
# This applies @with_comp_theme to the func.
func = with_comp_theme(settings.REPO_ROOT / "themes" / "edx.org")(func)
# This applies @patch.dict() to the func to set IS_EDX_DOMAIN.
func = patch.dict('django.conf.settings.FEATURES', {"IS_EDX_DOMAIN": is_edx_domain})(func)
return func
return _decorator
def dump_theming_info():
"""Dump a bunch of theming information, for debugging."""
for namespace, lookup in edxmako.LOOKUP.items():
print "--- %s: %s" % (namespace, lookup.template_args['module_directory'])
for directory in lookup.directories:
print " %s" % (directory,)
print "=" * 80
for dirname, __, filenames in os.walk(settings.MAKO_MODULE_DIR):
print "%s ----------------" % (dir,)
for filename in sorted(filenames):
if filename.endswith(".pyc"):
continue
with open(os.path.join(dirname, filename)) as f:
content = len(f.read())
print " %s: %d" % (filename, content)