Merge pull request #20633 from edx/adeel/part1_xss_vulnerability

Fix templates for XSS code injection via translations
This commit is contained in:
adeel khan
2019-06-25 15:20:12 +05:00
committed by GitHub
34 changed files with 232 additions and 193 deletions

View File

@@ -1824,11 +1824,11 @@ class RegistrationCodeRedemptionCourseEnrollment(SharedModuleStoreTestCase):
RegistrationCodeRedemption.objects.filter(registration_code__code=registration_code)
response = self.client.get(redeem_url)
self.assertEquals(len(RegistrationCodeRedemption.objects.filter(registration_code__code=registration_code)), 1)
self.assertIn("You've clicked a link for an enrollment code that has already been used.", response.content)
self.assertIn("You've clicked a link for an enrollment code that has already been used.", response.content)
#now check that the registration code has already been redeemed
response = self.client.post(redeem_url)
self.assertIn("You've clicked a link for an enrollment code that has already been used.", response.content)
self.assertIn("You've clicked a link for an enrollment code that has already been used.", response.content)
#now check the response of the dashboard page
dashboard_url = reverse('dashboard')

View File

@@ -2305,6 +2305,7 @@ INSTALLED_APPS = [
# edx-drf-extensions
'csrf.apps.CsrfAppConfig', # Enables frontend apps to retrieve CSRF tokens.
'xss_utils'
]
######################### CSRF #########################################

View File

@@ -7,13 +7,13 @@
{% block nav-global %}{% endblock %}
{% block userlinks %}
{% if site_url %}
<a href="{{ site_url }}">{% trans 'View site' %}</a> /
<a href="{{ site_url }}">{% trans 'View site' as tmsg%}{{tmsg|force_escape}}</a> /
{% endif %}
{% if user.is_active and user.is_staff %}
{% url 'django-admindocs-docroot' as docsroot %}
{% if docsroot %}
<a href="{{ docsroot }}">{% trans 'Documentation' %}</a> /
<a href="{{ docsroot }}">{% trans 'Documentation' as tmsg%}{{tmsg|force_escape}}</a> /
{% endif %}
{% endif %}
<a href="{% url 'admin:logout' %}">{% trans 'Log out' %}</a>
<a href="{% url 'admin:logout' %}">{% trans 'Log out' as tmsg%}{{tmsg|force_escape}}</a>
{% endblock %}

View File

@@ -10,12 +10,14 @@
{% if form.non_field_errors|length > 0 %}
<p class="errornote">
{% trans "Please correct the errors below." %}
{% trans "Please correct the errors below." as tmsg %}{{tmsg|force_escape}}
</p>
{{ form.non_field_errors }}
{% endif %}
{% filter force_escape %}
{% blocktrans with username=retirement.user.username %}Are you sure you want to cancel retirement for user "{{ username }}"? {% endblocktrans %}
{% endfilter %}
<fieldset class="module aligned">
{% for field in form %}
@@ -33,7 +35,7 @@
</fieldset>
<div class="submit-row">
<input type="submit" class="default" value="{% trans 'Submit' %}">
<input type="submit" class="default" value="{% trans 'Submit' as tmsg %}{{tmsg|force_escape}}">
</div>
</form>

View File

@@ -1,6 +1,7 @@
<%page expression_filter="h"/>
<%! from django.utils.translation import ugettext as _ %>
<div class="wrap-instructor-info studio-view">
<a class="instructor-info-action" href="${edit_link}">${_("View Unit in Studio")}</a>
</div>
${frag_content}
${frag_content | n, decode.utf8}

View File

@@ -1,15 +1,17 @@
{% extends "main_django.html" %}
{% load i18n staticfiles %}
{% load django_markup %}
{% block title %}{% trans "Signed Out" %} | {{ block.super }}{% endblock %}
{% block title %}{% trans "Signed Out" as tmsg %} | {{ tmsg | force_escape }} | {{ block.super }}{% endblock %}
{% block body %}
<h1>{% trans "You have signed out." %}</h1>
<h1>{% trans "You have signed out." as tmsg %} | {{ tmsg | force_escape }}</h1>
<p style="text-align: center; margin-bottom: 20px;">
{% blocktrans trimmed %}
If you are not redirected within 5 seconds, <a href="{{ target }}">click here to go to the home page</a>.
{% blocktrans trimmed asvar signout_msg1 %}
If you are not redirected within 5 seconds, {start_anchor}click here to go to the home page{end_anchor}.
{% endblocktrans %}
{% interpolate_html signout_msg1 start_anchor='<a href="{{ target }}">'|safe end_anchor='</a>'|safe %}
</p>
<div id="iframeContainer" style="visibility: hidden" data-redirect-url="{{ target }}">

View File

@@ -1,6 +1,8 @@
<%page expression_filter="h"/>
<%!
import json
from django.utils.translation import ugettext as _
from openedx.core.djangolib.js_utils import js_escaped_string
%>
<!DOCTYPE HTML>
<html>
@@ -28,7 +30,7 @@ from django.utils.translation import ugettext as _
</form>
<script type="text/javascript">
(function (d) {
var element = d.getElementById("lti-${element_id}");
var element = d.getElementById("lti-${element_id | n, js_escaped_string}");
if (element) {
element.submit();
}

View File

@@ -29,7 +29,7 @@
{% load render_bundle from webpack_loader %}
{% render_bundle "commons" %}
<div class="window-wrap" dir="{{LANGUAGE_BIDI|yesno:'rtl,ltr'}}">
<a class="nav-skip" href="#main">{% trans "Skip to main content" %}</a>
<a class="nav-skip" href="#main">{% trans "Skip to main content" as tmsg %} | {{ tmsg | force_escape }}</a>
{% with course=request.course %}
{% include "header.html"|microsite_template_path with online_help_token=online_help_token %}
{% endwith %}

View File

@@ -1,3 +1,4 @@
<%page expression_filter="h"/>
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
${static.css(group='style-vendor-tinymce-content', raw=True)}
@@ -5,6 +6,7 @@ ${static.css(group='style-vendor-tinymce-skin', raw=True)}
${static.css(group='style-xmodule-annotations', raw=True)}
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.js_utils import js_escaped_string
from django.urls import reverse
%>
@@ -80,8 +82,8 @@ from django.urls import reverse
optionsAnnotator: {
permissions:{
user: {
id:"${student.email}",
name:"${student.username}"
id:"${student.email | n, js_escaped_string}",
name:"${student.username | n, js_escaped_string}"
},
userString: function (user) {
if (user && user.name)
@@ -95,9 +97,9 @@ from django.urls import reverse
},
permissions: {
'read': [],
'update': ["${student.email}"],
'delete': ["${student.email}"],
'admin': ["${student.email}"]
'update': ["${student.email | n, js_escaped_string}"],
'delete': ["${student.email | n, js_escaped_string}"],
'admin': ["${student.email | n, js_escaped_string}"]
},
showViewPermissionsCheckbox: true,
showEditPermissionsCheckbox: false,
@@ -132,11 +134,11 @@ from django.urls import reverse
},
},
auth: {
token: "${token}"
token: "${token | n, js_escaped_string}"
},
store: {
// The endpoint of the store on your server.
prefix: "${storage}",
prefix: "${storage | n, js_escaped_string}",
annotationData: {},
@@ -170,11 +172,11 @@ from django.urls import reverse
}
},
auth: {
token: "${token}"
token: "${token | n, js_escaped_string}"
},
store: {
// The endpoint of the store on your server.
prefix: "${storage}",
prefix: "${storage | n, js_escaped_string}",
annotationData: {},
@@ -189,7 +191,7 @@ from django.urls import reverse
}
};
var imgURLRoot = "${settings.STATIC_URL}" + "js/vendor/ova/catch/img/";
var imgURLRoot = "${settings.STATIC_URL | n, js_escaped_string}" + "js/vendor/ova/catch/img/";
//remove old instances
if (Annotator._instances.length !== 0) {
$('#notesHolder').annotator("destroy");
@@ -213,7 +215,7 @@ from django.urls import reverse
showPublicPrivate: true,
pagination:pagination,//Number of Annotations per load in the pagination,
flags:is_staff,
default_tab: "${default_tab}",
default_tab: "${default_tab | n, js_escaped_string}",
},
Catch = new CatchAnnotation($('#catchDIV'),catchOptions);
// TODO: Fix to avoid using global scope!

