Make /static/ urls work in the courseware
This commit is contained in:
@@ -1,19 +1,25 @@
|
||||
from staticfiles.storage import staticfiles_storage
|
||||
import re
|
||||
|
||||
PREFIX = '/static/'
|
||||
STATIC_PATTERN = re.compile(r"""
|
||||
(?P<quote>['"]) # the opening quotes
|
||||
{prefix} # the prefix
|
||||
(?P<rest>.*?) # everything else in the url
|
||||
(?P=quote) # the first matching closing quote
|
||||
""".format(prefix=PREFIX), re.VERBOSE)
|
||||
PREFIX_LEN = len(PREFIX)
|
||||
|
||||
def replace(static_url):
|
||||
def replace(static_url, prefix=None):
|
||||
if prefix is None:
|
||||
prefix = ''
|
||||
else:
|
||||
prefix = prefix + '/'
|
||||
|
||||
quote = static_url.group('quote')
|
||||
url = staticfiles_storage.url(static_url.group('rest'))
|
||||
url = staticfiles_storage.url(prefix + static_url.group('rest'))
|
||||
return "".join([quote, url, quote])
|
||||
|
||||
def replace_urls(text):
|
||||
return STATIC_PATTERN.sub(replace, text)
|
||||
|
||||
def replace_urls(text, staticfiles_prefix=None, replace_prefix='/static/'):
|
||||
def replace_url(static_url):
|
||||
return replace(static_url, staticfiles_prefix)
|
||||
|
||||
return re.sub(r"""
|
||||
(?P<quote>\\?['"]) # the opening quotes
|
||||
{prefix} # the prefix
|
||||
(?P<rest>.*?) # everything else in the url
|
||||
(?P=quote) # the first matching closing quote
|
||||
""".format(prefix=replace_prefix), replace_url, text, flags=re.VERBOSE)
|
||||
|
||||
@@ -15,6 +15,7 @@ from xmodule.raw_module import RawDescriptor
|
||||
from progress import Progress
|
||||
from capa.capa_problem import LoncapaProblem
|
||||
from capa.responsetypes import StudentInputError
|
||||
from static_replace import replace_urls
|
||||
|
||||
log = logging.getLogger("mitx.courseware")
|
||||
|
||||
@@ -258,7 +259,7 @@ class CapaModule(XModule):
|
||||
html = '<div id="problem_{id}" class="problem" data-url="{ajax_url}">'.format(
|
||||
id=self.location.html_id(), ajax_url=self.system.ajax_url) + html + "</div>"
|
||||
|
||||
return html
|
||||
return replace_urls(html, self.metadata['data_dir'])
|
||||
|
||||
def handle_ajax(self, dispatch, get):
|
||||
'''
|
||||
|
||||
@@ -115,7 +115,9 @@ class XMLModuleStore(ModuleStore):
|
||||
MakoDescriptorSystem.__init__(self, **system_kwargs)
|
||||
XMLParsingSystem.__init__(self, **system_kwargs)
|
||||
|
||||
return ImportSystem(self).process_xml(etree.tostring(course_data))
|
||||
course_descriptor = ImportSystem(self).process_xml(etree.tostring(course_data))
|
||||
course_descriptor.metadata['data_dir'] = course_dir
|
||||
return course_descriptor
|
||||
|
||||
def get_item(self, location):
|
||||
"""
|
||||
|
||||
@@ -211,7 +211,13 @@ class XModuleDescriptor(Plugin):
|
||||
js_module = None
|
||||
|
||||
# A list of metadata that this module can inherit from its parent module
|
||||
inheritable_metadata = ('graded', 'due', 'graceperiod', 'showanswer', 'rerandomize')
|
||||
inheritable_metadata = (
|
||||
'graded', 'due', 'graceperiod', 'showanswer', 'rerandomize',
|
||||
|
||||
# This is used by the XMLModuleStore to provide for locations for static files,
|
||||
# and will need to be removed when that code is removed
|
||||
'data_dir'
|
||||
)
|
||||
|
||||
# A list of descriptor attributes that must be equal for the discriptors to be
|
||||
# equal
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import Http404
|
||||
from django.http import HttpResponse
|
||||
from lxml import etree
|
||||
from functools import wraps
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from mitxmako.shortcuts import render_to_string
|
||||
from models import StudentModule, StudentModuleCache
|
||||
from static_replace import replace_urls
|
||||
|
||||
log = logging.getLogger("mitx.courseware")
|
||||
|
||||
@@ -222,6 +222,12 @@ def get_module(user, request, location, student_module_cache, position=None):
|
||||
|
||||
module = descriptor.xmodule_constructor(system)(instance_state, shared_state)
|
||||
|
||||
# TODO (cpennington): When modules are shared between courses, the static
|
||||
# prefix is going to have to be specific to the module, not the directory
|
||||
# that the xml was loaded from
|
||||
prefix = module.metadata['data_dir']
|
||||
module = replace_static_urls(module, prefix)
|
||||
|
||||
if settings.MITX_FEATURES.get('DISPLAY_HISTOGRAMS_TO_STAFF') and user.is_staff:
|
||||
module = add_histogram(module)
|
||||
|
||||
@@ -251,9 +257,32 @@ def get_module(user, request, location, student_module_cache, position=None):
|
||||
return (module, instance_module, shared_module, descriptor.category)
|
||||
|
||||
|
||||
def replace_static_urls(module, prefix):
|
||||
"""
|
||||
Updates the supplied module with a new get_html function that wraps
|
||||
the old get_html function and substitutes urls of the form /static/...
|
||||
with urls that are /static/<prefix>/...
|
||||
"""
|
||||
original_get_html = module.get_html
|
||||
|
||||
@wraps(original_get_html)
|
||||
def get_html():
|
||||
return replace_urls(original_get_html(), staticfiles_prefix=prefix)
|
||||
|
||||
module.get_html = get_html
|
||||
return module
|
||||
|
||||
|
||||
def add_histogram(module):
|
||||
"""
|
||||
Updates the supplied module with a new get_html function that wraps
|
||||
the output of the old get_html function with additional information
|
||||
for admin users only, including a histogram of student answers and the
|
||||
definition of the xmodule
|
||||
"""
|
||||
original_get_html = module.get_html
|
||||
|
||||
@wraps(original_get_html)
|
||||
def get_html():
|
||||
module_id = module.id
|
||||
histogram = grade_histogram(module_id)
|
||||
|
||||
@@ -19,6 +19,7 @@ Longer TODO:
|
||||
multiple sites, but we do need a way to map their data assets.
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
import tempfile
|
||||
import glob2
|
||||
|
||||
@@ -167,19 +168,17 @@ MANAGERS = ADMINS
|
||||
# Static content
|
||||
STATIC_URL = '/static/'
|
||||
ADMIN_MEDIA_PREFIX = '/static/admin/'
|
||||
STATIC_ROOT = ENV_ROOT / "staticfiles"
|
||||
STATIC_ROOT = ENV_ROOT / "staticfiles"
|
||||
|
||||
# FIXME: We should iterate through the courses we have, adding the static
|
||||
# contents for each of them. (Right now we just use symlinks.)
|
||||
STATICFILES_DIRS = [
|
||||
PROJECT_ROOT / "static",
|
||||
ASKBOT_ROOT / "askbot" / "skins",
|
||||
("circuits", DATA_DIR / "images"),
|
||||
("handouts", DATA_DIR / "handouts"),
|
||||
("subs", DATA_DIR / "subs"),
|
||||
|
||||
# This is how you would use the textbook images locally
|
||||
# ("book", ENV_ROOT / "book_images")
|
||||
] + [
|
||||
# TODO (cpennington): When courses are stored in a database, this
|
||||
# should no longer be added to STATICFILES
|
||||
(course_dir, DATA_DIR / course_dir)
|
||||
for course_dir in os.listdir(DATA_DIR)
|
||||
]
|
||||
|
||||
# Locale/Internationalization
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
<script type="text/javascript" src="${static.url('js/vendor/jquery.cookie.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/vendor/jquery.qtip.min.js')}"></script>
|
||||
|
||||
## TODO (cpennington): Remove this when we have a good way for modules to specify js to load on the page
|
||||
## and in the wiki
|
||||
<script type="text/javascript" src="${static.url('js/schematic.js')}"></script>
|
||||
|
||||
% if settings.MITX_FEATURES['USE_DJANGO_PIPELINE']:
|
||||
<%static:js group='application'/>
|
||||
% endif
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</h2>
|
||||
|
||||
<section class="problem">
|
||||
${ static.replace_urls(problem['html']) }
|
||||
${ problem['html'] }
|
||||
|
||||
<section class="action">
|
||||
<input type="hidden" name="problem_id" value="${ problem['name'] }">
|
||||
|
||||
Reference in New Issue
Block a user