Merge pull request #2553 from edx/cdodge/microsite-cleanup
Address Microsite PR feedback - separate out middleware from microsite logic, shor...
This commit is contained in:
@@ -55,7 +55,7 @@ from contentstore import utils
|
||||
from student.roles import CourseInstructorRole, CourseStaffRole, CourseCreatorRole, GlobalStaff
|
||||
from student import auth
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
__all__ = ['course_info_handler', 'course_handler', 'course_info_update_handler',
|
||||
'settings_handler',
|
||||
@@ -535,7 +535,7 @@ def settings_handler(request, tag=None, package_id=None, branch=None, version_gu
|
||||
|
||||
# see if the ORG of this course can be attributed to a 'Microsite'. In that case, the
|
||||
# course about page should be editable in Studio
|
||||
about_page_editable = not MicrositeConfiguration.get_microsite_configuration_value_for_org(
|
||||
about_page_editable = not microsite.get_value_for_org(
|
||||
course_module.location.org,
|
||||
'ENABLE_MKTG_SITE',
|
||||
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
|
||||
|
||||
@@ -10,7 +10,7 @@ from django.conf import settings
|
||||
from edxmako.shortcuts import render_to_response
|
||||
|
||||
from external_auth.views import ssl_login_shortcut, ssl_get_cert_from_request
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
__all__ = ['signup', 'login_page', 'howitworks']
|
||||
|
||||
@@ -49,7 +49,7 @@ def login_page(request):
|
||||
{
|
||||
'csrf': csrf_token,
|
||||
'forgot_password_link': "//{base}/login#forgot-password-modal".format(base=settings.LMS_BASE),
|
||||
'platform_name': MicrositeConfiguration.get_microsite_configuration_value('platform_name', settings.PLATFORM_NAME),
|
||||
'platform_name': microsite.get_value('platform_name', settings.PLATFORM_NAME),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -239,16 +239,8 @@ VIRTUAL_UNIVERSITIES = ENV_TOKENS.get('VIRTUAL_UNIVERSITIES', [])
|
||||
MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = ENV_TOKENS.get("MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED", 5)
|
||||
MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = ENV_TOKENS.get("MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS", 15 * 60)
|
||||
|
||||
|
||||
MICROSITE_CONFIGURATION = ENV_TOKENS.get('MICROSITE_CONFIGURATION', {})
|
||||
MICROSITE_ROOT_DIR = ENV_TOKENS.get('MICROSITE_ROOT_DIR')
|
||||
if len(MICROSITE_CONFIGURATION.keys()) > 0:
|
||||
enable_microsites(
|
||||
MICROSITE_CONFIGURATION,
|
||||
SUBDOMAIN_BRANDING,
|
||||
VIRTUAL_UNIVERSITIES,
|
||||
microsites_root=path(MICROSITE_ROOT_DIR)
|
||||
)
|
||||
MICROSITE_ROOT_DIR = path(ENV_TOKENS.get('MICROSITE_ROOT_DIR', ''))
|
||||
|
||||
#### PASSWORD POLICY SETTINGS #####
|
||||
PASSWORD_MIN_LENGTH = ENV_TOKENS.get("PASSWORD_MIN_LENGTH")
|
||||
|
||||
@@ -27,7 +27,7 @@ Longer TODO:
|
||||
import sys
|
||||
import lms.envs.common
|
||||
from lms.envs.common import (
|
||||
USE_TZ, TECH_SUPPORT_EMAIL, PLATFORM_NAME, BUGS_EMAIL, DOC_STORE_CONFIG, enable_microsites, ALL_LANGUAGES
|
||||
USE_TZ, TECH_SUPPORT_EMAIL, PLATFORM_NAME, BUGS_EMAIL, DOC_STORE_CONFIG, ALL_LANGUAGES
|
||||
)
|
||||
from path import path
|
||||
|
||||
@@ -84,6 +84,9 @@ FEATURES = {
|
||||
|
||||
# Toggles embargo functionality
|
||||
'EMBARGO': False,
|
||||
|
||||
# Turn on/off Microsites feature
|
||||
'USE_MICROSITES': False,
|
||||
}
|
||||
ENABLE_JASMINE = False
|
||||
|
||||
|
||||
@@ -6,10 +6,7 @@ This is a localdev test for the Microsite processing pipeline
|
||||
# pylint: disable=W0401, W0614
|
||||
|
||||
from .dev import *
|
||||
from .dev import SUBDOMAIN_BRANDING, VIRTUAL_UNIVERSITIES
|
||||
|
||||
MICROSITE_NAMES = ['openedx']
|
||||
MICROSITE_CONFIGURATION = {}
|
||||
|
||||
if MICROSITE_NAMES and len(MICROSITE_NAMES) > 0:
|
||||
enable_microsites(MICROSITE_NAMES, MICROSITE_CONFIGURATION, SUBDOMAIN_BRANDING, VIRTUAL_UNIVERSITIES)
|
||||
FEATURES['USE_MICROSITES'] = True
|
||||
|
||||
@@ -199,3 +199,31 @@ FEATURES['DISABLE_RESET_EMAIL_TEST'] = True
|
||||
|
||||
# Toggles embargo on for testing
|
||||
FEATURES['EMBARGO'] = True
|
||||
|
||||
# set up some testing for microsites
|
||||
MICROSITE_CONFIGURATION = {
|
||||
"test_microsite": {
|
||||
"domain_prefix": "testmicrosite",
|
||||
"university": "test_microsite",
|
||||
"platform_name": "Test Microsite",
|
||||
"logo_image_url": "test_microsite/images/header-logo.png",
|
||||
"email_from_address": "test_microsite@edx.org",
|
||||
"payment_support_email": "test_microsite@edx.org",
|
||||
"ENABLE_MKTG_SITE": False,
|
||||
"SITE_NAME": "test_microsite.localhost",
|
||||
"course_org_filter": "TestMicrositeX",
|
||||
"course_about_show_social_links": False,
|
||||
"css_overrides_file": "test_microsite/css/test_microsite.css",
|
||||
"show_partners": False,
|
||||
"show_homepage_promo_video": False,
|
||||
"course_index_overlay_text": "This is a Test Microsite Overlay Text.",
|
||||
"course_index_overlay_logo_file": "test_microsite/images/header-logo.png",
|
||||
"homepage_overlay_html": "<h1>This is a Test Microsite Overlay HTML</h1>"
|
||||
},
|
||||
"default": {
|
||||
"university": "default_university",
|
||||
"domain_prefix": "www",
|
||||
}
|
||||
}
|
||||
MICROSITE_ROOT_DIR = COMMON_ROOT / 'test' / 'test_microsites'
|
||||
FEATURES['USE_MICROSITES'] = True
|
||||
|
||||
@@ -16,7 +16,7 @@ from django.template import Context
|
||||
from django.http import HttpResponse
|
||||
import logging
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
from edxmako import lookup_template
|
||||
import edxmako.middleware
|
||||
@@ -37,7 +37,7 @@ def marketing_link(name):
|
||||
# link_map maps URLs from the marketing site to the old equivalent on
|
||||
# the Django site
|
||||
link_map = settings.MKTG_URL_LINK_MAP
|
||||
enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
enable_mktg_site = microsite.get_value(
|
||||
'ENABLE_MKTG_SITE',
|
||||
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
|
||||
)
|
||||
@@ -80,7 +80,7 @@ def marketing_link_context_processor(request):
|
||||
def render_to_string(template_name, dictionary, context=None, namespace='main'):
|
||||
|
||||
# see if there is an override template defined in the microsite
|
||||
template_name = MicrositeConfiguration.get_microsite_template_path(template_name)
|
||||
template_name = microsite.get_template_path(template_name)
|
||||
|
||||
context_instance = Context(dictionary)
|
||||
# add dictionary to context_instance
|
||||
@@ -111,7 +111,7 @@ def render_to_response(template_name, dictionary=None, context_instance=None, na
|
||||
"""
|
||||
|
||||
# see if there is an override template defined in the microsite
|
||||
template_name = MicrositeConfiguration.get_microsite_template_path(template_name)
|
||||
template_name = microsite.get_template_path(template_name)
|
||||
|
||||
dictionary = dictionary or {}
|
||||
return HttpResponse(render_to_string(template_name, dictionary, context_instance, namespace), **kwargs)
|
||||
|
||||
@@ -8,6 +8,9 @@ from . import add_lookup
|
||||
def run():
|
||||
"""
|
||||
Setup mako lookup directories.
|
||||
|
||||
IMPORTANT: This method can be called multiple times during application startup. Any changes to this method
|
||||
must be safe for multiple callers during startup phase.
|
||||
"""
|
||||
template_locations = settings.MAKO_TEMPLATES
|
||||
for namespace, directories in template_locations.items():
|
||||
|
||||
142
common/djangoapps/microsite_configuration/microsite.py
Normal file
142
common/djangoapps/microsite_configuration/microsite.py
Normal file
@@ -0,0 +1,142 @@
|
||||
"""
|
||||
This file implements the Microsite support for the Open edX platform.
|
||||
A microsite enables the following features:
|
||||
|
||||
1) Mapping of sub-domain name to a 'brand', e.g. foo-university.edx.org
|
||||
2) Present a landing page with a listing of courses that are specific to the 'brand'
|
||||
3) Ability to swap out some branding elements in the website
|
||||
"""
|
||||
import threading
|
||||
import os.path
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
CURRENT_REQUEST_CONFIGURATION = threading.local()
|
||||
CURRENT_REQUEST_CONFIGURATION.data = {}
|
||||
|
||||
|
||||
def has_configuration_set():
|
||||
"""
|
||||
Returns whether there is any Microsite configuration settings
|
||||
"""
|
||||
return getattr(settings, "MICROSITE_CONFIGURATION", False)
|
||||
|
||||
|
||||
def get_configuration():
|
||||
"""
|
||||
Returns the current request's microsite configuration
|
||||
"""
|
||||
if not hasattr(CURRENT_REQUEST_CONFIGURATION, 'data'):
|
||||
return {}
|
||||
|
||||
return CURRENT_REQUEST_CONFIGURATION.data
|
||||
|
||||
|
||||
def is_request_in_microsite():
|
||||
"""
|
||||
This will return if current request is a request within a microsite
|
||||
"""
|
||||
return get_configuration()
|
||||
|
||||
|
||||
def get_value(val_name, default=None):
|
||||
"""
|
||||
Returns a value associated with the request's microsite, if present
|
||||
"""
|
||||
configuration = get_configuration()
|
||||
return configuration.get(val_name, default)
|
||||
|
||||
|
||||
def get_template_path(relative_path):
|
||||
"""
|
||||
Returns a path (string) to a Mako template, which can either be in
|
||||
a microsite directory (as an override) or will just return what is passed in which is
|
||||
expected to be a string
|
||||
"""
|
||||
|
||||
if not is_request_in_microsite():
|
||||
return relative_path
|
||||
|
||||
microsite_template_path = str(get_value('template_dir'))
|
||||
|
||||
if microsite_template_path:
|
||||
search_path = os.path.join(microsite_template_path, relative_path)
|
||||
|
||||
if os.path.isfile(search_path):
|
||||
path = '{0}/templates/{1}'.format(
|
||||
get_value('microsite_name'),
|
||||
relative_path
|
||||
)
|
||||
return path
|
||||
|
||||
return relative_path
|
||||
|
||||
|
||||
def get_value_for_org(org, val_name, default=None):
|
||||
"""
|
||||
This returns a configuration value for a microsite which has an org_filter that matches
|
||||
what is passed in
|
||||
"""
|
||||
if not has_configuration_set():
|
||||
return default
|
||||
|
||||
for value in settings.MICROSITE_CONFIGURATION.values():
|
||||
org_filter = value.get('course_org_filter', None)
|
||||
if org_filter == org:
|
||||
return value.get(val_name, default)
|
||||
return default
|
||||
|
||||
|
||||
def get_all_orgs():
|
||||
"""
|
||||
This returns a set of orgs that are considered within a microsite. This can be used,
|
||||
for example, to do filtering
|
||||
"""
|
||||
org_filter_set = set()
|
||||
if not has_configuration_set():
|
||||
return org_filter_set
|
||||
|
||||
for value in settings.MICROSITE_CONFIGURATION.values():
|
||||
org_filter = value.get('course_org_filter')
|
||||
if org_filter:
|
||||
org_filter_set.add(org_filter)
|
||||
|
||||
return org_filter_set
|
||||
|
||||
|
||||
def clear():
|
||||
"""
|
||||
Clears out any microsite configuration from the current request/thread
|
||||
"""
|
||||
CURRENT_REQUEST_CONFIGURATION.data = {}
|
||||
|
||||
|
||||
def _set_current_microsite(microsite_config_key, subdomain, domain):
|
||||
"""
|
||||
Helper internal method to actually put a microsite on the threadlocal
|
||||
"""
|
||||
config = settings.MICROSITE_CONFIGURATION[microsite_config_key].copy()
|
||||
config['subdomain'] = subdomain
|
||||
config['site_domain'] = domain
|
||||
CURRENT_REQUEST_CONFIGURATION.data = config
|
||||
|
||||
|
||||
def set_by_domain(domain):
|
||||
"""
|
||||
For a given request domain, find a match in our microsite configuration and then assign
|
||||
it to the thread local so that it is available throughout the entire
|
||||
Django request processing
|
||||
"""
|
||||
if not has_configuration_set() or not domain:
|
||||
return
|
||||
|
||||
for key, value in settings.MICROSITE_CONFIGURATION.items():
|
||||
subdomain = value.get('domain_prefix')
|
||||
if subdomain and domain.startswith(subdomain):
|
||||
_set_current_microsite(key, subdomain, domain)
|
||||
return
|
||||
|
||||
# if no match on subdomain then see if there is a 'default' microsite defined
|
||||
# if so, then use that
|
||||
if 'default' in settings.MICROSITE_CONFIGURATION:
|
||||
_set_current_microsite('default', subdomain, domain)
|
||||
@@ -1,183 +1,36 @@
|
||||
"""
|
||||
This file implements the initial Microsite support for the Open edX platform.
|
||||
This file implements the Middleware support for the Open edX platform.
|
||||
A microsite enables the following features:
|
||||
|
||||
1) Mapping of sub-domain name to a 'brand', e.g. foo-university.edx.org
|
||||
2) Present a landing page with a listing of courses that are specific to the 'brand'
|
||||
3) Ability to swap out some branding elements in the website
|
||||
"""
|
||||
import threading
|
||||
import os.path
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
_microsite_configuration_threadlocal = threading.local()
|
||||
_microsite_configuration_threadlocal.data = {}
|
||||
from microsite_configuration import microsite
|
||||
|
||||
|
||||
def has_microsite_configuration_set():
|
||||
"""
|
||||
Returns whether the MICROSITE_CONFIGURATION has been set in the configuration files
|
||||
"""
|
||||
return getattr(settings, "MICROSITE_CONFIGURATION", False)
|
||||
|
||||
|
||||
class MicrositeConfiguration(object):
|
||||
class MicrositeMiddleware(object):
|
||||
"""
|
||||
Middleware class which will bind configuration information regarding 'microsites' on a per request basis.
|
||||
The actual configuration information is taken from Django settings information
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def is_request_in_microsite(cls):
|
||||
"""
|
||||
This will return if current request is a request within a microsite
|
||||
"""
|
||||
return cls.get_microsite_configuration()
|
||||
|
||||
@classmethod
|
||||
def get_microsite_configuration(cls):
|
||||
"""
|
||||
Returns the current request's microsite configuration
|
||||
"""
|
||||
if not hasattr(_microsite_configuration_threadlocal, 'data'):
|
||||
return {}
|
||||
|
||||
return _microsite_configuration_threadlocal.data
|
||||
|
||||
@classmethod
|
||||
def get_microsite_configuration_value(cls, val_name, default=None):
|
||||
"""
|
||||
Returns a value associated with the request's microsite, if present
|
||||
"""
|
||||
configuration = cls.get_microsite_configuration()
|
||||
return configuration.get(val_name, default)
|
||||
|
||||
@classmethod
|
||||
def get_microsite_template_path(cls, relative_path):
|
||||
"""
|
||||
Returns a path to a Mako template, which can either be in
|
||||
a microsite directory (as an override) or will just return what is passed in
|
||||
"""
|
||||
|
||||
if not cls.is_request_in_microsite():
|
||||
return relative_path
|
||||
|
||||
microsite_template_path = cls.get_microsite_configuration_value('template_dir')
|
||||
|
||||
if microsite_template_path:
|
||||
search_path = microsite_template_path / relative_path
|
||||
|
||||
if os.path.isfile(search_path):
|
||||
path = '{0}/templates/{1}'.format(
|
||||
cls.get_microsite_configuration_value('microsite_name'),
|
||||
relative_path
|
||||
)
|
||||
return path
|
||||
|
||||
return relative_path
|
||||
|
||||
@classmethod
|
||||
def get_microsite_configuration_value_for_org(cls, org, val_name, default=None):
|
||||
"""
|
||||
This returns a configuration value for a microsite which has an org_filter that matches
|
||||
what is passed in
|
||||
"""
|
||||
if not has_microsite_configuration_set():
|
||||
return default
|
||||
|
||||
for key in settings.MICROSITE_CONFIGURATION.keys():
|
||||
org_filter = settings.MICROSITE_CONFIGURATION[key].get('course_org_filter', None)
|
||||
if org_filter == org:
|
||||
return settings.MICROSITE_CONFIGURATION[key].get(val_name, default)
|
||||
return default
|
||||
|
||||
@classmethod
|
||||
def get_all_microsite_orgs(cls):
|
||||
"""
|
||||
This returns a set of orgs that are considered within a Microsite. This can be used,
|
||||
for example, to do filtering
|
||||
"""
|
||||
org_filter_set = []
|
||||
if not has_microsite_configuration_set():
|
||||
return org_filter_set
|
||||
|
||||
for key in settings.MICROSITE_CONFIGURATION:
|
||||
org_filter = settings.MICROSITE_CONFIGURATION[key].get('course_org_filter')
|
||||
if org_filter:
|
||||
org_filter_set.append(org_filter)
|
||||
|
||||
return org_filter_set
|
||||
|
||||
def clear_microsite_configuration(self):
|
||||
"""
|
||||
Clears out any microsite configuration from the current request/thread
|
||||
"""
|
||||
_microsite_configuration_threadlocal.data = {}
|
||||
|
||||
def process_request(self, request):
|
||||
"""
|
||||
Middleware entry point on every request processing. This will associate a request's domain name
|
||||
with a 'University' and any corresponding microsite configuration information
|
||||
"""
|
||||
self.clear_microsite_configuration()
|
||||
microsite.clear()
|
||||
|
||||
domain = request.META.get('HTTP_HOST', None)
|
||||
|
||||
if domain:
|
||||
subdomain = MicrositeConfiguration.pick_subdomain(domain, settings.SUBDOMAIN_BRANDING.keys())
|
||||
university = MicrositeConfiguration.match_university(subdomain)
|
||||
microsite_configuration = self.get_microsite_configuration_for_university(university)
|
||||
if microsite_configuration:
|
||||
microsite_configuration['university'] = university
|
||||
microsite_configuration['subdomain'] = subdomain
|
||||
microsite_configuration['site_domain'] = domain
|
||||
_microsite_configuration_threadlocal.data = microsite_configuration
|
||||
microsite.set_by_domain(domain)
|
||||
|
||||
# also put the configuration on the request itself to make it easier to dereference
|
||||
request.microsite_configuration = _microsite_configuration_threadlocal.data
|
||||
return None
|
||||
|
||||
def process_response(self, request, response):
|
||||
"""
|
||||
Middleware entry point for request completion.
|
||||
"""
|
||||
self.clear_microsite_configuration()
|
||||
microsite.clear()
|
||||
return response
|
||||
|
||||
def get_microsite_configuration_for_university(self, university):
|
||||
"""
|
||||
For a given university, return the microsite configuration which
|
||||
is in the Django settings
|
||||
"""
|
||||
if not university:
|
||||
return None
|
||||
|
||||
if not has_microsite_configuration_set():
|
||||
return None
|
||||
|
||||
configuration = settings.MICROSITE_CONFIGURATION.get(university, None)
|
||||
return configuration
|
||||
|
||||
@classmethod
|
||||
def match_university(cls, domain):
|
||||
"""
|
||||
Return the university name specified for the domain, or None
|
||||
if no university was specified
|
||||
"""
|
||||
if not settings.FEATURES['SUBDOMAIN_BRANDING'] or domain is None:
|
||||
return None
|
||||
|
||||
subdomain = cls.pick_subdomain(domain, settings.SUBDOMAIN_BRANDING.keys())
|
||||
return settings.SUBDOMAIN_BRANDING.get(subdomain)
|
||||
|
||||
@classmethod
|
||||
def pick_subdomain(cls, domain, options, default='default'):
|
||||
"""
|
||||
Attempt to match the incoming request's HOST domain with a configuration map
|
||||
to see what subdomains are supported in Microsites.
|
||||
"""
|
||||
for option in options:
|
||||
if domain.startswith(option):
|
||||
return option
|
||||
return default
|
||||
|
||||
@@ -4,7 +4,7 @@ based on the current micro site.
|
||||
"""
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@@ -37,4 +37,4 @@ def platform_name():
|
||||
Django template tag that outputs the current platform name:
|
||||
{% platform_name %}
|
||||
"""
|
||||
return MicrositeConfiguration.get_microsite_configuration_value('platform_name', settings.PLATFORM_NAME)
|
||||
return microsite.get_value('platform_name', settings.PLATFORM_NAME)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
Some additional unit tests for Microsite logic. The LMS covers some of the Microsite testing, this adds
|
||||
some additional coverage
|
||||
"""
|
||||
import django.test
|
||||
|
||||
from microsite_configuration.microsite import get_value_for_org
|
||||
|
||||
|
||||
class TestMicrosites(django.test.TestCase):
|
||||
"""
|
||||
Run through some Microsite logic
|
||||
"""
|
||||
|
||||
def test_get_value_for_org(self):
|
||||
"""
|
||||
Make sure we can do lookups on Microsite configuration based on ORG fields
|
||||
"""
|
||||
|
||||
# first make sure default value is returned if there's no Microsite ORG match
|
||||
value = get_value_for_org("BogusX", "university", "default_value")
|
||||
self.assertEquals(value, "default_value")
|
||||
|
||||
# now test when we call in a value Microsite ORG, note this is defined in test.py configuration
|
||||
value = get_value_for_org("TestMicrositeX", "university", "default_value")
|
||||
self.assertEquals(value, "test_microsite")
|
||||
@@ -4,10 +4,13 @@ Tests microsite_configuration templatetags and helper functions.
|
||||
"""
|
||||
from django.test import TestCase
|
||||
from django.conf import settings
|
||||
from .templatetags import microsite
|
||||
from microsite_configuration.templatetags import microsite
|
||||
|
||||
|
||||
class MicroSiteTests(TestCase):
|
||||
"""
|
||||
Make sure some of the helper functions work
|
||||
"""
|
||||
def test_breadcrumbs(self):
|
||||
crumbs = ['my', 'less specific', 'Page']
|
||||
expected = u'my | less specific | Page | edX'
|
||||
@@ -23,10 +26,9 @@ class MicroSiteTests(TestCase):
|
||||
def test_platform_name(self):
|
||||
pname = microsite.platform_name()
|
||||
self.assertEqual(pname, settings.PLATFORM_NAME)
|
||||
|
||||
|
||||
def test_breadcrumb_tag(self):
|
||||
crumbs = ['my', 'less specific', 'Page']
|
||||
expected = u'my | less specific | Page | edX'
|
||||
title = microsite.page_title_breadcrumbs_tag(None, *crumbs)
|
||||
self.assertEqual(expected, title)
|
||||
|
||||
@@ -74,7 +74,7 @@ from dogapi import dog_stats_api
|
||||
from util.json_request import JsonResponse
|
||||
from util.bad_request_rate_limiter import BadRequestRateLimiter
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
from util.password_policy_validators import (
|
||||
validate_password_length, validate_password_complexity,
|
||||
@@ -350,7 +350,7 @@ def signin_user(request):
|
||||
context = {
|
||||
'course_id': request.GET.get('course_id'),
|
||||
'enrollment_action': request.GET.get('enrollment_action'),
|
||||
'platform_name': MicrositeConfiguration.get_microsite_configuration_value(
|
||||
'platform_name': microsite.get_value(
|
||||
'platform_name',
|
||||
settings.PLATFORM_NAME
|
||||
),
|
||||
@@ -373,7 +373,7 @@ def register_user(request, extra_context=None):
|
||||
context = {
|
||||
'course_id': request.GET.get('course_id'),
|
||||
'enrollment_action': request.GET.get('enrollment_action'),
|
||||
'platform_name': MicrositeConfiguration.get_microsite_configuration_value(
|
||||
'platform_name': microsite.get_value(
|
||||
'platform_name',
|
||||
settings.PLATFORM_NAME
|
||||
),
|
||||
@@ -416,11 +416,11 @@ def dashboard(request):
|
||||
|
||||
# for microsites, we want to filter and only show enrollments for courses within
|
||||
# the microsites 'ORG'
|
||||
course_org_filter = MicrositeConfiguration.get_microsite_configuration_value('course_org_filter')
|
||||
course_org_filter = microsite.get_value('course_org_filter')
|
||||
|
||||
# Let's filter out any courses in an "org" that has been declared to be
|
||||
# in a Microsite
|
||||
org_filter_out_set = MicrositeConfiguration.get_all_microsite_orgs()
|
||||
org_filter_out_set = microsite.get_all_orgs()
|
||||
|
||||
# remove our current Microsite from the "filter out" list, if applicable
|
||||
if course_org_filter:
|
||||
@@ -1160,7 +1160,7 @@ def create_account(request, post_override=None):
|
||||
|
||||
# don't send email if we are doing load testing or random user generation for some reason
|
||||
if not (settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')):
|
||||
from_address = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
from_address = microsite.get_value(
|
||||
'email_from_address',
|
||||
settings.DEFAULT_FROM_EMAIL
|
||||
)
|
||||
@@ -1502,7 +1502,7 @@ def change_email_request(request):
|
||||
|
||||
message = render_to_string('emails/email_change.txt', context)
|
||||
|
||||
from_address = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
from_address = microsite.get_value(
|
||||
'email_from_address',
|
||||
settings.DEFAULT_FROM_EMAIL
|
||||
)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
COURSE_REGEX = re.compile(r'^.*?/courses/(?P<course_id>[^/]+/[^/]+/[^/]+)')
|
||||
|
||||
@@ -19,7 +19,7 @@ def safe_get_host(request):
|
||||
if isinstance(settings.ALLOWED_HOSTS, (list, tuple)) and '*' not in settings.ALLOWED_HOSTS:
|
||||
return request.get_host()
|
||||
else:
|
||||
return MicrositeConfiguration.get_microsite_configuration_value('site_domain', settings.SITE_NAME)
|
||||
return microsite.get_value('site_domain', settings.SITE_NAME)
|
||||
|
||||
|
||||
def course_id_from_url(url):
|
||||
|
||||
3
common/test/test_microsites/default/readme.txt
Normal file
3
common/test/test_microsites/default/readme.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
This directory is intentionally empty.
|
||||
|
||||
We need to have a directory on disk for the corresponding Microsite configuration to be considered 'valid'. Therefore to execute some 'default' use-cases, we have this empty directory.
|
||||
@@ -1,7 +1,7 @@
|
||||
## mako
|
||||
<%! from django.core.urlresolvers import reverse %>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ from xmodule.modulestore.django import modulestore
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
from django.conf import settings
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
|
||||
def get_visible_courses():
|
||||
@@ -15,7 +15,7 @@ def get_visible_courses():
|
||||
if isinstance(c, CourseDescriptor)]
|
||||
courses = sorted(courses, key=lambda course: course.number)
|
||||
|
||||
subdomain = MicrositeConfiguration.get_microsite_configuration_value('subdomain', 'default')
|
||||
subdomain = microsite.get_value('subdomain', 'default')
|
||||
|
||||
# See if we have filtered course listings in this domain
|
||||
filtered_visible_ids = None
|
||||
@@ -24,7 +24,7 @@ def get_visible_courses():
|
||||
if hasattr(settings, 'COURSE_LISTINGS') and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG:
|
||||
filtered_visible_ids = frozenset(settings.COURSE_LISTINGS[subdomain])
|
||||
|
||||
filtered_by_org = MicrositeConfiguration.get_microsite_configuration_value('course_org_filter')
|
||||
filtered_by_org = microsite.get_value('course_org_filter')
|
||||
|
||||
if filtered_by_org:
|
||||
return [course for course in courses if course.location.org == filtered_by_org]
|
||||
@@ -33,7 +33,7 @@ def get_visible_courses():
|
||||
else:
|
||||
# Let's filter out any courses in an "org" that has been declared to be
|
||||
# in a Microsite
|
||||
org_filter_out_set = MicrositeConfiguration.get_all_microsite_orgs()
|
||||
org_filter_out_set = microsite.get_all_orgs()
|
||||
return [course for course in courses if course.location.org not in org_filter_out_set]
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ def get_university_for_request():
|
||||
Return the university name specified for the domain, or None
|
||||
if no university was specified
|
||||
"""
|
||||
return MicrositeConfiguration.get_microsite_configuration_value('university')
|
||||
return microsite.get_value('university')
|
||||
|
||||
|
||||
def get_logo_url():
|
||||
@@ -52,7 +52,7 @@ def get_logo_url():
|
||||
|
||||
# if the MicrositeConfiguration has a value for the logo_image_url
|
||||
# let's use that
|
||||
image_url = MicrositeConfiguration.get_microsite_configuration_value('logo_image_url')
|
||||
image_url = microsite.get_value('logo_image_url')
|
||||
if image_url:
|
||||
return '{static_url}{image_url}'.format(
|
||||
static_url=settings.STATIC_URL,
|
||||
@@ -60,7 +60,7 @@ def get_logo_url():
|
||||
)
|
||||
|
||||
# otherwise, use the legacy means to configure this
|
||||
university = MicrositeConfiguration.get_microsite_configuration_value('university')
|
||||
university = microsite.get_value('university')
|
||||
|
||||
if university is None:
|
||||
return '{static_url}images/header-logo.png'.format(
|
||||
|
||||
@@ -8,7 +8,7 @@ from edxmako.shortcuts import render_to_response
|
||||
import student.views
|
||||
import courseware.views
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
from edxmako.shortcuts import marketing_link
|
||||
from util.cache import cache_if_anonymous
|
||||
|
||||
@@ -27,7 +27,7 @@ def index(request):
|
||||
from external_auth.views import ssl_login
|
||||
return ssl_login(request)
|
||||
|
||||
enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
enable_mktg_site = microsite.get_value(
|
||||
'ENABLE_MKTG_SITE',
|
||||
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
|
||||
)
|
||||
@@ -35,11 +35,11 @@ def index(request):
|
||||
if enable_mktg_site:
|
||||
return redirect(settings.MKTG_URLS.get('ROOT'))
|
||||
|
||||
university = MicrositeConfiguration.match_university(request.META.get('HTTP_HOST'))
|
||||
domain = request.META.get('HTTP_HOST')
|
||||
|
||||
# keep specialized logic for Edge until we can migrate over Edge to fully use
|
||||
# microsite definitions
|
||||
if university == 'edge':
|
||||
if domain and 'edge.edx.org' in domain:
|
||||
context = {
|
||||
'suppress_toplevel_navigation': True
|
||||
}
|
||||
@@ -59,7 +59,7 @@ def courses(request):
|
||||
to that. Otherwise, if subdomain branding is on, this is the university
|
||||
profile page. Otherwise, it's the edX courseware.views.courses page
|
||||
"""
|
||||
enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
enable_mktg_site = microsite.get_value(
|
||||
'ENABLE_MKTG_SITE',
|
||||
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
|
||||
)
|
||||
|
||||
@@ -70,7 +70,7 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
self.assertContains(resp, 'This is a Test Microsite Overlay') # Overlay test message
|
||||
self.assertContains(resp, 'test_microsite/images/header-logo.png') # logo swap
|
||||
self.assertContains(resp, 'test_microsite/css/test_microsite.css') # css override
|
||||
self.assertContains(resp, 'test_microsite/css/test_microsite') # css override
|
||||
self.assertContains(resp, 'Test Microsite') # page title
|
||||
|
||||
# assert that test course display name is visible
|
||||
@@ -101,7 +101,7 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
self.assertNotContains(resp, 'This is a Test Microsite Overlay') # Overlay test message
|
||||
self.assertNotContains(resp, 'test_microsite/images/header-logo.png') # logo swap
|
||||
self.assertNotContains(resp, 'test_microsite/css/test_microsite.css') # css override
|
||||
self.assertNotContains(resp, 'test_microsite/css/test_microsite') # css override
|
||||
self.assertNotContains(resp, '<title>Test Microsite</title>') # page title
|
||||
|
||||
# assert that test course display name IS NOT VISIBLE, since that is a Microsite only course
|
||||
|
||||
@@ -38,7 +38,7 @@ from xmodule.modulestore.search import path_to_location
|
||||
from xmodule.course_module import CourseDescriptor
|
||||
import shoppingcart
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
log = logging.getLogger("edx.courseware")
|
||||
|
||||
@@ -528,7 +528,7 @@ def registered_for_course(course, user):
|
||||
@cache_if_anonymous
|
||||
def course_about(request, course_id):
|
||||
|
||||
if MicrositeConfiguration.get_microsite_configuration_value(
|
||||
if microsite.get_value(
|
||||
'ENABLE_MKTG_SITE',
|
||||
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
|
||||
):
|
||||
|
||||
@@ -14,7 +14,7 @@ from student.models import CourseEnrollment, CourseEnrollmentAllowed
|
||||
from courseware.models import StudentModule
|
||||
from edxmako.shortcuts import render_to_string
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
# For determining if a shibboleth course
|
||||
SHIBBOLETH_DOMAIN_PREFIX = 'shib:'
|
||||
@@ -229,7 +229,7 @@ def send_mail_to_student(student, param_dict):
|
||||
if 'course' in param_dict:
|
||||
param_dict['course_name'] = param_dict['course'].display_name_with_default
|
||||
|
||||
param_dict['site_name'] = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
param_dict['site_name'] = microsite.get_value(
|
||||
'SITE_NAME',
|
||||
param_dict['site_name']
|
||||
)
|
||||
@@ -271,7 +271,7 @@ def send_mail_to_student(student, param_dict):
|
||||
|
||||
# Email subject *must not* contain newlines
|
||||
subject = ''.join(subject.splitlines())
|
||||
from_address = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
from_address = microsite.get_value(
|
||||
'email_from_address',
|
||||
settings.DEFAULT_FROM_EMAIL
|
||||
)
|
||||
|
||||
@@ -62,7 +62,7 @@ from xblock.field_data import DictFieldData
|
||||
from xblock.fields import ScopeIds
|
||||
from django.utils.translation import ugettext as _u
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -1295,7 +1295,7 @@ def _do_enroll_students(course, course_id, students, overload=False, auto_enroll
|
||||
ceaset.delete()
|
||||
|
||||
if email_students:
|
||||
stripped_site_name = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
stripped_site_name = microsite.get_value(
|
||||
'SITE_NAME',
|
||||
settings.SITE_NAME
|
||||
)
|
||||
@@ -1389,7 +1389,7 @@ def _do_unenroll_students(course_id, students, email_students=False):
|
||||
old_students, _ = get_and_clean_student_list(students)
|
||||
status = dict([x, 'unprocessed'] for x in old_students)
|
||||
|
||||
stripped_site_name = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
stripped_site_name = microsite.get_value(
|
||||
'SITE_NAME',
|
||||
settings.SITE_NAME
|
||||
)
|
||||
@@ -1469,7 +1469,7 @@ def send_mail_to_student(student, param_dict):
|
||||
# add some helpers and microconfig subsitutions
|
||||
if 'course' in param_dict:
|
||||
param_dict['course_name'] = param_dict['course'].display_name_with_default
|
||||
param_dict['site_name'] = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
param_dict['site_name'] = microsite.get_value(
|
||||
'SITE_NAME',
|
||||
param_dict.get('site_name', '')
|
||||
)
|
||||
@@ -1497,7 +1497,7 @@ def send_mail_to_student(student, param_dict):
|
||||
|
||||
# Email subject *must not* contain newlines
|
||||
subject = ''.join(subject.splitlines())
|
||||
from_address = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
from_address = microsite.get_value(
|
||||
'email_from_address',
|
||||
settings.DEFAULT_FROM_EMAIL
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ from verify_student.models import SoftwareSecurePhotoVerification
|
||||
from .exceptions import (InvalidCartItem, PurchasedCallbackException, ItemAlreadyInCartException,
|
||||
AlreadyEnrolledInCourseException, CourseDoesNotExistException)
|
||||
|
||||
from microsite_configuration.middleware import MicrositeConfiguration
|
||||
from microsite_configuration import microsite
|
||||
|
||||
log = logging.getLogger("shoppingcart")
|
||||
|
||||
@@ -175,7 +175,7 @@ class Order(models.Model):
|
||||
}
|
||||
)
|
||||
try:
|
||||
from_address = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
from_address = microsite.get_value(
|
||||
'email_from_address',
|
||||
settings.DEFAULT_FROM_EMAIL
|
||||
)
|
||||
@@ -477,7 +477,7 @@ class CertificateItem(OrderItem):
|
||||
user_email=course_enrollment.user.email,
|
||||
order_number=order_number)
|
||||
to_email = [settings.PAYMENT_SUPPORT_EMAIL]
|
||||
from_email = [MicrositeConfiguration.get_microsite_configuration_value(
|
||||
from_email = [microsite.get_value(
|
||||
'payment_support_email',
|
||||
settings.PAYMENT_SUPPORT_EMAIL
|
||||
)]
|
||||
|
||||
@@ -356,14 +356,7 @@ MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = ENV_TOKENS.get("MAX_FAILED_LOGIN_ATTEMPTS_AL
|
||||
MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS = ENV_TOKENS.get("MAX_FAILED_LOGIN_ATTEMPTS_LOCKOUT_PERIOD_SECS", 15 * 60)
|
||||
|
||||
MICROSITE_CONFIGURATION = ENV_TOKENS.get('MICROSITE_CONFIGURATION', {})
|
||||
MICROSITE_ROOT_DIR = ENV_TOKENS.get('MICROSITE_ROOT_DIR')
|
||||
if MICROSITE_CONFIGURATION:
|
||||
enable_microsites(
|
||||
MICROSITE_CONFIGURATION,
|
||||
SUBDOMAIN_BRANDING,
|
||||
VIRTUAL_UNIVERSITIES,
|
||||
microsites_root=path(MICROSITE_ROOT_DIR)
|
||||
)
|
||||
MICROSITE_ROOT_DIR = path(ENV_TOKENS.get('MICROSITE_ROOT_DIR', ''))
|
||||
|
||||
#### PASSWORD POLICY SETTINGS #####
|
||||
PASSWORD_MIN_LENGTH = ENV_TOKENS.get("PASSWORD_MIN_LENGTH")
|
||||
|
||||
@@ -6,7 +6,7 @@ This is a localdev test for the Microsite processing pipeline
|
||||
# pylint: disable=W0401, W0614
|
||||
|
||||
from .dev import *
|
||||
from .dev import SUBDOMAIN_BRANDING, VIRTUAL_UNIVERSITIES
|
||||
from ..dev import ENV_ROOT, FEATURES
|
||||
|
||||
|
||||
MICROSITE_CONFIGURATION = {
|
||||
@@ -30,13 +30,9 @@ MICROSITE_CONFIGURATION = {
|
||||
}
|
||||
}
|
||||
|
||||
if len(MICROSITE_CONFIGURATION.keys()) > 0:
|
||||
enable_microsites(
|
||||
MICROSITE_CONFIGURATION,
|
||||
SUBDOMAIN_BRANDING,
|
||||
VIRTUAL_UNIVERSITIES
|
||||
)
|
||||
MICROSITE_ROOT_DIR = ENV_ROOT / 'edx-microsite'
|
||||
|
||||
# pretend we are behind some marketing site, we want to be able to assert that the Microsite config values override
|
||||
# this global setting
|
||||
FEATURES['ENABLE_MKTG_SITE'] = True
|
||||
FEATURES['USE_MICROSITES'] = True
|
||||
|
||||
@@ -229,6 +229,9 @@ FEATURES = {
|
||||
# that people can submit content and modify the Wiki in any arbitrary manner. We're leaving this as True in the
|
||||
# defaults, so that we maintain current behavior
|
||||
'ALLOW_WIKI_ROOT_ACCESS': True,
|
||||
|
||||
# Turn on/off Microsites feature
|
||||
'USE_MICROSITES': False,
|
||||
}
|
||||
|
||||
# Used for A/B testing
|
||||
@@ -693,7 +696,7 @@ TEMPLATE_LOADERS = (
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'request_cache.middleware.RequestCache',
|
||||
'microsite_configuration.middleware.MicrositeConfiguration',
|
||||
'microsite_configuration.middleware.MicrositeMiddleware',
|
||||
'django_comment_client.middleware.AjaxExceptionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
@@ -1183,64 +1186,6 @@ MKTG_URL_LINK_MAP = {
|
||||
}
|
||||
|
||||
|
||||
############################### MICROSITES ################################
|
||||
def enable_microsites(microsite_config_dict, subdomain_branding, virtual_universities, microsites_root=ENV_ROOT / "microsites"):
|
||||
"""
|
||||
Enable the use of microsites, which are websites that allow
|
||||
for subdomains for the edX platform, e.g. foo.edx.org
|
||||
"""
|
||||
|
||||
if not microsite_config_dict:
|
||||
return
|
||||
|
||||
FEATURES['USE_MICROSITES'] = True
|
||||
|
||||
for microsite_name in microsite_config_dict.keys():
|
||||
# Calculate the location of the microsite's files
|
||||
microsite_root = microsites_root / microsite_name
|
||||
microsite_config = microsite_config_dict[microsite_name]
|
||||
|
||||
# pull in configuration information from each
|
||||
# microsite root
|
||||
|
||||
if os.path.isdir(microsite_root):
|
||||
# store the path on disk for later use
|
||||
microsite_config['microsite_root'] = microsite_root
|
||||
|
||||
# get the domain that this should reside
|
||||
domain = microsite_config['domain_prefix']
|
||||
|
||||
# get the virtual university that this should use
|
||||
university = microsite_config['university']
|
||||
|
||||
# add to the existing maps in our settings
|
||||
subdomain_branding[domain] = university
|
||||
virtual_universities.append(university)
|
||||
|
||||
template_dir = microsite_root / 'templates'
|
||||
microsite_config['template_dir'] = template_dir
|
||||
|
||||
microsite_config['microsite_name'] = microsite_name
|
||||
|
||||
else:
|
||||
# not sure if we have application logging at this stage of
|
||||
# startup
|
||||
print '**** Error loading microsite {0}. Directory does not exist'.format(microsite_root)
|
||||
# remove from our configuration as it is not valid
|
||||
del microsite_config_dict[microsite_name]
|
||||
|
||||
# if we have microsites, then let's turn on SUBDOMAIN_BRANDING
|
||||
# Note check size of the dict because some microsites might not be found on disk and
|
||||
# we could be left with none
|
||||
if microsite_config_dict:
|
||||
FEATURES['SUBDOMAIN_BRANDING'] = True
|
||||
|
||||
TEMPLATE_DIRS.append(microsites_root)
|
||||
MAKO_TEMPLATES['main'].append(microsites_root)
|
||||
|
||||
STATICFILES_DIRS.append(microsites_root)
|
||||
|
||||
|
||||
################# Student Verification #################
|
||||
VERIFY_STUDENT = {
|
||||
"DAYS_GOOD_FOR": 365, # How many days is a verficiation good for?
|
||||
|
||||
@@ -299,16 +299,14 @@ MICROSITE_CONFIGURATION = {
|
||||
"course_index_overlay_text": "This is a Test Microsite Overlay Text.",
|
||||
"course_index_overlay_logo_file": "test_microsite/images/header-logo.png",
|
||||
"homepage_overlay_html": "<h1>This is a Test Microsite Overlay HTML</h1>"
|
||||
},
|
||||
"default": {
|
||||
"university": "default_university",
|
||||
"domain_prefix": "www",
|
||||
}
|
||||
}
|
||||
|
||||
if len(MICROSITE_CONFIGURATION.keys()) > 0:
|
||||
enable_microsites(
|
||||
MICROSITE_CONFIGURATION,
|
||||
SUBDOMAIN_BRANDING,
|
||||
VIRTUAL_UNIVERSITIES,
|
||||
microsites_root=COMMON_ROOT / "test" / 'test_microsites'
|
||||
)
|
||||
MICROSITE_ROOT_DIR = COMMON_ROOT / 'test' / 'test_microsites'
|
||||
FEATURES['USE_MICROSITES'] = True
|
||||
|
||||
######### LinkedIn ########
|
||||
LINKEDIN_API['COMPANY_ID'] = '0000000'
|
||||
|
||||
@@ -9,6 +9,9 @@ settings.INSTALLED_APPS # pylint: disable=W0104
|
||||
|
||||
from django_startup import autostartup
|
||||
import edxmako
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def run():
|
||||
@@ -20,6 +23,9 @@ def run():
|
||||
if settings.FEATURES.get('USE_CUSTOM_THEME', False):
|
||||
enable_theme()
|
||||
|
||||
if settings.FEATURES.get('USE_MICROSITES', False):
|
||||
enable_microsites()
|
||||
|
||||
|
||||
def enable_theme():
|
||||
"""
|
||||
@@ -51,3 +57,45 @@ def enable_theme():
|
||||
settings.STATICFILES_DIRS.append(
|
||||
(u'themes/{}'.format(settings.THEME_NAME), theme_root / 'static')
|
||||
)
|
||||
|
||||
|
||||
def enable_microsites():
|
||||
"""
|
||||
Enable the use of microsites, which are websites that allow
|
||||
for subdomains for the edX platform, e.g. foo.edx.org
|
||||
"""
|
||||
|
||||
microsites_root = settings.MICROSITE_ROOT_DIR
|
||||
microsite_config_dict = settings.MICROSITE_CONFIGURATION
|
||||
|
||||
for ms_name, ms_config in microsite_config_dict.items():
|
||||
# Calculate the location of the microsite's files
|
||||
ms_root = microsites_root / ms_name
|
||||
ms_config = microsite_config_dict[ms_name]
|
||||
|
||||
# pull in configuration information from each
|
||||
# microsite root
|
||||
|
||||
if ms_root.isdir():
|
||||
# store the path on disk for later use
|
||||
ms_config['microsite_root'] = ms_root
|
||||
|
||||
template_dir = ms_root / 'templates'
|
||||
ms_config['template_dir'] = template_dir
|
||||
|
||||
ms_config['microsite_name'] = ms_name
|
||||
log.info('Loading microsite {0}'.format(ms_root))
|
||||
else:
|
||||
# not sure if we have application logging at this stage of
|
||||
# startup
|
||||
log.error('Error loading microsite {0}. Directory does not exist'.format(ms_root))
|
||||
# remove from our configuration as it is not valid
|
||||
del microsite_config_dict[ms_name]
|
||||
|
||||
# if we have any valid microsites defined, let's wire in the Mako and STATIC_FILES search paths
|
||||
if microsite_config_dict:
|
||||
settings.TEMPLATE_DIRS.append(microsites_root)
|
||||
settings.MAKO_TEMPLATES['main'].append(microsites_root)
|
||||
edxmako.startup.run()
|
||||
|
||||
settings.STATICFILES_DIRS.insert(0, microsites_root)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
cart_link = ""
|
||||
%>
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
|
||||
<%inherit file="../main.html" />
|
||||
|
||||
@@ -20,13 +20,15 @@
|
||||
|
||||
<%
|
||||
if self.theme_enabled():
|
||||
google_analytics_file = u'../' + MicrositeConfiguration.get_microsite_configuration_value('google_analytics_file', 'theme-google-analytics.html')
|
||||
google_analytics_file = u'../{ga}'.format(
|
||||
ga=microsite.get_value('google_analytics_file', 'theme-google-analytics.html')
|
||||
)
|
||||
else:
|
||||
google_analytics_file = '../google_analytics.html'
|
||||
%>
|
||||
|
||||
<%include file="${google_analytics_file}" />
|
||||
|
||||
|
||||
## OG (Open Graph) title and description added below to give social media info to display
|
||||
## (https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content#tags)
|
||||
<meta property="og:title" content="${get_course_about_section(course, 'title')}" />
|
||||
@@ -141,7 +143,7 @@
|
||||
%endif
|
||||
|
||||
<span class="register disabled">${_("You are registered for this course")}</span>
|
||||
|
||||
|
||||
%if show_courseware_link:
|
||||
<strong>${_("View Courseware")}</strong>
|
||||
</a>
|
||||
@@ -169,7 +171,7 @@
|
||||
% elif is_course_full:
|
||||
<span class="register disabled">
|
||||
${_("Course is full")}
|
||||
</span>
|
||||
</span>
|
||||
%else:
|
||||
<a href="#" class="register">
|
||||
${_("Register for {course.display_number_with_default}").format(course=course) | h}
|
||||
@@ -216,7 +218,7 @@
|
||||
<section class="course-sidebar">
|
||||
<section class="course-summary">
|
||||
<header>
|
||||
% if MicrositeConfiguration.get_microsite_configuration_value('course_about_show_social_links', True):
|
||||
% if microsite.get_value('course_about_show_social_links', True):
|
||||
<div class="social-sharing">
|
||||
<div class="sharing-message">${_("Share with friends and family!")}</div>
|
||||
## TODO: this should probably be an overrideable block,
|
||||
@@ -230,15 +232,34 @@
|
||||
<img src="${static.url('images/social/email-sharing.png')}" alt="Email someone to say you've registered for this course">
|
||||
</a>
|
||||
% else:
|
||||
<%
|
||||
site_domain = MicrositeConfiguration.get_microsite_configuration_value('site_domain', 'www.edx.org')
|
||||
platform_name = MicrositeConfiguration.get_microsite_configuration_value('platform_name', 'edX')
|
||||
|
||||
tweet_action = "http://twitter.com/intent/tweet?text=I+just+registered+for+"+course.number+"+"+get_course_about_section(course, 'title')+"+through+"+MicrositeConfiguration.get_microsite_configuration_value('course_about_twitter_account', '@edxonline')+":+http://"+site_domain+reverse('about_course', args=[course.id])
|
||||
<%
|
||||
site_domain = microsite.get_value('site_domain', 'www.edx.org')
|
||||
platform_name = microsite.get_value('platform_name', 'edX')
|
||||
|
||||
facebook_link = MicrositeConfiguration.get_microsite_configuration_value('course_about_facebook_link', 'http://www.facebook.com/EdxOnline')
|
||||
tweet_action = "http://twitter.com/intent/tweet?text=I+just+registered+for+{number}+{title}+through+{account}:+{url}".format(
|
||||
number=course.number,
|
||||
title=get_course_about_section(course, 'title'),
|
||||
account=microsite.get_value('course_about_twitter_account', '@edxonline'),
|
||||
url="http://{domain}{path}".format(
|
||||
domain=site_domain,
|
||||
path=reverse('about_course', args=[course.id])
|
||||
)
|
||||
)
|
||||
|
||||
email_subject = "mailto:?subject=Take%20a%20course%20with%20"+platform_name+"%20online&body=I%20just%20registered%20for%20"+course.number+"%20"+get_course_about_section(course, 'title')+"%20through%20"+platform_name+"%20http://"+site_domain+reverse('about_course', args=[course.id])
|
||||
facebook_link = microsite.get_value('course_about_facebook_link', 'http://www.facebook.com/EdxOnline')
|
||||
|
||||
email_subject = "mailto:?subject={subject}&body={body}".format(
|
||||
subject="Take a course with {platform} online".format(platform=platform_name),
|
||||
body="I just registered for {number} {title} through {platform} {url}".format(
|
||||
number=course.number,
|
||||
title=get_course_about_section(course, 'title'),
|
||||
platform=platform_name,
|
||||
url="http://{domain}{path}".format(
|
||||
domain=site_domain,
|
||||
path=reverse('about_course', args=[course.id]),
|
||||
)
|
||||
)
|
||||
).replace(" ", "%20")
|
||||
%>
|
||||
<a href="${tweet_action}" class="share">
|
||||
<img src="${static.url('images/social/twitter-sharing.png')}" alt="Tweet that you've registered for this course">
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
|
||||
<%block name="pagetitle">${_("Courses")}</%block>
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
|
||||
<section class="find-courses">
|
||||
|
||||
<%
|
||||
course_index_overlay_text = MicrositeConfiguration.get_microsite_configuration_value('course_index_overlay_text', _("Explore free courses from leading universities."))
|
||||
course_index_overlay_text = microsite.get_value('course_index_overlay_text', _("Explore free courses from leading universities."))
|
||||
|
||||
# not sure why this is, but if I use static.url('images/edx_bw.png') then the HTML rendering
|
||||
# of this template goes wonky
|
||||
|
||||
logo_file = MicrositeConfiguration.get_microsite_configuration_value(
|
||||
logo_file = microsite.get_value(
|
||||
'course_index_overlay_logo_file', settings.STATIC_URL + 'images/edx_bw.png')
|
||||
%>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
% if self.stanford_theme_enabled():
|
||||
<img src="${static.url('themes/stanford/images/seal.png')}" alt="Stanford Seal Logo" />
|
||||
% else:
|
||||
<img src='${logo_file}' alt="${MicrositeConfiguration.get_microsite_configuration_value('platform_name', settings.PLATFORM_NAME)} Logo" />
|
||||
<img src='${logo_file}' alt="${microsite.get_value('platform_name', settings.PLATFORM_NAME)} Logo" />
|
||||
% endif
|
||||
</div>
|
||||
% if self.stanford_theme_enabled():
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
|
||||
<%! from django.core.urlresolvers import reverse %>
|
||||
<section id="forgot-password-modal" class="modal" role="dialog" aria-label="${_('Password Reset')}">
|
||||
@@ -28,7 +28,7 @@
|
||||
<li class="field required text" id="forgot-password-modal-field-email">
|
||||
<label for="pwd_reset_email">${_("Your E-mail Address")}</label>
|
||||
<input class="" id="pwd_reset_email" type="email" name="email" value="" placeholder="example: username@domain.com" aria-describedby="pwd_reset_email-tip" aria-required="true" />
|
||||
<span class="tip tip-input" id="pwd_reset_email-tip">${_("This is the e-mail address you used to register with {platform}").format(platform=MicrositeConfiguration.get_microsite_configuration_value('platform_name', settings.PLATFORM_NAME))}</span>
|
||||
<span class="tip tip-input" id="pwd_reset_email-tip">${_("This is the e-mail address you used to register with {platform}").format(platform=microsite.get_value('platform_name', settings.PLATFORM_NAME))}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
<%! import pytz %>
|
||||
<%! from django.conf import settings %>
|
||||
<%! from courseware.tabs import get_discussion_link %>
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! platform_name = MicrositeConfiguration.get_microsite_configuration_value("platform_name", settings.PLATFORM_NAME) %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
<%! platform_name = microsite.get_value("platform_name", settings.PLATFORM_NAME) %>
|
||||
|
||||
% if settings.FEATURES.get('ENABLE_FEEDBACK_SUBMISSION', False):
|
||||
|
||||
@@ -53,7 +53,6 @@ discussion_link = get_discussion_link(course) if course else None
|
||||
<p>${_('Have a <strong>question about something specific</strong>? You can contact the {platform_name} general support team directly:').format(
|
||||
platform_name=platform_name
|
||||
)}</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="help-buttons">
|
||||
|
||||
@@ -4,15 +4,15 @@
|
||||
<%inherit file="main.html" />
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
|
||||
<%
|
||||
homepage_overlay_html = MicrositeConfiguration.get_microsite_configuration_value('homepage_overlay_html')
|
||||
homepage_overlay_html = microsite.get_value('homepage_overlay_html')
|
||||
|
||||
show_homepage_promo_video = MicrositeConfiguration.get_microsite_configuration_value('show_homepage_promo_video', True)
|
||||
homepage_promo_video_youtube_id = MicrositeConfiguration.get_microsite_configuration_value('homepage_promo_video_youtube_id', "XNaiOGxWeto")
|
||||
show_homepage_promo_video = microsite.get_value('show_homepage_promo_video', True)
|
||||
homepage_promo_video_youtube_id = microsite.get_value('homepage_promo_video_youtube_id', "XNaiOGxWeto")
|
||||
|
||||
show_partners = MicrositeConfiguration.get_microsite_configuration_value('show_partners', True)
|
||||
show_partners = microsite.get_value('show_partners', True)
|
||||
|
||||
%>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%inherit file="main.html" />
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%! from django.core.urlresolvers import reverse %>
|
||||
@@ -169,7 +169,7 @@
|
||||
|
||||
<%
|
||||
# allow for microsite overrides on the registration sidebars, otherwise default to pre-existing ones
|
||||
sidebar_file = MicrositeConfiguration.get_microsite_template_path('login-sidebar.html')
|
||||
sidebar_file = microsite.get_template_path('login-sidebar.html')
|
||||
%>
|
||||
|
||||
<%include file="${sidebar_file}" />
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
<%! from microsite_configuration import page_title_breadcrumbs %>
|
||||
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
@@ -29,7 +29,7 @@
|
||||
return getattr(settings, "THEME_NAME", None) == "stanford"
|
||||
%>
|
||||
</%def>
|
||||
|
||||
|
||||
## this needs to be here to prevent the title from mysteriously appearing in the body, in one case
|
||||
<%def name="pagetitle()" />
|
||||
<%block name="title">
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
<script type="text/javascript" src="/jsi18n/"></script>
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="${static.url(MicrositeConfiguration.get_microsite_configuration_value('favicon_path', settings.FAVICON_PATH))}" />
|
||||
<link rel="icon" type="image/x-icon" href="${static.url(microsite.get_value('favicon_path', settings.FAVICON_PATH))}" />
|
||||
|
||||
<%static:css group='style-vendor'/>
|
||||
<%static:css group='style-app'/>
|
||||
@@ -71,11 +71,11 @@
|
||||
|
||||
else:
|
||||
header_extra_file = None
|
||||
header_file = MicrositeConfiguration.get_microsite_template_path('navigation.html')
|
||||
google_analytics_file = MicrositeConfiguration.get_microsite_template_path('google_analytics.html')
|
||||
footer_file = MicrositeConfiguration.get_microsite_template_path('footer.html')
|
||||
header_file = microsite.get_template_path('navigation.html')
|
||||
google_analytics_file = microsite.get_template_path('google_analytics.html')
|
||||
footer_file = microsite.get_template_path('footer.html')
|
||||
|
||||
style_overrides_file = MicrositeConfiguration.get_microsite_configuration_value('css_overrides_file')
|
||||
style_overrides_file = microsite.get_value('css_overrides_file')
|
||||
%>
|
||||
|
||||
% if header_extra_file:
|
||||
|
||||
@@ -11,7 +11,7 @@ import branding
|
||||
from status.status import get_site_status_msg
|
||||
%>
|
||||
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
<%! from microsite_configuration.templatetags.microsite import platform_name %>
|
||||
|
||||
## Provide a hook for themes to inject branding on top.
|
||||
@@ -49,7 +49,7 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
<%block name="navigation_logo">
|
||||
<img src="${static.url(branding.get_logo_url())}" alt="
|
||||
% if course:
|
||||
${course.display_org_with_default | h}: ${course.display_number_with_default | h} ${course.display_name_with_default | h} @
|
||||
${course.display_org_with_default | h}: ${course.display_number_with_default | h} ${course.display_name_with_default | h} @
|
||||
% endif
|
||||
${platform_name()}
|
||||
" />
|
||||
@@ -101,7 +101,7 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
% else:
|
||||
<ol class="left nav-global">
|
||||
<%block name="navigation_global_links">
|
||||
% if MicrositeConfiguration.get_microsite_configuration_value('ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False)):
|
||||
% if microsite.get_value('ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False)):
|
||||
<li class="nav-global-01">
|
||||
<a href="${marketing_link('HOW_IT_WORKS')}">${_("How it Works")}</a>
|
||||
</li>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<%! from microsite_configuration.middleware import MicrositeConfiguration %>
|
||||
<%! from microsite_configuration import microsite %>
|
||||
|
||||
<%inherit file="main.html" />
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
|
||||
<%
|
||||
# allow for microsite overrides on the registration sidebars, otherwise default to pre-existing ones
|
||||
sidebar_file = MicrositeConfiguration.get_microsite_template_path('register-sidebar.html')
|
||||
sidebar_file = microsite.get_template_path('register-sidebar.html')
|
||||
%>
|
||||
|
||||
<%include file="${sidebar_file}" />
|
||||
|
||||
Reference in New Issue
Block a user