View File

@@ -2,7 +2,7 @@
{% load i18n configuration %}
{% block title %}
{% trans "Authorize" %} | {% platform_name %}
{% trans "Authorize" as tmsg %}{{tmsg|force_escape}} | {% platform_name %}
{% endblock %}
{% block body %}
@@ -12,7 +12,7 @@
<div class="block-center">
{% if not error %}
<form id="authorizationForm" method="post">
<h1 class="block-center-heading">{% trans "Authorize" %} {{ application.name }}?</h1>
<h1 class="block-center-heading">{% trans "Authorize" as tmsg %}{{tmsg|force_escape}} {{ application.name }}?</h1>
{% csrf_token %}
{% for field in form %}
@@ -21,7 +21,7 @@
{% endif %}
{% endfor %}
<p>{% trans "The above application requests the following permissions from your account:" %}</p>
<p>{% trans "The above application requests the following permissions from your account:" as tmsg%}{{tmsg|force_escape}}</p>
<ul>
{% for scope in scopes_descriptions %}
<li>{{ scope }}</li>
@@ -29,7 +29,7 @@
</ul>
{% if content_orgs %}
<p>{% trans "These permissions will be granted for data from your courses associated with the following content providers:" %}</p>
<p>{% trans "These permissions will be granted for data from your courses associated with the following content providers:" as tmsg %}{{tmsg|force_escape}}</p>
<ul>
{% for org_name in content_orgs %}
<li>{{ org_name }}</li>
@@ -37,7 +37,7 @@
</ul>
{% endif %}
<p>{% trans "Please click the 'Allow' button to grant these permissions to the above application. Otherwise, to withhold these permissions, please click the 'Cancel' button." %}
<p>{% trans "Please click the 'Allow' button to grant these permissions to the above application. Otherwise, to withhold these permissions, please click the 'Cancel' button." as tmsg %}{{tmsg|force_escape}}
</p>
{{ form.errors }}
@@ -45,13 +45,13 @@
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-authorization-cancel" name="cancel"/>{% trans "Cancel" %}</button><button type="submit" class="btn btn-authorization-allow" name="allow" value="Authorize"/>{% trans "Allow" %}</button>
<button type="submit" class="btn btn-authorization-cancel" name="cancel"/>{% trans "Cancel" as tmsg%}{{tmsg|force_escape}}</button><button type="submit" class="btn btn-authorization-allow" name="allow" value="Authorize"/>{% trans "Allow" as tmsg%}{{tmsg|force_escape}}</button>
</div>
</div>
</form>
{% else %}
<h2>{% trans "Error" %}: {{ error.error }}</h2>
<h2>{% trans "Error" as tmsg%}{{tmsg|force_escape}}: {{ error.error }}</h2>
<p>{{ error.description }}</p>
{% endif %}
</div>

View File

@@ -1,8 +1,11 @@
<%page expression_filter="h"/>
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
<%namespace file='main.html' import="login_query"/>
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.djangolib.js_utils import js_escaped_string
from django.urls import reverse
from django.utils import html
from django_countries import countries
@@ -50,7 +53,7 @@ import calendar
});
$('#register-form').on('ajax:success', function(event, json, xhr) {
var url = json.redirect_url || "${reverse('dashboard')}";
var url = json.redirect_url || "${reverse('dashboard') | n, js_escaped_string}";
location.href = url;
});
@@ -58,7 +61,7 @@ import calendar
toggleSubmitButton(true);
json = $.parseJSON(jqXHR.responseText);
$('.status.message.submission-error').addClass('is-shown').focus();
$('.status.message.submission-error .message-copy').html(json.value).stop().css("display", "block");
$('.status.message.submission-error .message-copy').text(json.value).stop().css("display", "block");
$(".field-error").removeClass('field-error');
$("[data-field='"+json.field+"']").addClass('field-error')
});
@@ -72,14 +75,14 @@ import calendar
removeClass('is-disabled').
attr('aria-disabled', false).
removeProp('disabled').
text("${_('Update my {platform_name} Account').format(platform_name=settings.PLATFORM_NAME)}");
text("${_('Update my {platform_name} Account').format(platform_name=settings.PLATFORM_NAME) | n, js_escaped_string}");
}
else {
$submitButton.
addClass('is-disabled').
attr('aria-disabled', true).
prop('disabled', true).
text("${_('Processing your account information')}");
text("${_('Processing your account information') | n, js_escaped_string}");
}
}
</script>
@@ -108,7 +111,9 @@ import calendar
</div>
<p class="instructions">
${_('Required fields are noted by <strong class="indicator">bold text and an asterisk (*)</strong>.')}
${Text(_('Required fields are noted by {strong_start}bold text and an asterisk (*){strong_end}.')).format(
strong_start=HTML('<strong class="indicator">'),
strong_end=HTML('</strong>')),}
</p>
<fieldset class="group group-form group-form-requiredinformation">
@@ -159,9 +164,9 @@ import calendar
<div class="field required checkbox" id="field-tos">
<input id="tos-yes" type="checkbox" name="terms_of_service" value="true" required aria-required="true" />
<label for="tos-yes">${_('I agree to the {link_start}Terms of Service{link_end}').format(
link_start='<a href="{url}" class="new-vp">'.format(url=marketing_link('TOS')),
link_end='</a>')}</label>
<label for="tos-yes">${Text(_('I agree to the {link_start}Terms of Service{link_end}')).format(
link_start=HTML('<a href="{url}" class="new-vp">').format(url=marketing_link('TOS')),
link_end=HTML('</a>'))}</label>
</div>
% endif
@@ -171,17 +176,17 @@ import calendar
<%
honor_code_path = marketing_link('HONOR')
%>
<label for="honorcode-yes">${_('I agree to the {link_start}Honor Code{link_end}').format(
link_start='<a href="{url}" class="new-vp">'.format(url=honor_code_path),
link_end='</a>')}</label>
<label for="honorcode-yes">${Text(_('I agree to the {link_start}Honor Code{link_end}')).format(
link_start=HTML('<a href="{url}" class="new-vp">').format(url=honor_code_path),
link_end=HTML('</a>'))}</label>
</div>
</li>
</ol>
</fieldset>
% if course_id and enrollment_action:
<input type="hidden" name="enrollment_action" value="${enrollment_action | h}" />
<input type="hidden" name="course_id" value="${course_id | h}" />
<input type="hidden" name="enrollment_action" value="${enrollment_action}" />
<input type="hidden" name="course_id" value="${course_id}" />
% endif
<div class="form-actions">

View File

