Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
f974347d
Commit
f974347d
authored
Aug 31, 2016
by
Saleem Latif
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update theming to have priority over microsites.
parent
33ae93ec
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
248 additions
and
12 deletions
+248
-12
openedx/core/djangoapps/theming/helpers.py
+28
-4
openedx/core/djangoapps/theming/middleware.py
+3
-2
openedx/core/djangoapps/theming/models.py
+18
-5
openedx/core/djangoapps/theming/tests/test_helpers.py
+148
-1
openedx/core/djangoapps/theming/tests/test_microsites.py
+51
-0
No files found.
openedx/core/djangoapps/theming/helpers.py
View file @
f974347d
...
...
@@ -11,7 +11,7 @@ from django.contrib.staticfiles.storage import staticfiles_storage
from
request_cache.middleware
import
RequestCache
from
microsite_configuration
import
microsite
from
openedx.core.djangoapps.site_configuration
import
helpers
as
configuration_helpers
from
logging
import
getLogger
logger
=
getLogger
(
__name__
)
# pylint: disable=invalid-name
...
...
@@ -21,7 +21,10 @@ def get_template_path(relative_path, **kwargs):
"""
This is a proxy function to hide microsite_configuration behind comprehensive theming.
"""
if
microsite
.
is_request_in_microsite
():
# We need to give priority to theming over microsites
# So, we apply microsite override only if there is no associated site theme
# and associated microsite is present.
if
not
current_request_has_associated_site_theme
()
and
microsite
.
is_request_in_microsite
():
relative_path
=
microsite
.
get_template_path
(
relative_path
,
**
kwargs
)
return
relative_path
...
...
@@ -30,7 +33,8 @@ def is_request_in_themed_site():
"""
This is a proxy function to hide microsite_configuration behind comprehensive theming.
"""
return
microsite
.
is_request_in_microsite
()
# We need to give priority to theming/site-configuration over microsites
return
configuration_helpers
.
is_site_configuration_enabled
()
or
microsite
.
is_request_in_microsite
()
def
get_template
(
uri
):
...
...
@@ -38,7 +42,10 @@ def get_template(uri):
This is a proxy function to hide microsite_configuration behind comprehensive theming.
:param uri: uri of the template
"""
return
microsite
.
get_template
(
uri
)
# We need to give priority to theming over microsites
# So, we apply microsite template override only when there is no associated theme,
if
not
current_request_has_associated_site_theme
():
return
microsite
.
get_template
(
uri
)
def
get_template_path_with_theme
(
relative_path
):
...
...
@@ -190,6 +197,18 @@ def get_current_theme():
return
None
def
current_request_has_associated_site_theme
():
"""
True if current request has an associated SiteTheme, False otherwise.
Returns:
True if current request has an associated SiteTheme, False otherwise
"""
request
=
get_current_request
()
site_theme
=
getattr
(
request
,
'site_theme'
,
None
)
return
bool
(
site_theme
and
site_theme
.
id
)
def
get_theme_base_dir
(
theme_dir_name
,
suppress_error
=
False
):
"""
Returns absolute path to the directory that contains the given theme.
...
...
@@ -298,7 +317,12 @@ def is_comprehensive_theming_enabled():
Returns:
(bool): True if comprehensive theming is enabled else False
"""
# We need to give priority to theming over microsites
if
settings
.
ENABLE_COMPREHENSIVE_THEMING
and
current_request_has_associated_site_theme
():
return
True
# Disable theming for microsites
# Microsite configurations take priority over the default site theme.
if
microsite
.
is_request_in_microsite
():
return
False
...
...
openedx/core/djangoapps/theming/middleware.py
View file @
f974347d
...
...
@@ -5,7 +5,7 @@ Note:
This middleware depends on "django_sites_extensions" app
So it must be added to INSTALLED_APPS in django settings files.
"""
from
django.conf
import
settings
from
openedx.core.djangoapps.theming.models
import
SiteTheme
...
...
@@ -18,4 +18,5 @@ class CurrentSiteThemeMiddleware(object):
"""
fetch Site Theme for the current site and add it to the request object.
"""
request
.
site_theme
=
SiteTheme
.
get_theme
(
request
.
site
)
default_theme
=
SiteTheme
(
site
=
request
.
site
,
theme_dir_name
=
settings
.
DEFAULT_SITE_THEME
)
request
.
site_theme
=
SiteTheme
.
get_theme
(
request
.
site
,
default
=
default_theme
)
openedx/core/djangoapps/theming/models.py
View file @
f974347d
...
...
@@ -20,20 +20,33 @@ class SiteTheme(models.Model):
return
self
.
theme_dir_name
@staticmethod
def
get_theme
(
site
):
def
get_theme
(
site
,
default
=
None
):
"""
Get SiteTheme object for given site, returns default site theme if it can not
find a theme for the given site and `DEFAULT_SITE_THEME` setting has a proper value.
Args:
site (django.contrib.sites.models.Site): site object related to the current site.
default (openedx.core.djangoapps.models.SiteTheme): site theme object to return in case there is no theme
associated for the given site.
Returns:
SiteTheme object for given site or a default site
set by `DEFAULT_SITE_THEME`
SiteTheme object for given site or a default site
passed in as the argument.
"""
theme
=
site
.
themes
.
first
()
return
theme
or
default
if
(
not
theme
)
and
settings
.
DEFAULT_SITE_THEME
:
theme
=
SiteTheme
(
site
=
site
,
theme_dir_name
=
settings
.
DEFAULT_SITE_THEME
)
return
theme
@staticmethod
def
has_theme
(
site
):
"""
Returns True if given site has an associated site theme in database, returns False otherwise.
Note: DEFAULT_SITE_THEME is not considered as an associated site.
Args:
site (django.contrib.sites.models.Site): site object related to the current site.
Returns:
True if given site has an associated site theme in database, returns False otherwise.
"""
return
site
.
themes
.
exists
()
openedx/core/djangoapps/theming/tests/test_helpers.py
View file @
f974347d
...
...
@@ -2,13 +2,14 @@
Test helpers for Comprehensive Theming.
"""
import
unittest
from
mock
import
patch
from
mock
import
patch
,
Mock
from
django.test
import
TestCase
,
override_settings
from
django.conf
import
settings
from
openedx.core.djangoapps.theming.tests.test_util
import
with_comprehensive_theme
from
openedx.core.djangoapps.site_configuration
import
helpers
as
configuration_helpers
from
openedx.core.djangoapps.theming
import
helpers
as
theming_helpers
from
openedx.core.djangoapps.theming.helpers
import
get_template_path_with_theme
,
strip_site_theme_templates_path
,
\
get_themes
,
Theme
,
get_theme_base_dir
...
...
@@ -54,6 +55,152 @@ class TestHelpers(TestCase):
jwt_auth
=
configuration_helpers
.
get_value
(
'JWT_AUTH'
)
self
.
assertEqual
(
jwt_auth
[
override_key
],
override_value
)
def
test_is_comprehensive_theming_enabled
(
self
):
"""
Tests to make sure the is_comprehensive_theming_enabled function works as expected.
Here are different scenarios that we need to test
1. Theming is enabled, there is a SiteTheme record and microsite configuration for the current site.
is_comprehensive_theming_enabled should return True
2. Theming is enabled, there is no SiteTheme record but there is microsite configuration for the current site.
is_comprehensive_theming_enabled should return False
3. Theming is enabled, there is neither a SiteTheme record nor microsite configuration for the current site.
is_comprehensive_theming_enabled should return True
4. Theming is disabled, there is a SiteTheme record and microsite configuration for the current site.
is_comprehensive_theming_enabled should return False
5. Theming is disabled, there is no SiteTheme record but there is microsite configuration for the current site.
is_comprehensive_theming_enabled should return False
6. Theming is disabled, there is neither a SiteTheme record nor microsite configuration for the current site.
is_comprehensive_theming_enabled should return False
"""
# Theming is enabled, there is a SiteTheme record and microsite configuration for the current site
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
True
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
True
),
):
self
.
assertTrue
(
theming_helpers
.
is_comprehensive_theming_enabled
())
# Theming is enabled, there is no SiteTheme record but there is microsite configuration for the current site.
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
False
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
True
),
):
self
.
assertFalse
(
theming_helpers
.
is_comprehensive_theming_enabled
())
# Theming is enabled, there is neither a SiteTheme record nor microsite configuration for the current site.
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
False
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
False
),
):
self
.
assertTrue
(
theming_helpers
.
is_comprehensive_theming_enabled
())
with
override_settings
(
ENABLE_COMPREHENSIVE_THEMING
=
False
):
# Theming is disabled, there is a SiteTheme record and microsite configuration for the current site.
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
True
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
True
),
):
self
.
assertFalse
(
theming_helpers
.
is_comprehensive_theming_enabled
())
# Theming is disabled, there is no SiteTheme record but
# there is microsite configuration for the current site.
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
False
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
True
),
):
self
.
assertFalse
(
theming_helpers
.
is_comprehensive_theming_enabled
())
# Theming is disabled, there is neither a SiteTheme record nor microsite configuration for the current site.
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
False
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
False
),
):
self
.
assertFalse
(
theming_helpers
.
is_comprehensive_theming_enabled
())
def
test_get_template
(
self
):
"""
Tests to make sure the get_template function works as expected.
"""
# if the current site has associated SiteTheme then get_template should return None
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
True
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
True
),
):
with
patch
(
"microsite_configuration.microsite.TEMPLATES_BACKEND"
)
as
mock_microsite_backend
:
mock_microsite_backend
.
get_template
=
Mock
(
return_value
=
"/microsite/about.html"
)
self
.
assertIsNone
(
theming_helpers
.
get_template
(
"about.html"
))
# if the current site does not have associated SiteTheme then get_template should return microsite override
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
False
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
True
),
):
with
patch
(
"microsite_configuration.microsite.TEMPLATES_BACKEND"
)
as
mock_microsite_backend
:
mock_microsite_backend
.
get_template
=
Mock
(
return_value
=
"/microsite/about.html"
)
self
.
assertEqual
(
theming_helpers
.
get_template
(
"about.html"
),
"/microsite/about.html"
)
def
test_get_template_path
(
self
):
"""
Tests to make sure the get_template_path function works as expected.
"""
# if the current site has associated SiteTheme then get_template_path should return the argument as is.
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
True
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
True
),
):
with
patch
(
"microsite_configuration.microsite.TEMPLATES_BACKEND"
)
as
mock_microsite_backend
:
mock_microsite_backend
.
get_template
=
Mock
(
return_value
=
"/microsite/about.html"
)
self
.
assertEqual
(
theming_helpers
.
get_template_path
(
"about.html"
),
"about.html"
)
# if the current site does not have associated SiteTheme then get_template_path should return microsite override
with
patch
(
"openedx.core.djangoapps.theming.helpers.current_request_has_associated_site_theme"
,
Mock
(
return_value
=
False
),
):
with
patch
(
"openedx.core.djangoapps.theming.helpers.microsite.is_request_in_microsite"
,
Mock
(
return_value
=
True
),
):
with
patch
(
"microsite_configuration.microsite.TEMPLATES_BACKEND"
)
as
mock_microsite_backend
:
mock_microsite_backend
.
get_template_path
=
Mock
(
return_value
=
"/microsite/about.html"
)
self
.
assertEqual
(
theming_helpers
.
get_template_path
(
"about.html"
),
"/microsite/about.html"
)
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
class
TestHelpersLMS
(
TestCase
):
...
...
openedx/core/djangoapps/theming/tests/test_microsites.py
0 → 100644
View file @
f974347d
"""
Tests for microsites and comprehensive themes.
"""
import
unittest
from
django.conf
import
settings
from
django.test
import
TestCase
from
django.contrib.sites.models
import
Site
from
openedx.core.djangoapps.theming.models
import
SiteTheme
@unittest.skipUnless
(
settings
.
ROOT_URLCONF
==
'lms.urls'
,
'Test only valid in lms'
)
class
TestComprehensiveThemeLMS
(
TestCase
):
"""
Test html, sass and static file overrides for comprehensive themes.
"""
def
__add_site_theme__
(
self
,
domain
,
theme
):
"""
Add a Site and SiteTheme record for the given domain and theme
Args:
domain: domain to which attach the new Site
theme: theme to apply on the new site
"""
site
,
__
=
Site
.
objects
.
get_or_create
(
domain
=
domain
,
name
=
domain
)
SiteTheme
.
objects
.
get_or_create
(
site
=
site
,
theme_dir_name
=
theme
)
def
test_theme_footer
(
self
):
"""
Test that theme footer is used instead of microsite footer.
"""
# Add SiteTheme with the same domain name as microsite
self
.
__add_site_theme__
(
domain
=
settings
.
MICROSITE_TEST_HOSTNAME
,
theme
=
"test-theme"
)
# Test that requesting on a host, where both theme and microsite is applied
# theme gets priority over microsite.
resp
=
self
.
client
.
get
(
'/'
,
HTTP_HOST
=
settings
.
MICROSITE_TEST_HOSTNAME
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
# This string comes from footer.html of test-theme
self
.
assertContains
(
resp
,
"This is a footer for test-theme."
)
def
test_microsite_footer
(
self
):
"""
Test that microsite footer is used instead of default theme footer.
"""
# Test that if theming is enabled but there is no SiteTheme for the current site, then
# DEFAULT_SITE_THEME does not interfere with microsites
resp
=
self
.
client
.
get
(
'/'
,
HTTP_HOST
=
settings
.
MICROSITE_TEST_HOSTNAME
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
# This string comes from footer.html of test_site, which is a microsite
self
.
assertContains
(
resp
,
"This is a Test Site footer"
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment