diff --git a/cms/templates/js/edit-textbook.underscore b/cms/templates/js/edit-textbook.underscore index 53ef8a1753d3594ddc53eddb22638a05e330559e..a9bfd2fd68ad0ca409cabecc57b5273914402148 100644 --- a/cms/templates/js/edit-textbook.underscore +++ b/cms/templates/js/edit-textbook.underscore @@ -15,7 +15,7 @@ </div> </fieldset> <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> <button class="action action-add-chapter"><i class="icon-plus"></i> <%= gettext("Add a Chapter") %></button> diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index ef9b80196fe6436a5ae8e9e93d9356c8464af84e..9b9dea4a4848443bdc4b0160f8f6eee4fc95c19d 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -1522,9 +1522,8 @@ def password_reset_confirm_wrapper( if PasswordHistory.is_password_reset_too_soon(user): num_days = settings.ADVANCED_SECURITY_CONFIG['MIN_TIME_IN_DAYS_BETWEEN_ALLOWED_RESETS'] 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, 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} day must elapse between password resets.", + "You are resetting passwords too frequently. Due to security policies, {num} days must elapse between password resets.", num_days ).format(num=num_days) diff --git a/common/static/js/src/jquery.timeago.locale.js b/common/static/js/src/jquery.timeago.locale.js index ad03e0a8a88f3ef78ee44746490fdd692a200f49..e8c5a98c1fefd0fde8b379d2096b1fb02fde7d15 100644 --- a/common/static/js/src/jquery.timeago.locale.js +++ b/common/static/js/src/jquery.timeago.locale.js @@ -1,5 +1,7 @@ jQuery.timeago.settings.strings = { + // Translators: %s will be a time quantity, such as "4 minutes" or "1 day" formatAgo: gettext("%s ago"), + // Translators: %s will be a time quantity, such as "4 minutes" or "1 day" formatFromNow: gettext("%s from now"), seconds: gettext("less than a minute"), minute: gettext("about a minute"), diff --git a/lms/djangoapps/dashboard/sysadmin.py b/lms/djangoapps/dashboard/sysadmin.py index 3bf3a0dae4d5dac040479573bdbf8e9b20e7494d..ce5193204e4272d566eabb2dce4535bfd1ef00e5 100644 --- a/lms/djangoapps/dashboard/sysadmin.py +++ b/lms/djangoapps/dashboard/sysadmin.py @@ -135,16 +135,25 @@ class Users(SysadminDashboardView): try: testuser = authenticate(username=euser.username, password=epass) except (TypeError, PermissionDenied, AttributeError), err: - msg += _('Failed in authenticating {0}, error {1}\n' - ).format(euser, err) + # 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}, error {error}\n').format( + username=euser, + error=err + ) continue 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') euser.set_password(epass) euser.save() continue if not msg: + # Translators: this means everything happened successfully, yay! msg = _('All ok!') return msg @@ -165,13 +174,16 @@ class Users(SysadminDashboardView): else: email = uname 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 mit_domain = 'ssl:MIT' if ExternalAuthMap.objects.filter(external_id=email, external_domain=mit_domain): - msg += _('Failed - email {0} already exists as ' - 'external_id').format(email) + msg += _('Failed - email {email_addr} already exists as {external_id}').format( + email_addr=email, + external_id="external_id" + ) return msg new_password = generate_password() else: @@ -190,8 +202,10 @@ class Users(SysadminDashboardView): try: user.save() except IntegrityError: - msg += _('Oops, failed to create user {0}, ' - 'IntegrityError').format(user) + msg += _('Oops, failed to create user {user}, {error}').format( + user=user, + error="IntegrityError" + ) return msg reg = Registration() @@ -217,7 +231,7 @@ class Users(SysadminDashboardView): eamap.dtsignup = timezone.now() eamap.save() - msg += _('User {0} created successfully!').format(user) + msg += _('User {user} created successfully!').format(user=user) return msg def delete_user(self, uname): @@ -229,17 +243,19 @@ class Users(SysadminDashboardView): try: user = User.objects.get(email=uname) 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 else: try: user = User.objects.get(username=uname) except User.DoesNotExist, err: - msg = _('Cannot find user with username {0} - {1}' - ).format(uname, str(err)) + msg = _('Cannot find user with username {username} - {error}').format( + username=uname, + error=str(err) + ) return msg user.delete() - return _('Deleted user {0}').format(uname) + return _('Deleted user {username}').format(username=uname) def make_common_context(self): """Returns the datatable used for this view""" @@ -252,7 +268,8 @@ class Users(SysadminDashboardView): User.objects.all().count()]] self.msg += u'<h2>{0}</h2>'.format( - _('Courses loaded in the modulestore')) + _('Courses loaded in the modulestore') + ) self.msg += u'<ol>' for course in self.get_courses(): self.msg += u'<li>{0} ({1})</li>'.format( @@ -418,6 +435,9 @@ class Courses(SysadminDashboardView): msg = u'' 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 ' 'not turned on, and it is generally not safe to import ' 'into an XMLModuleStore with multithreaded. We ' @@ -449,7 +469,7 @@ class Courses(SysadminDashboardView): msg += u'<pre>{0}</pre>'.format(cmd_output) 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 # Change branch if specified if branch: @@ -469,8 +489,9 @@ class Courses(SysadminDashboardView): msg += u'<hr width="50%"><pre>{0}</pre>'.format(escape(errlog)) else: course = self.def_ms.courses[os.path.abspath(gdir)] - msg += _('Loaded course {0} {1}<br/>Errors:').format( - cdir, course.display_name) + msg += _('Loaded course {course_name}<br/>Errors:').format( + course_name="{} {}".format(cdir, course.display_name) + ) errors = self.def_ms.get_course_errors(course.id) if not errors: msg += u'None' diff --git a/lms/djangoapps/instructor/views/instructor_dashboard.py b/lms/djangoapps/instructor/views/instructor_dashboard.py index 85e560ed62f54f7048412d8f81f23ef5f93b34f8..4293e60ea32a1c33bee61a5bf3011f4c0b1330a0 100644 --- a/lms/djangoapps/instructor/views/instructor_dashboard.py +++ b/lms/djangoapps/instructor/views/instructor_dashboard.py @@ -252,7 +252,7 @@ def _section_metrics(course_key, access): """Provide data for the corresponding dashboard section """ section_data = { 'section_key': 'metrics', - 'section_display_name': ('Metrics'), + 'section_display_name': _('Metrics'), 'access': access, 'course_id': course_key.to_deprecated_string(), 'sub_section_display_name': get_section_display_name(course_key), diff --git a/lms/static/coffee/src/instructor_dashboard/analytics.coffee b/lms/static/coffee/src/instructor_dashboard/analytics.coffee index 3736624540977c73ea40d4cf79e86dcd7f222c08..86d7dec1ff3f3be72eb4df6a9c675cb2fc7e0c3b 100644 --- a/lms/static/coffee/src/instructor_dashboard/analytics.coffee +++ b/lms/static/coffee/src/instructor_dashboard/analytics.coffee @@ -34,7 +34,9 @@ class ProfileDistributionWidget @reset_display() @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) => feature_res = data.feature_results if feature_res.type is 'EASY_CHOICE' diff --git a/lms/static/coffee/src/instructor_dashboard/membership.coffee b/lms/static/coffee/src/instructor_dashboard/membership.coffee index 3735f37ebcab029d90574d705149f795c466bd20..08f951a4aedc57d106a8127bc7ebfeb44f2d4bac 100644 --- a/lms/static/coffee/src/instructor_dashboard/membership.coffee +++ b/lms/static/coffee/src/instructor_dashboard/membership.coffee @@ -142,7 +142,7 @@ class AuthListWidget extends MemberListWidget data: rolename: @rolename success: (data) => cb? null, data[@rolename] 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}'" # send ajax request to modify access @@ -453,7 +453,7 @@ class BatchEnrollment (sr.identifier for sr in notenrolled) 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:"), (sr.identifier for sr in notunenrolled) diff --git a/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html b/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html index 3956a3e15fe6475b3a65865162196050c403490e..ecd2840f4f537813fb18cdd36866cf0ee0e389d7 100644 --- a/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html +++ b/lms/templates/instructor/instructor_dashboard_2/instructor_dashboard_2.html @@ -81,7 +81,9 @@ ## when the javascript loads, it clicks on the first section <ul class="instructor-nav"> % 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 </ul> diff --git a/lms/templates/shoppingcart/receipt.html b/lms/templates/shoppingcart/receipt.html index 1fdebeba241f759a65d5a46c9fb4ce0163d8d047..4ff99a9f7e12582e1547844cc9485cb6313645cf 100644 --- a/lms/templates/shoppingcart/receipt.html +++ b/lms/templates/shoppingcart/receipt.html @@ -72,7 +72,8 @@ % if any_refunds: <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> % endif diff --git a/lms/templates/shoppingcart/verified_cert_receipt.html b/lms/templates/shoppingcart/verified_cert_receipt.html index 44239622b50e059733236e5d27e996ebec549630..85b36aa231ccb12ad63abebccf2483a4503b4fcf 100644 --- a/lms/templates/shoppingcart/verified_cert_receipt.html +++ b/lms/templates/shoppingcart/verified_cert_receipt.html @@ -191,7 +191,8 @@ <div class="msg msg-refunds"> <h4 class="title sr">Please Note:</h4> <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> % endif diff --git a/lms/templates/video.html b/lms/templates/video.html index 979b7d85b06612e755ab8c460f919153f443a58b..0d52158b94947fc3a3f0ed969f7044eafab33199 100644 --- a/lms/templates/video.html +++ b/lms/templates/video.html @@ -122,6 +122,7 @@ % else: <li class="a11y-menu-item"> % endif + ## This is necessary so we don't scrape 'display_name' as a string. <% dname = item['display_name'] %> <a class="a11y-menu-item-link" href="#${item['value']}" title="${_(dname)}" data-value="${item['value']}"> ${_(dname)}