@@ -1,8 +1,10 @@
<%page expression_filter="h"/>
<%inherit file="main.html" />
<%namespace name='static' file='static_content.html'/>
<%namespace file='main.html' import="login_query"/>
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.js_utils import js_escaped_string
from django.urls import reverse
from django.utils import html
from django_countries import countries
@@ -52,14 +54,14 @@ import calendar
});
$('#register-form').on('ajax:success', function(event, json, xhr) {
var nextUrl = "${login_redirect_url}";
var nextUrl = "${login_redirect_url | n, js_escaped_string}";
if (json.redirect_url) {
nextUrl = json.redirect_url; // Most likely third party auth completion. This trumps 'nextUrl' above.
}
if (!isExternal(nextUrl)) {
location.href=nextUrl;
} else {
location.href="${reverse('dashboard')}";
location.href="${reverse('dashboard') | n, js_escaped_string}";
}
});
@@ -67,7 +69,7 @@ import calendar
toggleSubmitButton(true);
json = $.parseJSON(jqXHR.responseText);
$('.status.message.submission-error').addClass('is-shown').focus();
$('.status.message.submission-error .message-copy').html(json.value).stop().css("display", "block");
$('.status.message.submission-error .message-copy').text(json.value).stop().css("display", "block");
$(".field-error").removeClass('field-error');
$("[data-field='"+json.field+"']").addClass('field-error')
});
@@ -86,13 +88,13 @@ import calendar
removeClass('is-disabled').
attr('aria-disabled', false).
prop('disabled', false).
html("${_('Create My {platform_name} Account').format(platform_name=platform_name)}");
text("${_('Create My {platform_name} Account').format(platform_name=platform_name) | n, js_escaped_string}");
}
else {
$submitButton.
addClass('is-disabled').
prop('disabled', true).
text("${_('Processing your account information')}");
text("${_('Processing your account information') | n, js_escaped_string}");
}
}
</script>

View File

@@ -1,6 +1,8 @@
<%page expression_filter="h"/>
<%!
from django.urls import reverse
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML, Text
from django.conf import settings
%>
<%inherit file="main.html" />
@@ -14,11 +16,11 @@ from django.conf import settings
<hr class="horizontal-divider">
<p>
${_("You have re-enabled forum notification emails from {platform_name}. "
"You may {dashboard_link_start}return to your dashboard{link_end}.").format(
${Text(_("You have re-enabled forum notification emails from {platform_name}. "
"You may {dashboard_link_start}return to your dashboard{link_end}.")).format(
platform_name=settings.PLATFORM_NAME,
dashboard_link_start="<a href='{}'>".format(reverse('dashboard')),
link_end="</a>",)}
dashboard_link_start=HTML("<a href='{}'>").format(reverse('dashboard')),
link_end=HTML("</a>"),)}
</p>
</section>
</section>

View File

@@ -1,5 +1,7 @@
<%page expression_filter="h"/>
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML, Text
from django.urls import reverse
from openedx.core.lib.courses import course_image_url
%>
@@ -20,34 +22,34 @@ from openedx.core.lib.courses import course_image_url
<img class="item-image" src="${course_image_url(course)}"
alt="${_("{course_number} {course_title} Cover Image").format(
course_number=course.display_number_with_default,
course_title=course.display_name_with_default_escaped,
course_title=course.display_name_with_default,
)}" />
</div>
<div class="enrollment-details">
<div class="sub-title">
${_("Confirm your enrollment for: {span_start}course dates{span_end}").format(
span_start='<span class="course-date-label">',
span_end='</span>'
)}
${Text(_("Confirm your enrollment for: {span_start}course dates{span_end}")).format(
span_start=HTML('<span class="course-date-label">'),
span_end=HTML('</span>')
)}
<div class="clearfix"></div>
</div>
<div class="course-title">
<h1>
${course.display_name | h}
${course.display_name}
</h1>
</div>
<hr>
<div>
<p class="enrollment-text">
% if reg_code_already_redeemed:
${_(
${Text(_(
"You've clicked a link for an enrollment code that has already "
"been used. Check your {link_start}course dashboard{link_end} "
"to see if you're enrolled in the course, or contact your "
"company's administrator."
).format(
link_start=u'<a href="{url}">'.format(url=reverse('dashboard')),
link_end='</a>',
)).format(
link_start=HTML(u'<a href="{url}">').format(url=reverse('dashboard')),
link_end=HTML('</a>'),
)}
% elif redemption_success:
${_(
@@ -55,15 +57,15 @@ from openedx.core.lib.courses import course_image_url
"This course has now been added to your dashboard."
).format(
course_name=course.display_name,
) | h}
)}
% elif registered_for_course:
${_(
${Text(_(
"You're already enrolled for this course. "
"Visit your {link_start}dashboard{link_end} to see the course."
).format(
link_start=u'<a href="{url}">'.format(url=reverse('dashboard')),
link_end='</a>',
)}
)).format(
link_start=HTML(u'<a href="{url}">').format(url=reverse('dashboard')),
link_end=HTML('</a>'),
)}
% elif redeem_code_error:
${_( "There was an error processing your redeem code.")}
% else:
@@ -75,7 +77,7 @@ from openedx.core.lib.courses import course_image_url
).format(
course_name=course.display_name,
site_name=site_name,
) | h}
)}
% endif
</p>
</div>

View File

