Commit c4401fdc by chrisndodge

Merge pull request #2553 from edx/cdodge/microsite-cleanup

Address Microsite PR feedback - separate out middleware from microsite logic, shor...
parents 52b8d0c0 aa43689a
...@@ -55,7 +55,7 @@ from contentstore import utils ...@@ -55,7 +55,7 @@ from contentstore import utils
from student.roles import CourseInstructorRole, CourseStaffRole, CourseCreatorRole, GlobalStaff from student.roles import CourseInstructorRole, CourseStaffRole, CourseCreatorRole, GlobalStaff
from student import auth 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', __all__ = ['course_info_handler', 'course_handler', 'course_info_update_handler',
'settings_handler', 'settings_handler',
...@@ -535,7 +535,7 @@ def settings_handler(request, tag=None, package_id=None, branch=None, version_gu ...@@ -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 # 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 # 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, course_module.location.org,
'ENABLE_MKTG_SITE', 'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False) settings.FEATURES.get('ENABLE_MKTG_SITE', False)
......
...@@ -10,7 +10,7 @@ from django.conf import settings ...@@ -10,7 +10,7 @@ from django.conf import settings
from edxmako.shortcuts import render_to_response from edxmako.shortcuts import render_to_response
from external_auth.views import ssl_login_shortcut, ssl_get_cert_from_request 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'] __all__ = ['signup', 'login_page', 'howitworks']
...@@ -49,7 +49,7 @@ def login_page(request): ...@@ -49,7 +49,7 @@ def login_page(request):
{ {
'csrf': csrf_token, 'csrf': csrf_token,
'forgot_password_link': "//{base}/login#forgot-password-modal".format(base=settings.LMS_BASE), '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', []) ...@@ -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_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) 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_CONFIGURATION = ENV_TOKENS.get('MICROSITE_CONFIGURATION', {})
MICROSITE_ROOT_DIR = ENV_TOKENS.get('MICROSITE_ROOT_DIR') MICROSITE_ROOT_DIR = path(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)
)
#### PASSWORD POLICY SETTINGS ##### #### PASSWORD POLICY SETTINGS #####
PASSWORD_MIN_LENGTH = ENV_TOKENS.get("PASSWORD_MIN_LENGTH") PASSWORD_MIN_LENGTH = ENV_TOKENS.get("PASSWORD_MIN_LENGTH")
......
...@@ -27,7 +27,7 @@ Longer TODO: ...@@ -27,7 +27,7 @@ Longer TODO:
import sys import sys
import lms.envs.common import lms.envs.common
from lms.envs.common import ( 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 from path import path
...@@ -84,6 +84,9 @@ FEATURES = { ...@@ -84,6 +84,9 @@ FEATURES = {
# Toggles embargo functionality # Toggles embargo functionality
'EMBARGO': False, 'EMBARGO': False,
# Turn on/off Microsites feature
'USE_MICROSITES': False,
} }
ENABLE_JASMINE = False ENABLE_JASMINE = False
......
...@@ -6,10 +6,7 @@ This is a localdev test for the Microsite processing pipeline ...@@ -6,10 +6,7 @@ This is a localdev test for the Microsite processing pipeline
# pylint: disable=W0401, W0614 # pylint: disable=W0401, W0614
from .dev import * from .dev import *
from .dev import SUBDOMAIN_BRANDING, VIRTUAL_UNIVERSITIES
MICROSITE_NAMES = ['openedx'] MICROSITE_NAMES = ['openedx']
MICROSITE_CONFIGURATION = {} MICROSITE_CONFIGURATION = {}
FEATURES['USE_MICROSITES'] = True
if MICROSITE_NAMES and len(MICROSITE_NAMES) > 0:
enable_microsites(MICROSITE_NAMES, MICROSITE_CONFIGURATION, SUBDOMAIN_BRANDING, VIRTUAL_UNIVERSITIES)
...@@ -199,3 +199,31 @@ FEATURES['DISABLE_RESET_EMAIL_TEST'] = True ...@@ -199,3 +199,31 @@ FEATURES['DISABLE_RESET_EMAIL_TEST'] = True
# Toggles embargo on for testing # Toggles embargo on for testing
FEATURES['EMBARGO'] = True 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 ...@@ -16,7 +16,7 @@ from django.template import Context
from django.http import HttpResponse from django.http import HttpResponse
import logging import logging
from microsite_configuration.middleware import MicrositeConfiguration from microsite_configuration import microsite
from edxmako import lookup_template from edxmako import lookup_template
import edxmako.middleware import edxmako.middleware
...@@ -37,7 +37,7 @@ def marketing_link(name): ...@@ -37,7 +37,7 @@ def marketing_link(name):
# link_map maps URLs from the marketing site to the old equivalent on # link_map maps URLs from the marketing site to the old equivalent on
# the Django site # the Django site
link_map = settings.MKTG_URL_LINK_MAP link_map = settings.MKTG_URL_LINK_MAP
enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value( enable_mktg_site = microsite.get_value(
'ENABLE_MKTG_SITE', 'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False) settings.FEATURES.get('ENABLE_MKTG_SITE', False)
) )
...@@ -80,7 +80,7 @@ def marketing_link_context_processor(request): ...@@ -80,7 +80,7 @@ def marketing_link_context_processor(request):
def render_to_string(template_name, dictionary, context=None, namespace='main'): def render_to_string(template_name, dictionary, context=None, namespace='main'):
# see if there is an override template defined in the microsite # 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) context_instance = Context(dictionary)
# add dictionary to context_instance # add dictionary to context_instance
...@@ -111,7 +111,7 @@ def render_to_response(template_name, dictionary=None, context_instance=None, na ...@@ -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 # 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 {} dictionary = dictionary or {}
return HttpResponse(render_to_string(template_name, dictionary, context_instance, namespace), **kwargs) return HttpResponse(render_to_string(template_name, dictionary, context_instance, namespace), **kwargs)
...@@ -8,6 +8,9 @@ from . import add_lookup ...@@ -8,6 +8,9 @@ from . import add_lookup
def run(): def run():
""" """
Setup mako lookup directories. 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 template_locations = settings.MAKO_TEMPLATES
for namespace, directories in template_locations.items(): for namespace, directories in template_locations.items():
......
"""
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)
""" """
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: A microsite enables the following features:
1) Mapping of sub-domain name to a 'brand', e.g. foo-university.edx.org 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' 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 3) Ability to swap out some branding elements in the website
""" """
import threading from microsite_configuration import microsite
import os.path
from django.conf import settings
_microsite_configuration_threadlocal = threading.local() class MicrositeMiddleware(object):
_microsite_configuration_threadlocal.data = {}
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):
""" """
Middleware class which will bind configuration information regarding 'microsites' on a per request basis. Middleware class which will bind configuration information regarding 'microsites' on a per request basis.
The actual configuration information is taken from Django settings information 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): def process_request(self, request):
""" """
Middleware entry point on every request processing. This will associate a request's domain name Middleware entry point on every request processing. This will associate a request's domain name
with a 'University' and any corresponding microsite configuration information with a 'University' and any corresponding microsite configuration information
""" """
self.clear_microsite_configuration() microsite.clear()
domain = request.META.get('HTTP_HOST', None) domain = request.META.get('HTTP_HOST', None)
if domain: microsite.set_by_domain(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
# also put the configuration on the request itself to make it easier to dereference
request.microsite_configuration = _microsite_configuration_threadlocal.data
return None return None
def process_response(self, request, response): def process_response(self, request, response):
""" """
Middleware entry point for request completion. Middleware entry point for request completion.
""" """
self.clear_microsite_configuration() microsite.clear()
return response 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. ...@@ -4,7 +4,7 @@ based on the current micro site.
""" """
from django import template from django import template
from django.conf import settings from django.conf import settings
from microsite_configuration.middleware import MicrositeConfiguration from microsite_configuration import microsite
register = template.Library() register = template.Library()
...@@ -37,4 +37,4 @@ def platform_name(): ...@@ -37,4 +37,4 @@ def platform_name():
Django template tag that outputs the current platform name: Django template tag that outputs the current platform name:
{% platform_name %} {% platform_name %}
""" """
return MicrositeConfiguration.get_microsite_configuration_value('platform_name', settings.PLATFORM_NAME) return microsite.get_value('platform_name', settings.PLATFORM_NAME)
"""
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. ...@@ -4,10 +4,13 @@ Tests microsite_configuration templatetags and helper functions.
""" """
from django.test import TestCase from django.test import TestCase
from django.conf import settings from django.conf import settings
from .templatetags import microsite from microsite_configuration.templatetags import microsite
class MicroSiteTests(TestCase): class MicroSiteTests(TestCase):
"""
Make sure some of the helper functions work
"""
def test_breadcrumbs(self): def test_breadcrumbs(self):
crumbs = ['my', 'less specific', 'Page'] crumbs = ['my', 'less specific', 'Page']
expected = u'my | less specific | Page | edX' expected = u'my | less specific | Page | edX'
...@@ -23,10 +26,9 @@ class MicroSiteTests(TestCase): ...@@ -23,10 +26,9 @@ class MicroSiteTests(TestCase):
def test_platform_name(self): def test_platform_name(self):
pname = microsite.platform_name() pname = microsite.platform_name()
self.assertEqual(pname, settings.PLATFORM_NAME) self.assertEqual(pname, settings.PLATFORM_NAME)
def test_breadcrumb_tag(self): def test_breadcrumb_tag(self):
crumbs = ['my', 'less specific', 'Page'] crumbs = ['my', 'less specific', 'Page']
expected = u'my | less specific | Page | edX' expected = u'my | less specific | Page | edX'
title = microsite.page_title_breadcrumbs_tag(None, *crumbs) title = microsite.page_title_breadcrumbs_tag(None, *crumbs)
self.assertEqual(expected, title) self.assertEqual(expected, title)
\ No newline at end of file
...@@ -74,7 +74,7 @@ from dogapi import dog_stats_api ...@@ -74,7 +74,7 @@ from dogapi import dog_stats_api
from util.json_request import JsonResponse from util.json_request import JsonResponse
from util.bad_request_rate_limiter import BadRequestRateLimiter 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 ( from util.password_policy_validators import (
validate_password_length, validate_password_complexity, validate_password_length, validate_password_complexity,
...@@ -350,7 +350,7 @@ def signin_user(request): ...@@ -350,7 +350,7 @@ def signin_user(request):
context = { context = {
'course_id': request.GET.get('course_id'), 'course_id': request.GET.get('course_id'),
'enrollment_action': request.GET.get('enrollment_action'), 'enrollment_action': request.GET.get('enrollment_action'),
'platform_name': MicrositeConfiguration.get_microsite_configuration_value( 'platform_name': microsite.get_value(
'platform_name', 'platform_name',
settings.PLATFORM_NAME settings.PLATFORM_NAME
), ),
...@@ -373,7 +373,7 @@ def register_user(request, extra_context=None): ...@@ -373,7 +373,7 @@ def register_user(request, extra_context=None):
context = { context = {
'course_id': request.GET.get('course_id'), 'course_id': request.GET.get('course_id'),
'enrollment_action': request.GET.get('enrollment_action'), 'enrollment_action': request.GET.get('enrollment_action'),
'platform_name': MicrositeConfiguration.get_microsite_configuration_value( 'platform_name': microsite.get_value(
'platform_name', 'platform_name',
settings.PLATFORM_NAME settings.PLATFORM_NAME
), ),
...@@ -416,11 +416,11 @@ def dashboard(request): ...@@ -416,11 +416,11 @@ def dashboard(request):
# for microsites, we want to filter and only show enrollments for courses within # for microsites, we want to filter and only show enrollments for courses within
# the microsites 'ORG' # 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 # Let's filter out any courses in an "org" that has been declared to be
# in a Microsite # 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 # remove our current Microsite from the "filter out" list, if applicable
if course_org_filter: if course_org_filter:
...@@ -1160,7 +1160,7 @@ def create_account(request, post_override=None): ...@@ -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 # 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')): if not (settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING')):
from_address = MicrositeConfiguration.get_microsite_configuration_value( from_address = microsite.get_value(
'email_from_address', 'email_from_address',
settings.DEFAULT_FROM_EMAIL settings.DEFAULT_FROM_EMAIL
) )
...@@ -1502,7 +1502,7 @@ def change_email_request(request): ...@@ -1502,7 +1502,7 @@ def change_email_request(request):
message = render_to_string('emails/email_change.txt', context) message = render_to_string('emails/email_change.txt', context)
from_address = MicrositeConfiguration.get_microsite_configuration_value( from_address = microsite.get_value(
'email_from_address', 'email_from_address',
settings.DEFAULT_FROM_EMAIL settings.DEFAULT_FROM_EMAIL
) )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import re import re
from django.conf import settings 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>[^/]+/[^/]+/[^/]+)') COURSE_REGEX = re.compile(r'^.*?/courses/(?P<course_id>[^/]+/[^/]+/[^/]+)')
...@@ -19,7 +19,7 @@ def safe_get_host(request): ...@@ -19,7 +19,7 @@ def safe_get_host(request):
if isinstance(settings.ALLOWED_HOSTS, (list, tuple)) and '*' not in settings.ALLOWED_HOSTS: if isinstance(settings.ALLOWED_HOSTS, (list, tuple)) and '*' not in settings.ALLOWED_HOSTS:
return request.get_host() return request.get_host()
else: 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): def course_id_from_url(url):
......
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.
## mako ## mako
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
<%! from django.utils.translation import ugettext as _ %> <%! 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'/> <%namespace name='static' file='static_content.html'/>
......
...@@ -2,7 +2,7 @@ from xmodule.modulestore.django import modulestore ...@@ -2,7 +2,7 @@ from xmodule.modulestore.django import modulestore
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
from django.conf import settings from django.conf import settings
from microsite_configuration.middleware import MicrositeConfiguration from microsite_configuration import microsite
def get_visible_courses(): def get_visible_courses():
...@@ -15,7 +15,7 @@ def get_visible_courses(): ...@@ -15,7 +15,7 @@ def get_visible_courses():
if isinstance(c, CourseDescriptor)] if isinstance(c, CourseDescriptor)]
courses = sorted(courses, key=lambda course: course.number) 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 # See if we have filtered course listings in this domain
filtered_visible_ids = None filtered_visible_ids = None
...@@ -24,7 +24,7 @@ def get_visible_courses(): ...@@ -24,7 +24,7 @@ def get_visible_courses():
if hasattr(settings, 'COURSE_LISTINGS') and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG: if hasattr(settings, 'COURSE_LISTINGS') and subdomain in settings.COURSE_LISTINGS and not settings.DEBUG:
filtered_visible_ids = frozenset(settings.COURSE_LISTINGS[subdomain]) 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: if filtered_by_org:
return [course for course in courses if course.location.org == filtered_by_org] return [course for course in courses if course.location.org == filtered_by_org]
...@@ -33,7 +33,7 @@ def get_visible_courses(): ...@@ -33,7 +33,7 @@ def get_visible_courses():
else: else:
# Let's filter out any courses in an "org" that has been declared to be # Let's filter out any courses in an "org" that has been declared to be
# in a Microsite # 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] 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(): ...@@ -42,7 +42,7 @@ def get_university_for_request():
Return the university name specified for the domain, or None Return the university name specified for the domain, or None
if no university was specified if no university was specified
""" """
return MicrositeConfiguration.get_microsite_configuration_value('university') return microsite.get_value('university')
def get_logo_url(): def get_logo_url():
...@@ -52,7 +52,7 @@ def get_logo_url(): ...@@ -52,7 +52,7 @@ def get_logo_url():
# if the MicrositeConfiguration has a value for the logo_image_url # if the MicrositeConfiguration has a value for the logo_image_url
# let's use that # 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: if image_url:
return '{static_url}{image_url}'.format( return '{static_url}{image_url}'.format(
static_url=settings.STATIC_URL, static_url=settings.STATIC_URL,
...@@ -60,7 +60,7 @@ def get_logo_url(): ...@@ -60,7 +60,7 @@ def get_logo_url():
) )
# otherwise, use the legacy means to configure this # otherwise, use the legacy means to configure this
university = MicrositeConfiguration.get_microsite_configuration_value('university') university = microsite.get_value('university')
if university is None: if university is None:
return '{static_url}images/header-logo.png'.format( return '{static_url}images/header-logo.png'.format(
......
...@@ -8,7 +8,7 @@ from edxmako.shortcuts import render_to_response ...@@ -8,7 +8,7 @@ from edxmako.shortcuts import render_to_response
import student.views import student.views
import courseware.views import courseware.views
from microsite_configuration.middleware import MicrositeConfiguration from microsite_configuration import microsite
from edxmako.shortcuts import marketing_link from edxmako.shortcuts import marketing_link
from util.cache import cache_if_anonymous from util.cache import cache_if_anonymous
...@@ -27,7 +27,7 @@ def index(request): ...@@ -27,7 +27,7 @@ def index(request):
from external_auth.views import ssl_login from external_auth.views import ssl_login
return ssl_login(request) return ssl_login(request)
enable_mktg_site = MicrositeConfiguration.get_microsite_configuration_value( enable_mktg_site = microsite.get_value(
'ENABLE_MKTG_SITE', 'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False) settings.FEATURES.get('ENABLE_MKTG_SITE', False)
) )
...@@ -35,11 +35,11 @@ def index(request): ...@@ -35,11 +35,11 @@ def index(request):
if enable_mktg_site: if enable_mktg_site:
return redirect(settings.MKTG_URLS.get('ROOT')) 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 # keep specialized logic for Edge until we can migrate over Edge to fully use
# microsite definitions # microsite definitions
if university == 'edge': if domain and 'edge.edx.org' in domain:
context = { context = {
'suppress_toplevel_navigation': True 'suppress_toplevel_navigation': True
} }
...@@ -59,7 +59,7 @@ def courses(request): ...@@ -59,7 +59,7 @@ def courses(request):
to that. Otherwise, if subdomain branding is on, this is the university to that. Otherwise, if subdomain branding is on, this is the university
profile page. Otherwise, it's the edX courseware.views.courses page 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', 'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False) settings.FEATURES.get('ENABLE_MKTG_SITE', False)
) )
......
...@@ -70,7 +70,7 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -70,7 +70,7 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.assertContains(resp, 'This is a Test Microsite Overlay') # Overlay test message 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/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 self.assertContains(resp, 'Test Microsite') # page title
# assert that test course display name is visible # assert that test course display name is visible
...@@ -101,7 +101,7 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -101,7 +101,7 @@ class TestMicrosites(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.assertNotContains(resp, 'This is a Test Microsite Overlay') # Overlay test message 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/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 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 # 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 ...@@ -38,7 +38,7 @@ from xmodule.modulestore.search import path_to_location
from xmodule.course_module import CourseDescriptor from xmodule.course_module import CourseDescriptor
import shoppingcart import shoppingcart
from microsite_configuration.middleware import MicrositeConfiguration from microsite_configuration import microsite
log = logging.getLogger("edx.courseware") log = logging.getLogger("edx.courseware")
...@@ -528,7 +528,7 @@ def registered_for_course(course, user): ...@@ -528,7 +528,7 @@ def registered_for_course(course, user):
@cache_if_anonymous @cache_if_anonymous
def course_about(request, course_id): def course_about(request, course_id):
if MicrositeConfiguration.get_microsite_configuration_value( if microsite.get_value(
'ENABLE_MKTG_SITE', 'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False) settings.FEATURES.get('ENABLE_MKTG_SITE', False)
): ):
......
...@@ -14,7 +14,7 @@ from student.models import CourseEnrollment, CourseEnrollmentAllowed ...@@ -14,7 +14,7 @@ from student.models import CourseEnrollment, CourseEnrollmentAllowed
from courseware.models import StudentModule from courseware.models import StudentModule
from edxmako.shortcuts import render_to_string from edxmako.shortcuts import render_to_string
from microsite_configuration.middleware import MicrositeConfiguration from microsite_configuration import microsite
# For determining if a shibboleth course # For determining if a shibboleth course
SHIBBOLETH_DOMAIN_PREFIX = 'shib:' SHIBBOLETH_DOMAIN_PREFIX = 'shib:'
...@@ -229,7 +229,7 @@ def send_mail_to_student(student, param_dict): ...@@ -229,7 +229,7 @@ def send_mail_to_student(student, param_dict):
if 'course' in param_dict: if 'course' in param_dict:
param_dict['course_name'] = param_dict['course'].display_name_with_default 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', 'SITE_NAME',
param_dict['site_name'] param_dict['site_name']
) )
...@@ -271,7 +271,7 @@ def send_mail_to_student(student, param_dict): ...@@ -271,7 +271,7 @@ def send_mail_to_student(student, param_dict):
# Email subject *must not* contain newlines # Email subject *must not* contain newlines
subject = ''.join(subject.splitlines()) subject = ''.join(subject.splitlines())
from_address = MicrositeConfiguration.get_microsite_configuration_value( from_address = microsite.get_value(
'email_from_address', 'email_from_address',
settings.DEFAULT_FROM_EMAIL settings.DEFAULT_FROM_EMAIL
) )
......
...@@ -62,7 +62,7 @@ from xblock.field_data import DictFieldData ...@@ -62,7 +62,7 @@ from xblock.field_data import DictFieldData
from xblock.fields import ScopeIds from xblock.fields import ScopeIds
from django.utils.translation import ugettext as _u from django.utils.translation import ugettext as _u
from microsite_configuration.middleware import MicrositeConfiguration from microsite_configuration import microsite
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -1295,7 +1295,7 @@ def _do_enroll_students(course, course_id, students, overload=False, auto_enroll ...@@ -1295,7 +1295,7 @@ def _do_enroll_students(course, course_id, students, overload=False, auto_enroll
ceaset.delete() ceaset.delete()
if email_students: if email_students:
stripped_site_name = MicrositeConfiguration.get_microsite_configuration_value( stripped_site_name = microsite.get_value(
'SITE_NAME', 'SITE_NAME',
settings.SITE_NAME settings.SITE_NAME
) )
...@@ -1389,7 +1389,7 @@ def _do_unenroll_students(course_id, students, email_students=False): ...@@ -1389,7 +1389,7 @@ def _do_unenroll_students(course_id, students, email_students=False):
old_students, _ = get_and_clean_student_list(students) old_students, _ = get_and_clean_student_list(students)
status = dict([x, 'unprocessed'] for x in old_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', 'SITE_NAME',
settings.SITE_NAME settings.SITE_NAME
) )
...@@ -1469,7 +1469,7 @@ def send_mail_to_student(student, param_dict): ...@@ -1469,7 +1469,7 @@ def send_mail_to_student(student, param_dict):
# add some helpers and microconfig subsitutions # add some helpers and microconfig subsitutions
if 'course' in param_dict: if 'course' in param_dict:
param_dict['course_name'] = param_dict['course'].display_name_with_default 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', 'SITE_NAME',
param_dict.get('site_name', '') param_dict.get('site_name', '')
) )
...@@ -1497,7 +1497,7 @@ def send_mail_to_student(student, param_dict): ...@@ -1497,7 +1497,7 @@ def send_mail_to_student(student, param_dict):
# Email subject *must not* contain newlines # Email subject *must not* contain newlines
subject = ''.join(subject.splitlines()) subject = ''.join(subject.splitlines())
from_address = MicrositeConfiguration.get_microsite_configuration_value( from_address = microsite.get_value(
'email_from_address', 'email_from_address',
settings.DEFAULT_FROM_EMAIL settings.DEFAULT_FROM_EMAIL
) )
......
...@@ -35,7 +35,7 @@ from verify_student.models import SoftwareSecurePhotoVerification ...@@ -35,7 +35,7 @@ from verify_student.models import SoftwareSecurePhotoVerification
from .exceptions import (InvalidCartItem, PurchasedCallbackException, ItemAlreadyInCartException, from .exceptions import (InvalidCartItem, PurchasedCallbackException, ItemAlreadyInCartException,
AlreadyEnrolledInCourseException, CourseDoesNotExistException) AlreadyEnrolledInCourseException, CourseDoesNotExistException)
from microsite_configuration.middleware import MicrositeConfiguration from microsite_configuration import microsite
log = logging.getLogger("shoppingcart") log = logging.getLogger("shoppingcart")
...@@ -175,7 +175,7 @@ class Order(models.Model): ...@@ -175,7 +175,7 @@ class Order(models.Model):
} }
) )
try: try:
from_address = MicrositeConfiguration.get_microsite_configuration_value( from_address = microsite.get_value(
'email_from_address', 'email_from_address',
settings.DEFAULT_FROM_EMAIL settings.DEFAULT_FROM_EMAIL
) )
...@@ -477,7 +477,7 @@ class CertificateItem(OrderItem): ...@@ -477,7 +477,7 @@ class CertificateItem(OrderItem):
user_email=course_enrollment.user.email, user_email=course_enrollment.user.email,
order_number=order_number) order_number=order_number)
to_email = [settings.PAYMENT_SUPPORT_EMAIL] to_email = [settings.PAYMENT_SUPPORT_EMAIL]
from_email = [MicrositeConfiguration.get_microsite_configuration_value( from_email = [microsite.get_value(
'payment_support_email', 'payment_support_email',
settings.PAYMENT_SUPPORT_EMAIL settings.PAYMENT_SUPPORT_EMAIL
)] )]
......
...@@ -356,14 +356,7 @@ MAX_FAILED_LOGIN_ATTEMPTS_ALLOWED = ENV_TOKENS.get("MAX_FAILED_LOGIN_ATTEMPTS_AL ...@@ -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) 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_CONFIGURATION = ENV_TOKENS.get('MICROSITE_CONFIGURATION', {})
MICROSITE_ROOT_DIR = ENV_TOKENS.get('MICROSITE_ROOT_DIR') MICROSITE_ROOT_DIR = path(ENV_TOKENS.get('MICROSITE_ROOT_DIR', ''))
if MICROSITE_CONFIGURATION:
enable_microsites(
MICROSITE_CONFIGURATION,
SUBDOMAIN_BRANDING,
VIRTUAL_UNIVERSITIES,
microsites_root=path(MICROSITE_ROOT_DIR)
)
#### PASSWORD POLICY SETTINGS ##### #### PASSWORD POLICY SETTINGS #####
PASSWORD_MIN_LENGTH = ENV_TOKENS.get("PASSWORD_MIN_LENGTH") PASSWORD_MIN_LENGTH = ENV_TOKENS.get("PASSWORD_MIN_LENGTH")
......
...@@ -6,7 +6,7 @@ This is a localdev test for the Microsite processing pipeline ...@@ -6,7 +6,7 @@ This is a localdev test for the Microsite processing pipeline
# pylint: disable=W0401, W0614 # pylint: disable=W0401, W0614
from .dev import * from .dev import *
from .dev import SUBDOMAIN_BRANDING, VIRTUAL_UNIVERSITIES from ..dev import ENV_ROOT, FEATURES
MICROSITE_CONFIGURATION = { MICROSITE_CONFIGURATION = {
...@@ -30,13 +30,9 @@ MICROSITE_CONFIGURATION = { ...@@ -30,13 +30,9 @@ MICROSITE_CONFIGURATION = {
} }
} }
if len(MICROSITE_CONFIGURATION.keys()) > 0: MICROSITE_ROOT_DIR = ENV_ROOT / 'edx-microsite'
enable_microsites(
MICROSITE_CONFIGURATION,
SUBDOMAIN_BRANDING,
VIRTUAL_UNIVERSITIES
)
# pretend we are behind some marketing site, we want to be able to assert that the Microsite config values override # pretend we are behind some marketing site, we want to be able to assert that the Microsite config values override
# this global setting # this global setting
FEATURES['ENABLE_MKTG_SITE'] = True FEATURES['ENABLE_MKTG_SITE'] = True
FEATURES['USE_MICROSITES'] = True
...@@ -229,6 +229,9 @@ FEATURES = { ...@@ -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 # 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 # defaults, so that we maintain current behavior
'ALLOW_WIKI_ROOT_ACCESS': True, 'ALLOW_WIKI_ROOT_ACCESS': True,
# Turn on/off Microsites feature
'USE_MICROSITES': False,
} }
# Used for A/B testing # Used for A/B testing
...@@ -693,7 +696,7 @@ TEMPLATE_LOADERS = ( ...@@ -693,7 +696,7 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'request_cache.middleware.RequestCache', 'request_cache.middleware.RequestCache',
'microsite_configuration.middleware.MicrositeConfiguration', 'microsite_configuration.middleware.MicrositeMiddleware',
'django_comment_client.middleware.AjaxExceptionMiddleware', 'django_comment_client.middleware.AjaxExceptionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
...@@ -1183,64 +1186,6 @@ MKTG_URL_LINK_MAP = { ...@@ -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 ################# ################# Student Verification #################
VERIFY_STUDENT = { VERIFY_STUDENT = {
"DAYS_GOOD_FOR": 365, # How many days is a verficiation good for? "DAYS_GOOD_FOR": 365, # How many days is a verficiation good for?
......
...@@ -299,16 +299,14 @@ MICROSITE_CONFIGURATION = { ...@@ -299,16 +299,14 @@ MICROSITE_CONFIGURATION = {
"course_index_overlay_text": "This is a Test Microsite Overlay Text.", "course_index_overlay_text": "This is a Test Microsite Overlay Text.",
"course_index_overlay_logo_file": "test_microsite/images/header-logo.png", "course_index_overlay_logo_file": "test_microsite/images/header-logo.png",
"homepage_overlay_html": "<h1>This is a Test Microsite Overlay HTML</h1>" "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'
if len(MICROSITE_CONFIGURATION.keys()) > 0: FEATURES['USE_MICROSITES'] = True
enable_microsites(
MICROSITE_CONFIGURATION,
SUBDOMAIN_BRANDING,
VIRTUAL_UNIVERSITIES,
microsites_root=COMMON_ROOT / "test" / 'test_microsites'
)
######### LinkedIn ######## ######### LinkedIn ########
LINKEDIN_API['COMPANY_ID'] = '0000000' LINKEDIN_API['COMPANY_ID'] = '0000000'
...@@ -9,6 +9,9 @@ settings.INSTALLED_APPS # pylint: disable=W0104 ...@@ -9,6 +9,9 @@ settings.INSTALLED_APPS # pylint: disable=W0104
from django_startup import autostartup from django_startup import autostartup
import edxmako import edxmako
import logging
log = logging.getLogger(__name__)
def run(): def run():
...@@ -20,6 +23,9 @@ def run(): ...@@ -20,6 +23,9 @@ def run():
if settings.FEATURES.get('USE_CUSTOM_THEME', False): if settings.FEATURES.get('USE_CUSTOM_THEME', False):
enable_theme() enable_theme()
if settings.FEATURES.get('USE_MICROSITES', False):
enable_microsites()
def enable_theme(): def enable_theme():
""" """
...@@ -51,3 +57,45 @@ def enable_theme(): ...@@ -51,3 +57,45 @@ def enable_theme():
settings.STATICFILES_DIRS.append( settings.STATICFILES_DIRS.append(
(u'themes/{}'.format(settings.THEME_NAME), theme_root / 'static') (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 @@ ...@@ -12,7 +12,7 @@
cart_link = "" cart_link = ""
%> %>
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%! from microsite_configuration.middleware import MicrositeConfiguration %> <%! from microsite_configuration import microsite %>
<%inherit file="../main.html" /> <%inherit file="../main.html" />
...@@ -20,13 +20,15 @@ ...@@ -20,13 +20,15 @@
<% <%
if self.theme_enabled(): 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: else:
google_analytics_file = '../google_analytics.html' google_analytics_file = '../google_analytics.html'
%> %>
<%include file="${google_analytics_file}" /> <%include file="${google_analytics_file}" />
## OG (Open Graph) title and description added below to give social media info to display ## 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) ## (https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content#tags)
<meta property="og:title" content="${get_course_about_section(course, 'title')}" /> <meta property="og:title" content="${get_course_about_section(course, 'title')}" />
...@@ -141,7 +143,7 @@ ...@@ -141,7 +143,7 @@
%endif %endif
<span class="register disabled">${_("You are registered for this course")}</span> <span class="register disabled">${_("You are registered for this course")}</span>
%if show_courseware_link: %if show_courseware_link:
<strong>${_("View Courseware")}</strong> <strong>${_("View Courseware")}</strong>
</a> </a>
...@@ -169,7 +171,7 @@ ...@@ -169,7 +171,7 @@
% elif is_course_full: % elif is_course_full:
<span class="register disabled"> <span class="register disabled">
${_("Course is full")} ${_("Course is full")}
</span> </span>
%else: %else:
<a href="#" class="register"> <a href="#" class="register">
${_("Register for {course.display_number_with_default}").format(course=course) | h} ${_("Register for {course.display_number_with_default}").format(course=course) | h}
...@@ -216,7 +218,7 @@ ...@@ -216,7 +218,7 @@
<section class="course-sidebar"> <section class="course-sidebar">
<section class="course-summary"> <section class="course-summary">
<header> <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="social-sharing">
<div class="sharing-message">${_("Share with friends and family!")}</div> <div class="sharing-message">${_("Share with friends and family!")}</div>
## TODO: this should probably be an overrideable block, ## TODO: this should probably be an overrideable block,
...@@ -230,15 +232,34 @@ ...@@ -230,15 +232,34 @@
<img src="${static.url('images/social/email-sharing.png')}" alt="Email someone to say you've registered for this course"> <img src="${static.url('images/social/email-sharing.png')}" alt="Email someone to say you've registered for this course">
</a> </a>
% else: % else:
<% <%
site_domain = MicrositeConfiguration.get_microsite_configuration_value('site_domain', 'www.edx.org') site_domain = microsite.get_value('site_domain', 'www.edx.org')
platform_name = MicrositeConfiguration.get_microsite_configuration_value('platform_name', 'edX') platform_name = microsite.get_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]) tweet_action = "http://twitter.com/intent/tweet?text=I+just+registered+for+{number}+{title}+through+{account}:+{url}".format(
number=course.number,
facebook_link = MicrositeConfiguration.get_microsite_configuration_value('course_about_facebook_link', 'http://www.facebook.com/EdxOnline') title=get_course_about_section(course, 'title'),
account=microsite.get_value('course_about_twitter_account', '@edxonline'),
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]) url="http://{domain}{path}".format(
domain=site_domain,
path=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"> <a href="${tweet_action}" class="share">
<img src="${static.url('images/social/twitter-sharing.png')}" alt="Tweet that you've registered for this course"> <img src="${static.url('images/social/twitter-sharing.png')}" alt="Tweet that you've registered for this course">
......
...@@ -4,17 +4,17 @@ ...@@ -4,17 +4,17 @@
<%namespace name='static' file='../static_content.html'/> <%namespace name='static' file='../static_content.html'/>
<%block name="pagetitle">${_("Courses")}</%block> <%block name="pagetitle">${_("Courses")}</%block>
<%! from microsite_configuration.middleware import MicrositeConfiguration %> <%! from microsite_configuration import microsite %>
<section class="find-courses"> <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 # not sure why this is, but if I use static.url('images/edx_bw.png') then the HTML rendering
# of this template goes wonky # 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') 'course_index_overlay_logo_file', settings.STATIC_URL + 'images/edx_bw.png')
%> %>
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
% if self.stanford_theme_enabled(): % if self.stanford_theme_enabled():
<img src="${static.url('themes/stanford/images/seal.png')}" alt="Stanford Seal Logo" /> <img src="${static.url('themes/stanford/images/seal.png')}" alt="Stanford Seal Logo" />
% else: % 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 % endif
</div> </div>
% if self.stanford_theme_enabled(): % if self.stanford_theme_enabled():
......
<%! from django.utils.translation import ugettext as _ %> <%! from django.utils.translation import ugettext as _ %>
<%! from microsite_configuration.middleware import MicrositeConfiguration %> <%! from microsite_configuration import microsite %>
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
<section id="forgot-password-modal" class="modal" role="dialog" aria-label="${_('Password Reset')}"> <section id="forgot-password-modal" class="modal" role="dialog" aria-label="${_('Password Reset')}">
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
<li class="field required text" id="forgot-password-modal-field-email"> <li class="field required text" id="forgot-password-modal-field-email">
<label for="pwd_reset_email">${_("Your E-mail Address")}</label> <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" /> <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> </li>
</ol> </ol>
</fieldset> </fieldset>
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<%! import pytz %> <%! import pytz %>
<%! from django.conf import settings %> <%! from django.conf import settings %>
<%! from courseware.tabs import get_discussion_link %> <%! from courseware.tabs import get_discussion_link %>
<%! from microsite_configuration.middleware import MicrositeConfiguration %> <%! from microsite_configuration import microsite %>
<%! platform_name = MicrositeConfiguration.get_microsite_configuration_value("platform_name", settings.PLATFORM_NAME) %> <%! platform_name = microsite.get_value("platform_name", settings.PLATFORM_NAME) %>
% if settings.FEATURES.get('ENABLE_FEEDBACK_SUBMISSION', False): % if settings.FEATURES.get('ENABLE_FEEDBACK_SUBMISSION', False):
...@@ -53,7 +53,6 @@ discussion_link = get_discussion_link(course) if course else None ...@@ -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( <p>${_('Have a <strong>question about something specific</strong>? You can contact the {platform_name} general support team directly:').format(
platform_name=platform_name platform_name=platform_name
)}</p> )}</p>
<hr> <hr>
<div class="help-buttons"> <div class="help-buttons">
......
...@@ -4,15 +4,15 @@ ...@@ -4,15 +4,15 @@
<%inherit file="main.html" /> <%inherit file="main.html" />
<%namespace name='static' file='static_content.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) show_homepage_promo_video = microsite.get_value('show_homepage_promo_video', True)
homepage_promo_video_youtube_id = MicrositeConfiguration.get_microsite_configuration_value('homepage_promo_video_youtube_id', "XNaiOGxWeto") 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)
%> %>
......
<%inherit file="main.html" /> <%inherit file="main.html" />
<%! from microsite_configuration.middleware import MicrositeConfiguration %> <%! from microsite_configuration import microsite %>
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<%! from django.core.urlresolvers import reverse %> <%! from django.core.urlresolvers import reverse %>
...@@ -169,7 +169,7 @@ ...@@ -169,7 +169,7 @@
<% <%
# allow for microsite overrides on the registration sidebars, otherwise default to pre-existing ones # 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}" /> <%include file="${sidebar_file}" />
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<%! from django.utils.translation import ugettext as _ %> <%! 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 %> <%! from microsite_configuration import page_title_breadcrumbs %>
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
return getattr(settings, "THEME_NAME", None) == "stanford" return getattr(settings, "THEME_NAME", None) == "stanford"
%> %>
</%def> </%def>
## this needs to be here to prevent the title from mysteriously appearing in the body, in one case ## this needs to be here to prevent the title from mysteriously appearing in the body, in one case
<%def name="pagetitle()" /> <%def name="pagetitle()" />
<%block name="title"> <%block name="title">
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
<script type="text/javascript" src="/jsi18n/"></script> <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-vendor'/>
<%static:css group='style-app'/> <%static:css group='style-app'/>
...@@ -71,11 +71,11 @@ ...@@ -71,11 +71,11 @@
else: else:
header_extra_file = None header_extra_file = None
header_file = MicrositeConfiguration.get_microsite_template_path('navigation.html') header_file = microsite.get_template_path('navigation.html')
google_analytics_file = MicrositeConfiguration.get_microsite_template_path('google_analytics.html') google_analytics_file = microsite.get_template_path('google_analytics.html')
footer_file = MicrositeConfiguration.get_microsite_template_path('footer.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: % if header_extra_file:
......
...@@ -11,7 +11,7 @@ import branding ...@@ -11,7 +11,7 @@ import branding
from status.status import get_site_status_msg 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 %> <%! from microsite_configuration.templatetags.microsite import platform_name %>
## Provide a hook for themes to inject branding on top. ## Provide a hook for themes to inject branding on top.
...@@ -49,7 +49,7 @@ site_status_msg = get_site_status_msg(course_id) ...@@ -49,7 +49,7 @@ site_status_msg = get_site_status_msg(course_id)
<%block name="navigation_logo"> <%block name="navigation_logo">
<img src="${static.url(branding.get_logo_url())}" alt=" <img src="${static.url(branding.get_logo_url())}" alt="
% if course: % 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 % endif
${platform_name()} ${platform_name()}
" /> " />
...@@ -101,7 +101,7 @@ site_status_msg = get_site_status_msg(course_id) ...@@ -101,7 +101,7 @@ site_status_msg = get_site_status_msg(course_id)
% else: % else:
<ol class="left nav-global"> <ol class="left nav-global">
<%block name="navigation_global_links"> <%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"> <li class="nav-global-01">
<a href="${marketing_link('HOW_IT_WORKS')}">${_("How it Works")}</a> <a href="${marketing_link('HOW_IT_WORKS')}">${_("How it Works")}</a>
</li> </li>
......
<%! from django.utils.translation import ugettext as _ %> <%! from django.utils.translation import ugettext as _ %>
<%! from microsite_configuration.middleware import MicrositeConfiguration %> <%! from microsite_configuration import microsite %>
<%inherit file="main.html" /> <%inherit file="main.html" />
...@@ -314,7 +314,7 @@ ...@@ -314,7 +314,7 @@
<% <%
# allow for microsite overrides on the registration sidebars, otherwise default to pre-existing ones # 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}" /> <%include file="${sidebar_file}" />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment