Commit 4477c285 by Sarina Canelake

Merge pull request #4156 from edx/sarina/fix-i18n-bugs

Fix variable names to give context for translators
parents d3d45b88 30c8da15
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
</div> </div>
</fieldset> </fieldset>
<fieldset class="chapters-fields"> <fieldset class="chapters-fields">
<legend class="sr"><%= gettext("Chapter(s) information") %></legend> <legend class="sr"><%= gettext("Chapter information") %></legend>
<ol class="chapters list-input enum"></ol> <ol class="chapters list-input enum"></ol>
<button class="action action-add-chapter"><i class="icon-plus"></i> <%= gettext("Add a Chapter") %></button> <button class="action action-add-chapter"><i class="icon-plus"></i> <%= gettext("Add a Chapter") %></button>
......
...@@ -1522,9 +1522,8 @@ def password_reset_confirm_wrapper( ...@@ -1522,9 +1522,8 @@ def password_reset_confirm_wrapper(
if PasswordHistory.is_password_reset_too_soon(user): if PasswordHistory.is_password_reset_too_soon(user):
num_days = settings.ADVANCED_SECURITY_CONFIG['MIN_TIME_IN_DAYS_BETWEEN_ALLOWED_RESETS'] num_days = settings.ADVANCED_SECURITY_CONFIG['MIN_TIME_IN_DAYS_BETWEEN_ALLOWED_RESETS']
err_msg = ungettext( err_msg = ungettext(
# Translators: If you need to use a variable number instead of the number "one", use {num} in its place. "You are resetting passwords too frequently. Due to security policies, {num} day must elapse between password resets.",
"You are resetting passwords too frequently. Due to security policies, one day must elapse between password resets", "You are resetting passwords too frequently. Due to security policies, {num} days must elapse between password resets.",
"You are resetting passwords too frequently. Due to security policies, {num} days must elapse between password resets",
num_days num_days
).format(num=num_days) ).format(num=num_days)
......
jQuery.timeago.settings.strings = { jQuery.timeago.settings.strings = {
// Translators: %s will be a time quantity, such as "4 minutes" or "1 day"
formatAgo: gettext("%s ago"), formatAgo: gettext("%s ago"),
// Translators: %s will be a time quantity, such as "4 minutes" or "1 day"
formatFromNow: gettext("%s from now"), formatFromNow: gettext("%s from now"),
seconds: gettext("less than a minute"), seconds: gettext("less than a minute"),
minute: gettext("about a minute"), minute: gettext("about a minute"),
......
...@@ -135,16 +135,25 @@ class Users(SysadminDashboardView): ...@@ -135,16 +135,25 @@ class Users(SysadminDashboardView):
try: try:
testuser = authenticate(username=euser.username, password=epass) testuser = authenticate(username=euser.username, password=epass)
except (TypeError, PermissionDenied, AttributeError), err: except (TypeError, PermissionDenied, AttributeError), err:
msg += _('Failed in authenticating {0}, error {1}\n' # Translators: This message means that the user could not be authenticated (that is, we could
).format(euser, err) # not log them in for some reason - maybe they don't have permission, or their password was wrong)
msg += _('Failed in authenticating {username}, error {error}\n').format(
username=euser,
error=err
)
continue continue
if testuser is None: if testuser is None:
msg += _('Failed in authenticating {0}\n').format(euser) # Translators: This message means that the user could not be authenticated (that is, we could
# not log them in for some reason - maybe they don't have permission, or their password was wrong)
msg += _('Failed in authenticating {username}\n').format(username=euser)
# Translators: this means that the password has been corrected (sometimes the database needs to be resynchronized)
# Translate this as meaning "the password was fixed" or "the password was corrected".
msg += _('fixed password') msg += _('fixed password')
euser.set_password(epass) euser.set_password(epass)
euser.save() euser.save()
continue continue
if not msg: if not msg:
# Translators: this means everything happened successfully, yay!
msg = _('All ok!') msg = _('All ok!')
return msg return msg
...@@ -165,13 +174,16 @@ class Users(SysadminDashboardView): ...@@ -165,13 +174,16 @@ class Users(SysadminDashboardView):
else: else:
email = uname email = uname
if not email.endswith('@{0}'.format(email_domain)): if not email.endswith('@{0}'.format(email_domain)):
msg += u'{0} @{1}'.format(_('email must end in'), email_domain) # Translators: Domain is an email domain, such as "@gmail.com"
msg += _('Email address must end in {domain}').format(domain="@{0}".format(email_domain))
return msg return msg
mit_domain = 'ssl:MIT' mit_domain = 'ssl:MIT'
if ExternalAuthMap.objects.filter(external_id=email, if ExternalAuthMap.objects.filter(external_id=email,
external_domain=mit_domain): external_domain=mit_domain):
msg += _('Failed - email {0} already exists as ' msg += _('Failed - email {email_addr} already exists as {external_id}').format(
'external_id').format(email) email_addr=email,
external_id="external_id"
)
return msg return msg
new_password = generate_password() new_password = generate_password()
else: else:
...@@ -190,8 +202,10 @@ class Users(SysadminDashboardView): ...@@ -190,8 +202,10 @@ class Users(SysadminDashboardView):
try: try:
user.save() user.save()
except IntegrityError: except IntegrityError:
msg += _('Oops, failed to create user {0}, ' msg += _('Oops, failed to create user {user}, {error}').format(
'IntegrityError').format(user) user=user,
error="IntegrityError"
)
return msg return msg
reg = Registration() reg = Registration()
...@@ -217,7 +231,7 @@ class Users(SysadminDashboardView): ...@@ -217,7 +231,7 @@ class Users(SysadminDashboardView):
eamap.dtsignup = timezone.now() eamap.dtsignup = timezone.now()
eamap.save() eamap.save()
msg += _('User {0} created successfully!').format(user) msg += _('User {user} created successfully!').format(user=user)
return msg return msg
def delete_user(self, uname): def delete_user(self, uname):
...@@ -229,17 +243,19 @@ class Users(SysadminDashboardView): ...@@ -229,17 +243,19 @@ class Users(SysadminDashboardView):
try: try:
user = User.objects.get(email=uname) user = User.objects.get(email=uname)
except User.DoesNotExist, err: except User.DoesNotExist, err:
msg = _('Cannot find user with email address {0}').format(uname) msg = _('Cannot find user with email address {email_addr}').format(email_addr=uname)
return msg return msg
else: else:
try: try:
user = User.objects.get(username=uname) user = User.objects.get(username=uname)
except User.DoesNotExist, err: except User.DoesNotExist, err:
msg = _('Cannot find user with username {0} - {1}' msg = _('Cannot find user with username {username} - {error}').format(
).format(uname, str(err)) username=uname,
error=str(err)
)
return msg return msg
user.delete() user.delete()
return _('Deleted user {0}').format(uname) return _('Deleted user {username}').format(username=uname)
def make_common_context(self): def make_common_context(self):
"""Returns the datatable used for this view""" """Returns the datatable used for this view"""
...@@ -252,7 +268,8 @@ class Users(SysadminDashboardView): ...@@ -252,7 +268,8 @@ class Users(SysadminDashboardView):
User.objects.all().count()]] User.objects.all().count()]]
self.msg += u'<h2>{0}</h2>'.format( self.msg += u'<h2>{0}</h2>'.format(
_('Courses loaded in the modulestore')) _('Courses loaded in the modulestore')
)
self.msg += u'<ol>' self.msg += u'<ol>'
for course in self.get_courses(): for course in self.get_courses():
self.msg += u'<li>{0} ({1})</li>'.format( self.msg += u'<li>{0} ({1})</li>'.format(
...@@ -418,6 +435,9 @@ class Courses(SysadminDashboardView): ...@@ -418,6 +435,9 @@ class Courses(SysadminDashboardView):
msg = u'' msg = u''
if not getattr(settings, 'GIT_IMPORT_WITH_XMLMODULESTORE', False): if not getattr(settings, 'GIT_IMPORT_WITH_XMLMODULESTORE', False):
# Translators: "GIT_IMPORT_WITH_XMLMODULESTORE" is a variable name.
# "XMLModuleStore" and "MongoDB" are database systems. You should not
# translate these names.
return _('Refusing to import. GIT_IMPORT_WITH_XMLMODULESTORE is ' return _('Refusing to import. GIT_IMPORT_WITH_XMLMODULESTORE is '
'not turned on, and it is generally not safe to import ' 'not turned on, and it is generally not safe to import '
'into an XMLModuleStore with multithreaded. We ' 'into an XMLModuleStore with multithreaded. We '
...@@ -449,7 +469,7 @@ class Courses(SysadminDashboardView): ...@@ -449,7 +469,7 @@ class Courses(SysadminDashboardView):
msg += u'<pre>{0}</pre>'.format(cmd_output) msg += u'<pre>{0}</pre>'.format(cmd_output)
if not os.path.exists(gdir): if not os.path.exists(gdir):
msg += _('Failed to clone repository to {0}').format(gdir) msg += _('Failed to clone repository to {directory_name}').format(directory_name=gdir)
return msg return msg
# Change branch if specified # Change branch if specified
if branch: if branch:
...@@ -469,8 +489,9 @@ class Courses(SysadminDashboardView): ...@@ -469,8 +489,9 @@ class Courses(SysadminDashboardView):
msg += u'<hr width="50%"><pre>{0}</pre>'.format(escape(errlog)) msg += u'<hr width="50%"><pre>{0}</pre>'.format(escape(errlog))
else: else:
course = self.def_ms.courses[os.path.abspath(gdir)] course = self.def_ms.courses[os.path.abspath(gdir)]
msg += _('Loaded course {0} {1}<br/>Errors:').format( msg += _('Loaded course {course_name}<br/>Errors:').format(
cdir, course.display_name) course_name="{} {}".format(cdir, course.display_name)
)
errors = self.def_ms.get_course_errors(course.id) errors = self.def_ms.get_course_errors(course.id)
if not errors: if not errors:
msg += u'None' msg += u'None'
......
...@@ -252,7 +252,7 @@ def _section_metrics(course_key, access): ...@@ -252,7 +252,7 @@ def _section_metrics(course_key, access):
"""Provide data for the corresponding dashboard section """ """Provide data for the corresponding dashboard section """
section_data = { section_data = {
'section_key': 'metrics', 'section_key': 'metrics',
'section_display_name': ('Metrics'), 'section_display_name': _('Metrics'),
'access': access, 'access': access,
'course_id': course_key.to_deprecated_string(), 'course_id': course_key.to_deprecated_string(),
'sub_section_display_name': get_section_display_name(course_key), 'sub_section_display_name': get_section_display_name(course_key),
......
...@@ -34,7 +34,9 @@ class ProfileDistributionWidget ...@@ -34,7 +34,9 @@ class ProfileDistributionWidget
@reset_display() @reset_display()
@get_profile_distributions @feature, @get_profile_distributions @feature,
error: std_ajax_err => @show_error gettext("Error fetching distribution.") error: std_ajax_err =>
`// Translators: "Distribution" refers to a grade distribution. This error message appears when there is an error getting the data on grade distribution.`
@show_error gettext("Error fetching distribution.")
success: (data) => success: (data) =>
feature_res = data.feature_results feature_res = data.feature_results
if feature_res.type is 'EASY_CHOICE' if feature_res.type is 'EASY_CHOICE'
......
...@@ -142,7 +142,7 @@ class AuthListWidget extends MemberListWidget ...@@ -142,7 +142,7 @@ class AuthListWidget extends MemberListWidget
data: rolename: @rolename data: rolename: @rolename
success: (data) => cb? null, data[@rolename] success: (data) => cb? null, data[@rolename]
error: std_ajax_err => error: std_ajax_err =>
`// Translators: A rolename appears this sentence.` `// Translators: A rolename appears this sentence. A rolename is something like "staff" or "beta tester".`
cb? gettext("Error fetching list for role") + " '#{@rolename}'" cb? gettext("Error fetching list for role") + " '#{@rolename}'"
# send ajax request to modify access # send ajax request to modify access
...@@ -453,7 +453,7 @@ class BatchEnrollment ...@@ -453,7 +453,7 @@ class BatchEnrollment
(sr.identifier for sr in notenrolled) (sr.identifier for sr in notenrolled)
if notunenrolled.length if notunenrolled.length
`// Translators: A list of users appears after this sentence` `// Translators: A list of users appears after this sentence. This situation arises when a staff member tries to unenroll a user who is not currently enrolled in this course.`
render_list gettext("These users were not affiliated with the course so could not be unenrolled:"), render_list gettext("These users were not affiliated with the course so could not be unenrolled:"),
(sr.identifier for sr in notunenrolled) (sr.identifier for sr in notunenrolled)
......
...@@ -81,7 +81,9 @@ ...@@ -81,7 +81,9 @@
## when the javascript loads, it clicks on the first section ## when the javascript loads, it clicks on the first section
<ul class="instructor-nav"> <ul class="instructor-nav">
% for section_data in sections: % for section_data in sections:
<li class="nav-item"><a href="" data-section="${ section_data['section_key'] }">${_(section_data['section_display_name'])}</a></li> ## This is necessary so we don't scrape 'section_display_name' as a string.
<% dname = section_data['section_display_name'] %>
<li class="nav-item"><a href="" data-section="${ section_data['section_key'] }">${_(dname)}</a></li>
% endfor % endfor
</ul> </ul>
......
...@@ -72,7 +72,8 @@ ...@@ -72,7 +72,8 @@
% if any_refunds: % if any_refunds:
<p> <p>
${_("Note: items with strikethough like ")}<del>this</del>${_(" have been refunded.")} ## Translators: Please keep the "<del>" and "</del>" tags around your translation of the word "this" in your translation.
${_("Note: items with strikethough like <del>this</del> have been refunded.")}
</p> </p>
% endif % endif
......
...@@ -191,7 +191,8 @@ ...@@ -191,7 +191,8 @@
<div class="msg msg-refunds"> <div class="msg msg-refunds">
<h4 class="title sr">Please Note:</h4> <h4 class="title sr">Please Note:</h4>
<div class="copy"> <div class="copy">
<p>${_("Note: items with strikethough like ")}<del>${_("this")}</del>${_(" have been refunded.")}</p> ## Translators: Please keep the "<del>" and "</del>" tags around your translation of the word "this" in your translation.
<p>${_("Note: items with strikethough like <del>this</del> have been refunded.")}</p>
</div> </div>
</div> </div>
% endif % endif
......
...@@ -122,6 +122,7 @@ ...@@ -122,6 +122,7 @@
% else: % else:
<li class="a11y-menu-item"> <li class="a11y-menu-item">
% endif % endif
## This is necessary so we don't scrape 'display_name' as a string.
<% dname = item['display_name'] %> <% dname = item['display_name'] %>
<a class="a11y-menu-item-link" href="#${item['value']}" title="${_(dname)}" data-value="${item['value']}"> <a class="a11y-menu-item-link" href="#${item['value']}" title="${_(dname)}" data-value="${item['value']}">
${_(dname)} ${_(dname)}
......
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