@@ -1,5 +1,8 @@
<%page expression_filter="h"/>
<%namespace name='static' file='static_content.html'/>
<%!
from openedx.core.djangolib.markup import HTML, Text
from openedx.core.djangolib.js_utils import js_escaped_string
from django.conf import settings
from django.urls import reverse
from django_countries import countries
@@ -21,8 +24,8 @@ import calendar
<div id="register">
<header>
<h2>
${_('Sign Up for {platform_name}').format(
platform_name=u'<span class="edx">{}</span>'.format(settings.PLATFORM_NAME)
${Text(_('Sign Up for {platform_name}')).format(
platform_name=HTML(u'<span class="edx">{}</span>').format(settings.PLATFORM_NAME)
)}
</h2>
<hr>
@@ -47,7 +50,10 @@ import calendar
<label data-field="name" for="signup_fullname">${_('Full Name')} + ' *'</label>
<input id="signup_fullname" type="text" name="name" placeholder="${_('e.g. Your Name (for certificates)')}" required />
% else:
<p>${_('<i>Welcome</i> {name}').format(name=extauth_id)}</p><br/>
<p>${Text(_('{start_li}Welcome{end_li} {name}')).format(
start_li=HTML('<i>'),
end_li=HTML('</i>'),
name=extauth_id)}</p><br/>
<p><i>${_('Enter a public username:')}</i></p>
<label data-field="username" for="signup_username">${_('Public Username')} + ' *'</label>
@@ -127,17 +133,17 @@ import calendar
<div class="input-group">
<label data-field="terms_of_service" class="terms-of-service" for="signup_tos">
<input id="signup_tos" name="terms_of_service" type="checkbox" value="true">
${_('I agree to the {link_start}Terms of Service{link_end}').format(
link_start='<a href="{url}" target="_blank">'.format(url=reverse('tos')),
link_end='</a>') + ' *'}
${Text(_('I agree to the {link_start}Terms of Service{link_end}')).format(
link_start=HTML('<a href="{url}" target="_blank">').format(url=reverse('tos')),
link_end=HTML('</a>'))} *
</label>
% if settings.REGISTRATION_EXTRA_FIELDS['honor_code'] != 'hidden':
<label data-field="honor_code" class="honor-code" for="signup_honor">
<input id="signup_honor" name="honor_code" type="checkbox" value="true">
${_('I agree to the {link_start}Honor Code{link_end}').format(
link_start='<a href="{url}" target="_blank">'.format(url=reverse('honor')),
link_end='</a>') + ' *'}
${Text(_('I agree to the {link_start}Honor Code{link_end}')).format(
link_start=HTML('<a href="{url}" target="_blank">').format(url=reverse('honor')),
link_end=HTML('</a>'))} *
</label>
% endif
</div>
@@ -162,12 +168,12 @@ import calendar
<script type="text/javascript">
(function() {
$(document).delegate('#register_form', 'ajax:success', function(data, json, xhr) {
location.href="${reverse('dashboard')}";
location.href="${reverse('dashboard') | n, js_escaped_string}";
});
$(document).delegate('#register_form', 'ajax:error', function(event, jqXHR, textStatus) {
json = $.parseJSON(jqXHR.responseText);
$(".field-error").removeClass('field-error');
$('#register_error').html(json.value).stop().css("display", "block");
$('#register_error').text(json.value).stop().css("display", "block");
$("[data-field='"+json.field+"']").addClass('field-error')
});

View File

@@ -1,6 +1,8 @@
<%page expression_filter="h"/>
<%!
from django.urls import reverse
from django.utils.translation import ugettext as _
from openedx.core.djangolib.js_utils import js_escaped_string
%>
<%namespace name='static' file='../static_content.html'/>
@@ -9,8 +11,8 @@ from django.utils.translation import ugettext as _
<%block name="js_extra">
<%static:require_module module_name="support/js/certificates_factory" class_name="CertificatesFactory">
new CertificatesFactory({
userFilter: '${ user_filter }',
courseFilter: '${course_filter}'
userFilter: '${ user_filter | n, js_escaped_string}',
courseFilter: '${course_filter | n, js_escaped_string}'
});
</%static:require_module>
</%block>

View File

@@ -1,3 +1,4 @@
<%page expression_filter="h"/>
<%inherit file="/main.html" />
<%namespace name='static' file='/static_content.html'/>
<%!

View File

@@ -27,13 +27,13 @@
{% include "wiki/includes/article_menu.html" %}
</ul>
<div class="timestamp">
<span class="label">{% trans "Last modified:" %}</span><br />
<span class="label">{% trans "Last modified:" % as tmsg} | {{ tmsg | force_escape}}</span><br />
<span class="date">{{ article.current_revision.modified }}</span>
</div>
{% if urlpath %}
<div class="see-children">
<a href="{% url 'wiki:dir' path=urlpath.path %}">{% trans "See all children" %}</a>
<a href="{% url 'wiki:dir' path=urlpath.path %}">{% trans "See all children" as tmsg %} | {{ tmsg | force_escape}}</a>
</div>
{% endif %}
</div>
@@ -44,5 +44,5 @@
{% endblock %}
{% block footer_prepend %}
<p><em>{% trans "This article was last modified:" %} {{ article.current_revision.modified }}</em></p>
<p><em>{% trans "This article was last modified:" as tmsg %} | {{tmsg | force_escape}} {{ article.current_revision.modified }}</em></p>
{% endblock %}

View File

@@ -3,7 +3,7 @@
{% load theme_pipeline %}{% load sekizai_tags i18n configuration %}{% load staticfiles %}
{% block title %}
{% block pagetitle %}{% endblock %} | {% trans "Wiki" %} | {% platform_name %}
{% block pagetitle %}{% endblock %} | {% trans "Wiki" as tmsg%}{{tmsg|force_escape}} | {% platform_name %}
{% endblock %}
{% block bodyclass %}view-in-course view-wiki{% endblock %}

View File

@@ -1,7 +1,7 @@
{% extends "wiki/base.html" %}
{% load wiki_tags i18n sekizai_tags %}
{% block pagetitle %}{% trans "Add new article" %}{% endblock %}
{% block pagetitle %}{% trans "Add new article" as tmsg %}{{tmsg|force_escape}}{% endblock %}
{% block wiki_contents %}
@@ -26,19 +26,19 @@
<article class="main-article new-article">
{% include "wiki/includes/editormedia.html" %}
<h1 class="page-header">{% trans "Add new article" %}</h1>
<h1 class="page-header">{% trans "Add new article" as tmsg%}{{tmsg|force_escape}}</h1>
<form method="POST" class="form-horizontal">
{% wiki_form create_form %}
<div class="form-actions">
<button type="submit" name="save_changes" class="btn btn-primary btn-large">
<span class="icon fa fa-plus" aria-hidden="true"></span>
{% trans "Create article" %}
{% trans "Create article" as tmsg%}{{tmsg|force_escape}}
</button>
<a href="{% url 'wiki:get' path=parent_urlpath.path %}" class="btn btn-large back">
<span class="icon fa fa-circle-arrow-left" aria-hidden="true"></span>
{% trans "Go back" %}
{% trans "Go back" as tmsg%}{{tmsg|force_escape}}
</a>
</div>
{% include "wiki/includes/cheatsheet.html" %}

View File

@@ -1,34 +1,34 @@
{% extends "wiki/base.html" %}
{% load wiki_tags i18n sekizai_tags %}
{% block pagetitle %}{% trans "Delete article" %}{% endblock %}
{% block pagetitle %}{% trans "Delete article" as tmsg %}{{tmsg|force_escape}}{% endblock %}
{% block wiki_contents %}
<section class="delete">
<h1 class="page-header">{% trans "Delete" %} "{{ article.current_revision.title }}"</h1>
<h1 class="page-header">{% trans "Delete" as tmsg%}{{tmsg|force_escape}} "{{ article.current_revision.title }}"</h1>
{% if cannot_delete_root %}
<p class="lead">{% trans "You cannot delete a root article." %}</p>
<p><a href="{% url 'wiki:get' path=urlpath.path article_id=article.id %}">{% trans "Go back" %}</a></p>
<p class="lead">{% trans "You cannot delete a root article." as tmsg%}{{tmsg|force_escape}}</p>
<p><a href="{% url 'wiki:get' path=urlpath.path article_id=article.id %}">{% trans "Go back" as tmsg %}{{tmsg|force_escape}}</a></p>
{% else %}
{% if cannot_delete_children %}
<p class="alert alert-error"><strong>{% trans "You cannot delete this article because you do not have permission to delete articles with children. Try to remove the children manually one-by-one." %}</strong></p>
<p class="alert alert-error"><strong>{% trans "You cannot delete this article because you do not have permission to delete articles with children. Try to remove the children manually one-by-one." as tmsg %}{{tmsg|force_escape}}</strong></p>
{% endif %}
{% if delete_children %}
<p class="lead">{% trans "You are deleting an article. This means that its children will be deleted as well. If you choose to purge, children will also be purged!" %}</p>
<p class="lead">{% trans "You are deleting an article. This means that its children will be deleted as well. If you choose to purge, children will also be purged!" as tmsg%}{{tmsg|force_escape}}</p>
<h2>{% trans "Articles that will be deleted" %}</h2>
<h2>{% trans "Articles that will be deleted" as tmsg%}{{tmsg|force_escape}}</h2>
<ul>
{% for child in delete_children %}
<li><a href="{% url 'wiki:get' article_id=child.article.id %}" target="_blank">{{ child.article }}</a></li>
{% if delete_children_more %}
<li><em>{% trans "...and more!" %}</em></li>
<li><em>{% trans "...and more!" as tmsg%}{{tmsg|force_escape}}</em></li>
{% endif %}
{% endfor %}
</ul>
@@ -36,7 +36,7 @@
{% endif %}
{% if not cannot_delete_children %}
<p class="lead">{% trans "You are deleting an article. Please confirm." %}</p>
<p class="lead">{% trans "You are deleting an article. Please confirm." as tmsg%}{{tmsg|force_escape}}</p>
<form method="POST" class="form-horizontal">
{% wiki_form delete_form %}
@@ -46,11 +46,11 @@
<div class="form-actions">
<button type="submit" name="save_changes" class="btn btn-danger btn-large">
<span class="icon fa fa-remove" aria-hidden="true"></span>
{% trans "Delete article" %}
{% trans "Delete article" as tmsg%}{{tmsg|force_escape}}
</button>
<a href="{% url 'wiki:get' path=urlpath.path article_id=article.id %}" class="btn btn-large back">
<span class="icon fa fa-circle-arrow-left" aria-hidden="true"></span>
{% trans "Go back" %}
{% trans "Go back" as tmsg%}{{tmsg|force_escape}}
</a>
</div>
</form>

View File

@@ -1,7 +1,7 @@
{% extends "wiki/article.html" %}
{% load wiki_tags i18n sekizai_tags %}
{% block pagetitle %}{% trans "Edit" %}: {{ article.current_revision.title }}{% endblock %}
{% block pagetitle %}{% trans "Edit" as tmsg%}{{tmsg|force_escape}}: {{ article.current_revision.title }}{% endblock %}
{% block wiki_contents_tab %}
@@ -25,7 +25,7 @@
<div class="form-actions">
<button type="submit" name="save" value="1" class="btn btn-large btn-primary" onclick="this.form.target=''; this.form.action='{% url 'wiki:edit' path=urlpath.path article_id=article.id %}'">
<span class="icon fa fa-check-square-o" aria-hidden="true"></span>
{% trans "Save changes" %}
{% trans "Save changes" as tmsg%}{{tmsg|force_escape}}
</button>
<a class="btn btn-large" id="previewButton" href="#previewModal" rel="leanModal"
onclick="
@@ -33,21 +33,21 @@
document.article_edit_form.action='{% url 'wiki:preview' path=urlpath.path article_id=article.id %}';
document.article_edit_form.submit();">
<span class="icon fa fa-eye" aria-hidden="true"></span>
{% trans "Preview" %}
{% trans "Preview" as tmsg%}{{tmsg|force_escape}}
</a>
<a href="{% url 'wiki:delete' path=urlpath.path article_id=article.id %}" class="pull-right btn btn-danger">
<span class="icon fa fa-remove" aria-hidden="true"></span>
{% trans "Delete article" %}
{% trans "Delete article" as tmsg%}{{tmsg|force_escape}}
</a>
</div>
<div id="previewModal" class="modal" aria-hidden="true">
<div class="inner-wrapper" role="dialog" aria-labelledby="preview-title" aria-modal=true>
<button class="close-modal"><span class="icon fa fa-remove" aria-hidden="true"></span> <span class="sr">{% trans 'Close' %}</span></button>
<button class="close-modal"><span class="icon fa fa-remove" aria-hidden="true"></span> <span class="sr">{% trans 'Close' as tmsg%}{{tmsg|force_escape}}</span></button>
<header>
<h2 id="preview-title">{% trans "Wiki Preview" %}<span class="sr">, {% trans "window open" %}</span></h2>
<h2 id="preview-title">{% trans "Wiki Preview" as tmsg%}{{tmsg|force_escape}}<span class="sr">, {% trans "window open" as tmsg%}{{tmsg|force_escape}}</span></h2>
<hr/>
</header>
@@ -58,12 +58,12 @@
<div class="modal-footer">
<button type="submit" name="save" value="1" class="btn btn-large btn-primary" onclick="this.form.target=''; this.form.action='{% url 'wiki:edit' path=urlpath.path article_id=article.id %}'">
<span class="icon fa fa-check-square-o" aria-hidden="true"></span>
{% trans "Save changes" %}
{% trans "Save changes" as tmsg%}{{tmsg|force_escape}}
</button>
<a id="previewModalBackToEditor" href="#" class="btn btn-large">
<span class="icon fa fa-circle-arrow-left" aria-hidden="true"></span>
{% trans "Back to editor" %}
{% trans "Back to editor" as tmsg%}{{tmsg|force_escape}}
</a>
</div>
</div>

View File

@@ -1,7 +1,7 @@
{% extends "wiki/article.html" %}
{% load wiki_tags i18n sekizai_tags %}
{% block pagetitle %}{% trans "History" %}: {{ article.current_revision.title }}{% endblock %}
{% block pagetitle %}{% trans "History" as tmsg%}{{tmsg|force_escape}}: {{ article.current_revision.title }}{% endblock %}
{% block wiki_contents_tab %}
@@ -91,7 +91,7 @@
{% endaddtoblock %}
<p class="lead">
{% trans "Click each revision to see a list of edited lines. Click the Preview button to see how the article looked at this stage. At the bottom of this page, you can change to a particular revision or merge an old revision with the current one." %}
{% trans "Click each revision to see a list of edited lines. Click the Preview button to see how the article looked at this stage. At the bottom of this page, you can change to a particular revision or merge an old revision with the current one." as tmsg%}{{tmsg|force_escape}}
</p>
<form method="GET" name="revisions_form">
@@ -110,7 +110,7 @@
{% elif revision.automatic_log %}
{{ revision.automatic_log }}
{% else %}
{% trans "(no log message)" %}
{% trans "(no log message)" as tmsg%}{{tmsg|force_escape}}
{% endif %}
</small>
</div>
@@ -130,7 +130,7 @@
$('#previewRevisionModal .switch-to-revision').attr('href', '{% url 'wiki:change_revision' path=urlpath.path article_id=article.id revision_id=revision.id %}');
document.revisions_form.submit();">
<span class="icon fa fa-eye" aria-hidden="true"></span>
{% trans "Preview this revision" %}
{% trans "Preview this revision" as tmsg%}{{tmsg|force_escape}}
</a>
{% if article|can_write:user %}
@@ -149,7 +149,7 @@
<div id="collapse{{ revision.revision_number }}" class="accordion-body collapse" tabindex="0">
<div class="accordion-inner diff-container" style="padding: 0;">
<dl class="dl-horizontal">
<dt>{% trans "Auto log:" %}</dt>
<dt>{% trans "Auto log:" as tmsg%}{{tmsg|force_escape}}</dt>
<dd>{{ revision.automatic_log|default:"-"|linebreaksbr }}</dd>
</dl>
<table class="table table-condensed" style="margin: 0; border-collapse: collapse;">
@@ -157,7 +157,7 @@
<tr>
<th scope="col" class="linenumber">{% if revision.previous_revision %}#{{revision.previous_revision.revision_number}}{% endif %}</th>
<th scope="col" class="linenumber">#{{revision.revision_number}}</th>
<th scope="col">{% trans "Change" %}</th>
<th scope="col">{% trans "Change" as tmsg%}{{tmsg|force_escape}}</th>
</tr>
</thead>
</table>
@@ -180,17 +180,17 @@
$('.merge-revision-commit').attr('href', $('input[type=radio]:checked').attr('merge-button-commit-href'));
document.revisions_form.submit();">
<span class="icon fa fa-random" aria-hidden="true"></span>
{% trans "Merge selected with current..." %}
{% trans "Merge selected with current..." as tmsg%}{{tmsg|force_escape}}
</a>
{% else %}
<button type="submit" disabled="true" name="preview" value="1" class="btn btn-large">
<span class="icon fa fa-lock" aria-hidden="true"></span>
{% trans "Merge selected with current..." %}
{% trans "Merge selected with current..." as tmsg%}{{tmsg|force_escape}}
</button>
{% endif %}
<button type="submit" name="save" value="1" class="btn btn-large btn-primary" onclick="this.form.action=$('input[type=radio]:checked').attr('switch-button-href')">
<span class="icon fa fa-flag" aria-hidden="true"></span>
{% trans "Switch to selected version" %}
{% trans "Switch to selected version" as tmsg%}{{tmsg|force_escape}}
</button>
</div>
</div>
@@ -200,10 +200,10 @@
<input type="hidden" name="r" value="" />
<div id="previewRevisionModal" class="modal" aria-hidden="true">
<div class="inner-wrapper" role="dialog" aria-labelledby="preview-title" aria-modal=true>
<button class="close-modal"><span class="icon fa fa-remove" aria-hidden="true"></span> <span class="sr">{% trans 'Close' %}</span></button>
<button class="close-modal"><span class="icon fa fa-remove" aria-hidden="true"></span> <span class="sr">{% trans 'Close' as tmsg%}{{tmsg|force_escape}}</span></button>
<header>
<h2 id="preview-title">{% trans "Wiki Revision Preview" %}<span class="sr">, {% trans "window open" %}</span></h2>
<h2 id="preview-title">{% trans "Wiki Revision Preview" as tmsg%}{{tmsg|force_escape}}<span class="sr">, {% trans "window open" as tmsg%}{{tmsg|force_escape}}</span></h2>
<hr/>
</header>
<div class="modal-body">
@@ -212,17 +212,17 @@
<div class="modal-footer">
<a id="previewRevisionModalBackToHistory" href="#" class="btn btn-large" data-dismiss="modal">
<span class="icon fa fa-circle-arrow-left" aria-hidden="true"></span>
{% trans "Back to history view" %}
{% trans "Back to history view" as tmsg %}{{tmsg|force_escape}}
</a>
{% if article|can_write:user %}
<button type="button" class="btn btn-large btn-primary switch-to-revision">
<span class="icon fa fa-flag" aria-hidden="true"></span>
{% trans "Switch to this version" %}
{% trans "Switch to this version" as tmsg %}{{tmsg|force_escape}}
</button>
{% else %}
<button type="button" class="btn btn-large btn-primary disabled">
<span class="icon fa fa-lock" aria-hidden="true"></span>
{% trans "Switch to this version" %}
{% trans "Switch to this version" as tmsg%}{{tmsg|force_escape}}
</button>
{% endif %}
</div>
@@ -231,15 +231,15 @@
<div id="mergeModal" class="modal" aria-hidden="true">
<div class="inner-wrapper" role="dialog" aria-labelledby="merge-title" aria-modal=true>
<button class="close-modal"><span class="icon fa fa-remove" aria-hidden="true"></span> <span class="sr">{% trans 'Close' %}</span></button>
<button class="close-modal"><span class="icon fa fa-remove" aria-hidden="true"></span> <span class="sr">{% trans 'Close' as tmsg%}{{tmsg|force_escape}}</span></button>
<header>
<h2 id="merge-title">{% trans "Merge Revision" %}<span class="sr">, {% trans "window open" %}</span></h2>
<h2 id="merge-title">{% trans "Merge Revision" as tmsg %}{{tmsg|force_escape}}<span class="sr">, {% trans "window open" as tmsg%}{{tmsg|force_escape}}</span></h2>
<hr/>
</header>
<div class="modal-header">
<h1>{% trans "Merge with current" %}</h1>
<p class="lead"><span class="icon fa fa-info-circle" aria-hidden="true"></span> {% trans "When you merge a revision with the current, all data will be retained from both versions and merged at its approximate location from each revision." %} <strong>{% trans "After this, it's important to do a manual review." %}</strong></p>
<h1>{% trans "Merge with current" as tmsg%}{{tmsg|force_escape}}</h1>
<p class="lead"><span class="icon fa fa-info-circle" aria-hidden="true"></span> {% trans "When you merge a revision with the current, all data will be retained from both versions and merged at its approximate location from each revision." as tmsg %}{{tmsg|force_escape}} <strong>{% trans "After this, it's important to do a manual review." as tmsg%}{{tmsg|force_escape}}</strong></p>
</div>
<div class="modal-body">
<iframe name="mergeWindow"></iframe>
@@ -247,17 +247,17 @@
<div class="modal-footer">
<a id="mergeModalBackToHistory" href="#" class="btn btn-large" data-dismiss="modal">
<span class="icon fa fa-circle-arrow-left" aria-hidden="true"></span>
{% trans "Back to history view" %}
{% trans "Back to history view" as tmsg%}{{tmsg|force_escape}}
</a>
{% if article|can_write:user %}
<button type="button" class="btn btn-large btn-primary merge-revision-commit">
<span class="icon fa fa-file" aria-hidden="true"></span>
{% trans "Create new merged version" %}
{% trans "Create new merged version" as tmsg%}{{tmsg|force_escape}}
</button>
{% else %}
<button type="button" class="btn btn-large btn-primary disabled">
<span class="icon fa fa-lock" aria-hidden="true"></span>
{% trans "Create new merged version" %}
{% trans "Create new merged version" as tmsg%}{{tmsg|force_escape}}
</button>
{% endif %}
</div>

View File

@@ -1,12 +1,14 @@
{% load i18n %}
{% load django_markup %}
<em>
{% url 'wiki:signup' as signup_url %}
{% url 'wiki:login' as login_url %}
{% if login_url and signup_url %}
{% blocktrans trimmed %}
You need to <a href="{{ login_url }}">log in</a> or <a href="{{ signup_url }}">sign up</a> to use this function.
{% blocktrans trimmed asvar tmsg %}
You need to {anchor_start_login}log in{anchor_end} or {anchor_start_signup}sign up{anchor_end} to use this function.
{% endblocktrans %}
{% interpolate_html tmsg anchor_start_login='<a href="{{ login_url }}">'|safe anchor_end='</a>'|safe anchor_start_signup='<a href="{{ signup_url }}">'|safe %}
{% else %}
{% trans "You need to log in or sign up to use this function." %}
{% trans "You need to log in or sign up to use this function." as tmsg %} {{ tmsg|force_escape }}
{% endif %}
</em>

View File

@@ -1,60 +1,62 @@
{% load i18n %}
{% load django_markup %}
<div id="cheatsheetModal" class="modal" aria-hidden="true">
<div class="inner-wrapper" role="dialog" aria-labelledby="cheatsheet-title" aria-modal=true>
<button class="close-modal"><span class="icon fa fa-remove" aria-hidden="true"></span> <span class="sr">{% trans 'Close' %}</span></button>
<button class="close-modal"><span class="icon fa fa-remove" aria-hidden="true"></span> <span class="sr">{% trans 'Close' as tmsg %}{{tmsg|force_escape}}</span></button>
<header>
<h2 id="cheatsheet-title">{% trans "Wiki Cheatsheet" %}<span class="sr">, {% trans "window open" %}</span></h2>
<h2 id="cheatsheet-title">{% trans "Wiki Cheatsheet" as tmsg%}{{tmsg|force_escape}}<span class="sr">, {% trans "window open" as tmsg%}{{tmsg|force_escape}}</span></h2>
<hr/>
</header>
<div id="cheatsheet-body" class="modal-body">
<div class="left-column">
<section>
<h2>{% trans "Wiki Syntax Help" %}</h2>
<p>{% trans "This wiki uses <strong>Markdown</strong> for styling. There are several useful guides online. See any of the links below for in-depth details:" %}</p>
<h2>{% trans "Wiki Syntax Help" as tmsg %}{{tmsg|force_escape}}</h2>
<p>{% trans "This wiki uses {start_strong}Markdown{end_strong} for styling. There are several useful guides online. See any of the links below for in-depth details:" as tmsg%}
{% interpolate_html tmsg start_strong='<strong>'|safe end_strong='</strong>'|safe %}</p>
<ul>
<li><a href="http://daringfireball.net/projects/markdown/basics" target="_blank">{% trans 'Markdown: Basics' %}</a></li>
<li><a href="http://greg.vario.us/doc/markdown.txt" target="_blank">{% trans 'Quick Markdown Syntax Guide' %}</a></li>
<li><a href="http://www.lowendtalk.com/discussion/6/miniature-markdown-guide" target="_blank">{% trans 'Miniature Markdown Guide' %}</a></li>
<li><a href="http://daringfireball.net/projects/markdown/basics" target="_blank">{% trans 'Markdown: Basics' as tmsg %}{{tmsg|force_escape}}</a></li>
<li><a href="http://greg.vario.us/doc/markdown.txt" target="_blank">{% trans 'Quick Markdown Syntax Guide' as tmsg %}{{tmsg|force_escape}}</a></li>
<li><a href="http://www.lowendtalk.com/discussion/6/miniature-markdown-guide" target="_blank">{% trans 'Miniature Markdown Guide' as tmsg%}{{tmsg|force_escape}}</a></li>
</ul>
<p>{% trans "To create a new wiki article, create a link to it. Clicking the link gives you the creation page." %}</p>
<pre>{% trans "[Article Name](wiki:ArticleName)" %}</pre>
<p>{% trans "To create a new wiki article, create a link to it. Clicking the link gives you the creation page." as tmsg %}{{tmsg|force_escape}}</p>
<pre>{% trans "[Article Name](wiki:ArticleName)" as tmsg%}{{tmsg|force_escape}}</pre>
</section>
<section>
<h3>{% blocktrans with platform_name=settings.PLATFORM_NAME %}{{ platform_name }} Additions:{% endblocktrans %}</h3>
<pre>$LaTeX {% trans "Math Expression" %}$</pre>
<h3>{% filter force_escape %}{% blocktrans with platform_name=settings.PLATFORM_NAME %}{{ platform_name }} Additions:{% endblocktrans %}{%endfilter}</h3>
<pre>$LaTeX {% trans "Math Expression" as tmsg %}{{tmsg|force_escape}}$</pre>
</section>
</div>
<div class="right-column">
<section>
<h3>{% trans "Useful examples:" %}</h3>
<h3>{% trans "Useful examples:" as tmsg%}{{tmsg|force_escape}}</h3>
<pre>
http://wikipedia.org
[{% trans "Wikipedia" %}](http://wikipedia.org)
[{% blocktrans with platform_name=settings.PLATFORM_NAME %}{{ platform_name }} Wiki{% endblocktrans %}](wiki:/edx/)
[{% trans "Wikipedia" as tmsg%}{{tmsg|force_escape}}](http://wikipedia.org)
[{% filter force_escape %}{% blocktrans with platform_name=settings.PLATFORM_NAME %}{{ platform_name }} Wiki{% endblocktrans %}]{%endfilter%}(wiki:/edx/)
</pre>
<pre>
{% trans "Huge Header" %}
{% trans "Huge Header" as tmsg%}{{tmsg|force_escape}}
===========</pre>
<pre>
{% trans "Smaller Header" %}
{% trans "Smaller Header" as tmsg%}{{tmsg|force_escape}}
--------------</pre>
<pre>
{# Translators: Leave the punctuation, but translate "emphasis" #}
{% trans "*emphasis* or _emphasis_" %}</pre>
{% trans "*emphasis* or _emphasis_" as tmsg %}{{tmsg|force_escape}}</pre>
<pre>
{# Translators: Leave the punctuation, but translate "strong" #}
{% trans "**strong** or __strong__" %}</pre>
{% trans "**strong** or __strong__" as tmsg %}{{tmsg|force_escape}}</pre>
<pre>
- {% trans "Unordered List" %}
- {% trans "Sub Item 1" %}
- {% trans "Sub Item 2" %}</pre>
- {% trans "Unordered List" as tmsg%}{{tmsg|force_escape}}
- {% trans "Sub Item 1" as tmsg%}{{tmsg|force_escape}}
- {% trans "Sub Item 2" as tmsg %}{{tmsg|force_escape}}</pre>
<pre>
1. {% trans "Ordered" %}
2. {% trans "List" %}</pre>
1. {% trans "Ordered" as tmsg%}{{tmsg|force_escape}}
2. {% trans "List" as tmsg%}{{tmsg|force_escape}}</pre>
<pre>
&gt; {% trans "Quotes" %}</pre>
&gt; {% trans "Quotes" as tmsg%}{{tmsg|force_escape}}</pre>
</section>
</div>

View File

@@ -1,7 +1,9 @@
{% load i18n %}
<p id="hint_id_content" class="help-block">
{% filter force_escape %}
{% blocktrans with start_link="<a id='cheatsheetLink' href='#cheatsheetModal' rel='leanModal'>" end_link="</a>" trimmed %}
Markdown syntax is allowed. See the {{ start_link }}cheatsheet{{ end_link }} for help.
{% endblocktrans %}
{% endfilter %}
</p>
<textarea {{ attrs }}>{{ content }}</textarea>

View File

@@ -1,7 +1,7 @@
{% extends "wiki/article.html" %}
{% load wiki_tags i18n humanize %}
{% block pagetitle %}{% trans "Attachments" %}: {{ article.current_revision.title }}{% endblock %}
{% block pagetitle %}{% trans "Attachments" as tmsg%}{{tmsg|force_escape}}: {{ article.current_revision.title }}{% endblock %}
{% block wiki_contents_tab %}
<div class="row-fluid">
@@ -10,20 +10,20 @@
<div class="attachment-options">
<a class="btn" href="#" id="upload-file-btn">
<span class="icon fa fa-arrow-circle-o-up"></span>{% trans "Upload new file" %}
<span class="icon fa fa-arrow-circle-o-up"></span>{% trans "Upload new file" as tmsg %}{{tmsg|force_escape}}
</a>
<a class="btn" href="#" id="search-for-file-btn">
<span class="icon fa fa-plus-circle"></span>{% trans "Search and add file" %}
<span class="icon fa fa-plus-circle"></span>{% trans "Search and add file" as tmsg %}{{tmsg|force_escape}}
</a>
</div>
<div class="modal upload-modal hide fade" id="upload-modal">
<div class="modal-inner-wrapper">
<h4>{% trans "Upload File" %}</h4>
<h4>{% trans "Upload File" as tmsg%}{{tmsg|force_escape}}</h4>
<form method="POST" class="form-vertical" id="attachment_form" enctype="multipart/form-data">
{% wiki_form form %}
<button type="submit" name="save" value="1" class="btn btn-primary">
{% trans "Upload file" %}
{% trans "Upload file" as tmsg%}{{tmsg|force_escape}}
</button>
</form>
</div>
@@ -31,12 +31,12 @@
<div class="modal search-file-modal hide fade" id="search-file-modal">
<div class="modal-inner-wrapper">
<h4>{% trans "Search files and articles" %}</h4>
<p>{% trans "You can reuse files from other articles. These files are subject to updates on other articles which may or may not be a good thing." %}</p>
<h4>{% trans "Search files and articles" as tmsg%}{{tmsg|force_escape}}</h4>
<p>{% trans "You can reuse files from other articles. These files are subject to updates on other articles which may or may not be a good thing." as tmsg%}{{tmsg|force_escape}}</p>
<form method="GET" action="{% url 'wiki:attachments_search' path=urlpath.path article_id=article.id %}" class="form-search">
{{ search_form.query }}
<button class="btn btn-primary">
{% trans "Search" %}
{% trans "Search" as tmsg%}{{tmsg|force_escape}}
</button>
</form>
</div>
@@ -70,7 +70,7 @@
<a href="{% url 'wiki:attachments_download' path=urlpath.path article_id=article.id attachment_id=attachment.id %}">{{ attachment.current_revision.get_filename }}</a>
<span class="badge">{{ attachment.current_revision.created|naturaltime }}</span>
{% if attachment.current_revision.deleted %}
<span class="badge badge-important">{% trans "deleted" %}</span>
<span class="badge badge-important">{% trans "deleted" as tmsg%}{{tmsg|force_escape}}</span>
{% endif %}
</h3>
<p class="attachment-description">
@@ -80,27 +80,27 @@
<div class="attachment-details">
<table>
<tr>
<th>{% trans "Markdown tag" %}</th>
<th>{% trans "Uploaded by" %}</th>
<th>{% trans "Size" %}</th>
<th>{% trans "File History" %}</th>
<th>{% trans "Markdown tag" as tmsg %}{{tmsg|force_escape}}</th>
<th>{% trans "Uploaded by" as tmsg%}{{tmsg|force_escape}}</th>
<th>{% trans "Size" as tmsg%}{{tmsg|force_escape}}</th>
<th>{% trans "File History" as tmsg%}{{tmsg|force_escape}}</th>
<td class="attachment-actions">
{% if attachment|can_write:user %}
{% if not attachment.current_revision.deleted %}
{% if attachment.article == article %}
<a href="{% url 'wiki:attachments_delete' path=urlpath.path article_id=article.id attachment_id=attachment.id %}" class="btn btn-danger">{% trans "Delete" %}</a>
<a href="{% url 'wiki:attachments_delete' path=urlpath.path article_id=article.id attachment_id=attachment.id %}" class="btn btn-danger">{% trans "Delete" as tmsg %}{{tmsg|force_escape}}</a>
{% else %}
<a href="{% url 'wiki:attachments_delete' path=urlpath.path article_id=article.id attachment_id=attachment.id %}" class="btn">{% trans "Detach" %}</a>
<a href="{% url 'wiki:attachments_delete' path=urlpath.path article_id=article.id attachment_id=attachment.id %}" class="btn">{% trans "Detach" as tmsg %}{{tmsg|force_escape}}</a>
{% endif %}
<a href="{% url 'wiki:attachments_replace' path=urlpath.path article_id=article.id attachment_id=attachment.id %}" class="btn">{% trans "Replace" %}</a>
<a href="{% url 'wiki:attachments_replace' path=urlpath.path article_id=article.id attachment_id=attachment.id %}" class="btn">{% trans "Replace" as tmsg %}{{tmsg|force_escape}}</a>
{% else %}
{% if attachment.current_revision.previous_revision.id %}
<form method="POST" action="{% url 'wiki:attachments_revision_change' path=urlpath.path article_id=article.id attachment_id=attachment.id revision_id=attachment.current_revision.previous_revision.id %}">
{% csrf_token %}
<button class="btn">
{% trans "Restore" %}
{% trans "Restore" as tmsg %}{{tmsg|force_escape}}
</button>
</form>
{% endif %}
@@ -111,14 +111,14 @@
<tr>
<td><code>[attachment:{{ attachment.id }}]</code></td>
<td>
{% if attachment.current_revision.user %}{{ attachment.current_revision.user }}{% else %}{% if user|is_moderator %}{{ attachment.current_revision.ip_address|default:"anonymous (IP not logged)" }}{% else %}{% trans "anonymous (IP logged)" %}{% endif %}{% endif %}
{% if attachment.current_revision.user %}{{ attachment.current_revision.user }}{% else %}{% if user|is_moderator %}{{ attachment.current_revision.ip_address|default:"anonymous (IP not logged)" }}{% else %}{% trans "anonymous (IP logged)" as tmsg%}{{tmsg|force_escape}}{% endif %}{% endif %}
</td>
<td>{{ attachment.current_revision.get_size|filesizeformat }}</td>
<td>
<a href="{% url 'wiki:attachments_history' path=urlpath.path article_id=article.id attachment_id=attachment.id %}">
<span class="icon fa fa-clock-o"></span>
{% trans "File history" %} ({{ attachment.attachmentrevision_set.all.count }} {% trans "revisions" %})
{% trans "File history" as tmsg%}{{tmsg|force_escape}} ({{ attachment.attachmentrevision_set.all.count }} {% trans "revisions" as tmsg %}{{tmsg|force_escape}})
</a>
</td>
</tr>
@@ -126,7 +126,7 @@
</div>
</li>
{% empty %}
<p style="margin-bottom: 20px;"><em>{% trans "There are no attachments for this article." %}</em></p>
<p style="margin-bottom: 20px;"><em>{% trans "There are no attachments for this article." as tmsg %}{{tmsg|force_escape}}</em></p>
{% endfor %}
</ul>
</div>

View File

@@ -10,14 +10,14 @@
<div class="main-article">
{% if revision %}
<div class="alert alert-info">
<strong>{% trans "Previewing revision:" %}</strong>
<strong>{% trans "Previewing revision:" as tmsg%}{{tmsg|force_escape}}</strong>
{% include "wiki/includes/revision_info.html" %}
</div>
{% endif %}
{% if merge %}
<div class="alert alert-info">
<strong>{% trans "Previewing a merge between two revisions:" %}</strong>
<strong>{% trans "Previewing a merge between two revisions:" as tmsg%}{{tmsg|force_escape}}</strong>
<ol>
<li>{% include "wiki/includes/revision_info.html" with revision=merge1 %}</li>
<li>{% include "wiki/includes/revision_info.html" with revision=merge2 %}</li>
@@ -29,22 +29,22 @@
{% if revision and revision.deleted %}
<div class="warning">
<strong>{% trans "This revision has been deleted." %}</strong>
<p>{% trans "Restoring to this revision will mark the article as deleted." %}</p>
<strong>{% trans "This revision has been deleted." as tmsg %}{{tmsg|force_escape}}</strong>
<p>{% trans "Restoring to this revision will mark the article as deleted." as tmsg %}{{tmsg|force_escape}}</p>
</div>
{% else %}
{% wiki_render article content %}
{% endif %}
</div>
</section>
{% javascript 'application' %}
{% javascript 'module-js' %}
{% with mathjax_mode='wiki' %}
{% include "mathjax_include.html" %}
{% endwith %}
</body>
</html>

View File

@@ -33,4 +33,4 @@
padding-bottom: 20px;
}
}
</style>
</style>

View File

@@ -12,6 +12,7 @@ from django.conf import settings
from django.urls import reverse
from mock import patch
from openedx.core.djangolib.js_utils import js_escaped_string
from third_party_auth.tests.testutil import ThirdPartyAuthTestMixin
from util.testing import UrlResetMixin
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
@@ -225,7 +226,7 @@ class RegisterFormTest(ThirdPartyAuthTestMixin, UrlResetMixin, SharedModuleStore
# Verify that the parameters are sent on to the next page correctly
post_login_handler = _finish_auth_url(params)
js_success_var = u'var nextUrl = "{}";'.format(post_login_handler)
js_success_var = u'var nextUrl = "{}";'.format(js_escaped_string(post_login_handler))
self.assertContains(response, js_success_var)
# Verify that the login link preserves the querystring params

View File

@@ -1,18 +1,18 @@
{% load i18n %}
{% load static %}
<div class="content-paywall" role="group" aria-label="{% trans 'Content available only to verified track learners' %}">
<div class="content-paywall" role="group" aria-label="{% trans 'Content available only to verified track learners' as tmsg%}{{tmsg|force_escape}}">
<div>
<h3>
<span class="fa fa-lock" aria-hidden="true"></span>
{% trans "Verified Track Access" %}
{% trans "Verified Track Access" as tmsg%}{{tmsg|force_escape}}
</h3>
<span class="certSPAN_1">
{% trans "Graded assessments are available to Verified Track learners." %}
{% trans "Graded assessments are available to Verified Track learners." as tmsg %}{{tmsg|force_escape}}
</span>
{% if not mobile_app and ecommerce_checkout_link %}
<span class="certDIV_1" style="">
<a href="{{ecommerce_checkout_link}}" class="certA_1">
{% trans "Upgrade to unlock" %} ({{min_price}})
{% trans "Upgrade to unlock" as tmsg %}{{tmsg|force_escape}} ({{min_price}})
</a>
</span>
{% endif %}

View File

@@ -247,7 +247,7 @@ git+https://github.com/edx-solutions/xblock-drag-and-drop-v2@v2.2.1#egg=xblock-d
git+https://github.com/open-craft/xblock-poll@add89e14558c30f3c8dc7431e5cd6536fff6d941#egg=xblock-poll==1.5.1
xblock-utils==1.2.1
xblock==1.2.2
xmlsec==1.3.3 # via python3-saml
xss-utils==0.1.0
zendesk==1.1.1
# The following packages are considered to be unsafe in a requirements file:

View File

@@ -336,6 +336,7 @@ xblock-utils==1.2.1
xblock==1.2.2
xmlsec==1.3.3
xmltodict==0.12.0
xss-utils==0.1.0
zendesk==1.1.1
zipp==0.5.1

View File

@@ -322,6 +322,7 @@ xblock-utils==1.2.1
xblock==1.2.2
xmlsec==1.3.3
xmltodict==0.12.0 # via moto
xss-utils==0.1.0
zendesk==1.1.1
zipp==0.5.1 # via importlib-metadata