Commit a6bae4d2 by louyihua

i18n: Make static strings in xmodule files extractable

They can now be extracted.
parent afe30643
...@@ -10,9 +10,12 @@ import textwrap ...@@ -10,9 +10,12 @@ import textwrap
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
class AnnotatableFields(object): class AnnotatableFields(object):
data = String(help="XML data for the annotation", scope=Scope.content, data = String(help=_("XML data for the annotation"), scope=Scope.content,
default=textwrap.dedent( default=textwrap.dedent(
"""\ """\
<annotatable> <annotatable>
...@@ -32,8 +35,8 @@ class AnnotatableFields(object): ...@@ -32,8 +35,8 @@ class AnnotatableFields(object):
</annotatable> </annotatable>
""")) """))
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="Display name for this module", help=_("Display name for this module"),
scope=Scope.settings, scope=Scope.settings,
default='Annotation', default='Annotation',
) )
......
...@@ -32,6 +32,9 @@ from .util.duedate import get_extended_due_date ...@@ -32,6 +32,9 @@ from .util.duedate import get_extended_due_date
log = logging.getLogger("edx.courseware") log = logging.getLogger("edx.courseware")
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
# Generate this many different variants of problems with rerandomize=per_student # Generate this many different variants of problems with rerandomize=per_student
NUM_RANDOMIZATION_BINS = 20 NUM_RANDOMIZATION_BINS = 20
...@@ -86,101 +89,103 @@ class CapaFields(object): ...@@ -86,101 +89,103 @@ class CapaFields(object):
Define the possible fields for a Capa problem Define the possible fields for a Capa problem
""" """
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="This name appears in the horizontal navigation at the top of the page.", help=_("This name appears in the horizontal navigation at the top of the page."),
scope=Scope.settings, scope=Scope.settings,
# it'd be nice to have a useful default but it screws up other things; so, # it'd be nice to have a useful default but it screws up other things; so,
# use display_name_with_default for those # use display_name_with_default for those
default="Blank Advanced Problem" default="Blank Advanced Problem"
) )
attempts = Integer(help="Number of attempts taken by the student on this problem", attempts = Integer(
default=0, scope=Scope.user_state) help=_("Number of attempts taken by the student on this problem"),
default=0,
scope=Scope.user_state)
max_attempts = Integer( max_attempts = Integer(
display_name="Maximum Attempts", display_name=_("Maximum Attempts"),
help=("Defines the number of times a student can try to answer this problem. " help=_("Defines the number of times a student can try to answer this problem. "
"If the value is not set, infinite attempts are allowed."), "If the value is not set, infinite attempts are allowed."),
values={"min": 0}, scope=Scope.settings values={"min": 0}, scope=Scope.settings
) )
due = Date(help="Date that this problem is due by", scope=Scope.settings) due = Date(help=_("Date that this problem is due by"), scope=Scope.settings)
extended_due = Date( extended_due = Date(
help="Date that this problem is due by for a particular student. This " help=_("Date that this problem is due by for a particular student. This "
"can be set by an instructor, and will override the global due " "can be set by an instructor, and will override the global due "
"date if it is set to a date that is later than the global due " "date if it is set to a date that is later than the global due "
"date.", "date."),
default=None, default=None,
scope=Scope.user_state, scope=Scope.user_state,
) )
graceperiod = Timedelta( graceperiod = Timedelta(
help="Amount of time after the due date that submissions will be accepted", help=_("Amount of time after the due date that submissions will be accepted"),
scope=Scope.settings scope=Scope.settings
) )
showanswer = String( showanswer = String(
display_name="Show Answer", display_name=_("Show Answer"),
help=("Defines when to show the answer to the problem. " help=_("Defines when to show the answer to the problem. "
"A default value can be set in Advanced Settings."), "A default value can be set in Advanced Settings."),
scope=Scope.settings, scope=Scope.settings,
default="finished", default="finished",
values=[ values=[
{"display_name": "Always", "value": "always"}, {"display_name": _("Always"), "value": "always"},
{"display_name": "Answered", "value": "answered"}, {"display_name": _("Answered"), "value": "answered"},
{"display_name": "Attempted", "value": "attempted"}, {"display_name": _("Attempted"), "value": "attempted"},
{"display_name": "Closed", "value": "closed"}, {"display_name": _("Closed"), "value": "closed"},
{"display_name": "Finished", "value": "finished"}, {"display_name": _("Finished"), "value": "finished"},
{"display_name": "Past Due", "value": "past_due"}, {"display_name": _("Past Due"), "value": "past_due"},
{"display_name": "Never", "value": "never"}] {"display_name": _("Never"), "value": "never"}]
) )
force_save_button = Boolean( force_save_button = Boolean(
help="Whether to force the save button to appear on the page", help=_("Whether to force the save button to appear on the page"),
scope=Scope.settings, scope=Scope.settings,
default=False default=False
) )
rerandomize = Randomization( rerandomize = Randomization(
display_name="Randomization", display_name=_("Randomization"),
help="Defines how often inputs are randomized when a student loads the problem. " help=_("Defines how often inputs are randomized when a student loads the problem. "
"This setting only applies to problems that can have randomly generated numeric values. " "This setting only applies to problems that can have randomly generated numeric values. "
"A default value can be set in Advanced Settings.", "A default value can be set in Advanced Settings."),
default="never", default="never",
scope=Scope.settings, scope=Scope.settings,
values=[ values=[
{"display_name": "Always", "value": "always"}, {"display_name": _("Always"), "value": "always"},
{"display_name": "On Reset", "value": "onreset"}, {"display_name": _("On Reset"), "value": "onreset"},
{"display_name": "Never", "value": "never"}, {"display_name": _("Never"), "value": "never"},
{"display_name": "Per Student", "value": "per_student"} {"display_name": _("Per Student"), "value": "per_student"}
] ]
) )
data = String(help="XML data for the problem", scope=Scope.content, default="<problem></problem>") data = String(help=_("XML data for the problem"), scope=Scope.content, default="<problem></problem>")
correct_map = Dict(help="Dictionary with the correctness of current student answers", correct_map = Dict(help=_("Dictionary with the correctness of current student answers"),
scope=Scope.user_state, default={}) scope=Scope.user_state, default={})
input_state = Dict(help="Dictionary for maintaining the state of inputtypes", scope=Scope.user_state) input_state = Dict(help=_("Dictionary for maintaining the state of inputtypes"), scope=Scope.user_state)
student_answers = Dict(help="Dictionary with the current student responses", scope=Scope.user_state) student_answers = Dict(help=_("Dictionary with the current student responses"), scope=Scope.user_state)
done = Boolean(help="Whether the student has answered the problem", scope=Scope.user_state) done = Boolean(help=_("Whether the student has answered the problem"), scope=Scope.user_state)
seed = Integer(help="Random seed for this student", scope=Scope.user_state) seed = Integer(help=_("Random seed for this student"), scope=Scope.user_state)
last_submission_time = Date(help="Last submission time", scope=Scope.user_state) last_submission_time = Date(help=_("Last submission time"), scope=Scope.user_state)
submission_wait_seconds = Integer( submission_wait_seconds = Integer(
display_name="Timer Between Attempts", display_name=_("Timer Between Attempts"),
help="Seconds a student must wait between submissions for a problem with multiple attempts.", help=_("Seconds a student must wait between submissions for a problem with multiple attempts."),
scope=Scope.settings, scope=Scope.settings,
default=0) default=0)
weight = Float( weight = Float(
display_name="Problem Weight", display_name=_("Problem Weight"),
help=("Defines the number of points each problem is worth. " help=_("Defines the number of points each problem is worth. "
"If the value is not set, each response field in the problem is worth one point."), "If the value is not set, each response field in the problem is worth one point."),
values={"min": 0, "step": .1}, values={"min": 0, "step": .1},
scope=Scope.settings scope=Scope.settings
) )
markdown = String(help="Markdown source of this module", default=None, scope=Scope.settings) markdown = String(help=_("Markdown source of this module"), default=None, scope=Scope.settings)
source_code = String( source_code = String(
help="Source code for LaTeX and Word problems. This feature is not well-supported.", help=_("Source code for LaTeX and Word problems. This feature is not well-supported."),
scope=Scope.settings scope=Scope.settings
) )
text_customization = Dict( text_customization = Dict(
help="String customization substitutions for particular locations", help=_("String customization substitutions for particular locations"),
scope=Scope.settings scope=Scope.settings
# TODO: someday it should be possible to not duplicate this definition here # TODO: someday it should be possible to not duplicate this definition here
# and in inheritance.py # and in inheritance.py
) )
use_latex_compiler = Boolean( use_latex_compiler = Boolean(
help="Enable LaTeX templates?", help=_("Enable LaTeX templates?"),
default=False, default=False,
scope=Scope.settings scope=Scope.settings
) )
......
...@@ -13,6 +13,9 @@ import textwrap ...@@ -13,6 +13,9 @@ import textwrap
log = logging.getLogger("edx.courseware") log = logging.getLogger("edx.courseware")
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
V1_SETTINGS_ATTRIBUTES = [ V1_SETTINGS_ATTRIBUTES = [
"display_name", "display_name",
"max_attempts", "max_attempts",
...@@ -190,131 +193,136 @@ class VersionInteger(Integer): ...@@ -190,131 +193,136 @@ class VersionInteger(Integer):
class CombinedOpenEndedFields(object): class CombinedOpenEndedFields(object):
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="This name appears in the horizontal navigation at the top of the page.", help=_("This name appears in the horizontal navigation at the top of the page."),
default="Open Response Assessment", default="Open Response Assessment",
scope=Scope.settings scope=Scope.settings
) )
current_task_number = Integer( current_task_number = Integer(
help="Current task that the student is on.", help=_("Current task that the student is on."),
default=0, default=0,
scope=Scope.user_state scope=Scope.user_state
) )
old_task_states = List( old_task_states = List(
help=("A list of lists of state dictionaries for student states that are saved." help=_("A list of lists of state dictionaries for student states that are saved."
"This field is only populated if the instructor changes tasks after" "This field is only populated if the instructor changes tasks after"
"the module is created and students have attempted it (for example changes a self assessed problem to " "the module is created and students have attempted it (for example changes a self assessed problem to "
"self and peer assessed."), "self and peer assessed."),
scope = Scope.user_state scope = Scope.user_state
) )
task_states = List( task_states = List(
help="List of state dictionaries of each task within this module.", help=_("List of state dictionaries of each task within this module."),
scope=Scope.user_state scope=Scope.user_state
) )
state = String( state = String(
help="Which step within the current task that the student is on.", help=_("Which step within the current task that the student is on."),
default="initial", default="initial",
scope=Scope.user_state scope=Scope.user_state
) )
graded = Boolean( graded = Boolean(
display_name="Graded", display_name=_("Graded"),
help='Defines whether the student gets credit for this problem. Credit is based on peer grades of this problem.', help=_("Defines whether the student gets credit for this problem. Credit is based on peer grades of this problem."),
default=False, default=False,
scope=Scope.settings scope=Scope.settings
) )
student_attempts = Integer( student_attempts = Integer(
help="Number of attempts taken by the student on this problem", help=_("Number of attempts taken by the student on this problem"),
default=0, default=0,
scope=Scope.user_state scope=Scope.user_state
) )
ready_to_reset = Boolean( ready_to_reset = Boolean(
help="If the problem is ready to be reset or not.", help=_("If the problem is ready to be reset or not."),
default=False, default=False,
scope=Scope.user_state scope=Scope.user_state
) )
max_attempts = Integer( max_attempts = Integer(
display_name="Maximum Attempts", display_name=_("Maximum Attempts"),
help="The number of times the student can try to answer this problem.", help=_("The number of times the student can try to answer this problem."),
default=1, default=1,
scope=Scope.settings, scope=Scope.settings,
values={"min": 1 } values={"min": 1 }
) )
accept_file_upload = Boolean( accept_file_upload = Boolean(
display_name="Allow File Uploads", display_name=_("Allow File Uploads"),
help="Whether or not the student can submit files as a response.", help=_("Whether or not the student can submit files as a response."),
default=False, default=False,
scope=Scope.settings scope=Scope.settings
) )
skip_spelling_checks = Boolean( skip_spelling_checks = Boolean(
display_name="Disable Quality Filter", display_name=_("Disable Quality Filter"),
help="If False, the Quality Filter is enabled and submissions with poor spelling, short length, or poor grammar will not be peer reviewed.", help=_("If False, the Quality Filter is enabled and submissions with poor spelling, short length, or poor grammar will not be peer reviewed."),
default=False, default=False,
scope=Scope.settings scope=Scope.settings
) )
due = Date( due = Date(
help="Date that this problem is due by", help=_("Date that this problem is due by"),
scope=Scope.settings scope=Scope.settings
) )
extended_due = Date( extended_due = Date(
help="Date that this problem is due by for a particular student. This " help=_("Date that this problem is due by for a particular student. This "
"can be set by an instructor, and will override the global due " "can be set by an instructor, and will override the global due "
"date if it is set to a date that is later than the global due " "date if it is set to a date that is later than the global due "
"date.", "date."),
default=None, default=None,
scope=Scope.user_state, scope=Scope.user_state,
) )
graceperiod = Timedelta( graceperiod = Timedelta(
help="Amount of time after the due date that submissions will be accepted", help=_("Amount of time after the due date that submissions will be accepted"),
scope=Scope.settings scope=Scope.settings
) )
version = VersionInteger(help="Current version number", default=DEFAULT_VERSION, scope=Scope.settings) version = VersionInteger(
data = String(help="XML data for the problem", scope=Scope.content, help=_("Current version number"),
default=DEFAULT_VERSION,
scope=Scope.settings)
data = String(
help=_("XML data for the problem"),
scope=Scope.content,
default=DEFAULT_DATA) default=DEFAULT_DATA)
weight = Float( weight = Float(
display_name="Problem Weight", display_name=_("Problem Weight"),
help="Defines the number of points each problem is worth. If the value is not set, each problem is worth one point.", help=_("Defines the number of points each problem is worth. If the value is not set, each problem is worth one point."),
scope=Scope.settings, scope=Scope.settings,
values={"min": 0, "step": ".1"}, values={"min": 0, "step": ".1"},
default=1 default=1
) )
min_to_calibrate = Integer( min_to_calibrate = Integer(
display_name="Minimum Peer Grading Calibrations", display_name=_("Minimum Peer Grading Calibrations"),
help="The minimum number of calibration essays each student will need to complete for peer grading.", help=_("The minimum number of calibration essays each student will need to complete for peer grading."),
default=3, default=3,
scope=Scope.settings, scope=Scope.settings,
values={"min": 1, "max": 20, "step": "1"} values={"min": 1, "max": 20, "step": "1"}
) )
max_to_calibrate = Integer( max_to_calibrate = Integer(
display_name="Maximum Peer Grading Calibrations", display_name=_("Maximum Peer Grading Calibrations"),
help="The maximum number of calibration essays each student will need to complete for peer grading.", help=_("The maximum number of calibration essays each student will need to complete for peer grading."),
default=6, default=6,
scope=Scope.settings, scope=Scope.settings,
values={"min": 1, "max": 20, "step": "1"} values={"min": 1, "max": 20, "step": "1"}
) )
peer_grader_count = Integer( peer_grader_count = Integer(
display_name="Peer Graders per Response", display_name=_("Peer Graders per Response"),
help="The number of peers who will grade each submission.", help=_("The number of peers who will grade each submission."),
default=3, default=3,
scope=Scope.settings, scope=Scope.settings,
values={"min": 1, "step": "1", "max": 5} values={"min": 1, "step": "1", "max": 5}
) )
required_peer_grading = Integer( required_peer_grading = Integer(
display_name="Required Peer Grading", display_name=_("Required Peer Grading"),
help="The number of other students each student making a submission will have to grade.", help=_("The number of other students each student making a submission will have to grade."),
default=3, default=3,
scope=Scope.settings, scope=Scope.settings,
values={"min": 1, "step": "1", "max": 5} values={"min": 1, "step": "1", "max": 5}
) )
peer_grade_finished_submissions_when_none_pending = Boolean( peer_grade_finished_submissions_when_none_pending = Boolean(
display_name='Allow "overgrading" of peer submissions', display_name=_('Allow "overgrading" of peer submissions'),
help=("EXPERIMENTAL FEATURE. Allow students to peer grade submissions that already have the requisite number of graders, " help=_("EXPERIMENTAL FEATURE. Allow students to peer grade submissions that already have the requisite number of graders, "
"but ONLY WHEN all submissions they are eligible to grade already have enough graders. " "but ONLY WHEN all submissions they are eligible to grade already have enough graders. "
"This is intended for use when settings for `Required Peer Grading` > `Peer Graders per Response`"), "This is intended for use when settings for `Required Peer Grading` > `Peer Graders per Response`"),
default=False, default=False,
scope=Scope.settings, scope=Scope.settings,
) )
markdown = String( markdown = String(
help="Markdown source of this module", help=_("Markdown source of this module"),
default=textwrap.dedent("""\ default=textwrap.dedent("""\
[prompt] [prompt]
<h3>Censorship in the Libraries</h3> <h3>Censorship in the Libraries</h3>
......
...@@ -6,30 +6,33 @@ from xmodule.editing_module import MetadataOnlyEditingDescriptor ...@@ -6,30 +6,33 @@ from xmodule.editing_module import MetadataOnlyEditingDescriptor
from xblock.fields import String, Scope from xblock.fields import String, Scope
from uuid import uuid4 from uuid import uuid4
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
class DiscussionFields(object): class DiscussionFields(object):
discussion_id = String(scope=Scope.settings, default="$$GUID$$") discussion_id = String(scope=Scope.settings, default="$$GUID$$")
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="Display name for this module", help=_("Display name for this module"),
default="Discussion", default="Discussion",
scope=Scope.settings scope=Scope.settings
) )
data = String( data = String(
help="XML data for the problem", help=_("XML data for the problem"),
scope=Scope.content, scope=Scope.content,
default="<discussion></discussion>" default="<discussion></discussion>"
) )
discussion_category = String( discussion_category = String(
display_name="Category", display_name=_("Category"),
default="Week 1", default="Week 1",
help="A category name for the discussion. This name appears in the left pane of the discussion forum for the course.", help=_("A category name for the discussion. This name appears in the left pane of the discussion forum for the course."),
scope=Scope.settings scope=Scope.settings
) )
discussion_target = String( discussion_target = String(
display_name="Subcategory", display_name=_("Subcategory"),
default="Topic-Level Student-Visible Label", default="Topic-Level Student-Visible Label",
help="A subcategory name for the discussion. This name appears in the left pane of the discussion forum for the course.", help=_("A subcategory name for the discussion. This name appears in the left pane of the discussion forum for the course."),
scope=Scope.settings scope=Scope.settings
) )
sort_key = String(scope=Scope.settings) sort_key = String(scope=Scope.settings)
......
...@@ -19,26 +19,29 @@ from xblock.core import XBlock ...@@ -19,26 +19,29 @@ from xblock.core import XBlock
log = logging.getLogger("edx.courseware") log = logging.getLogger("edx.courseware")
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
class HtmlFields(object): class HtmlFields(object):
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="This name appears in the horizontal navigation at the top of the page.", help=_("This name appears in the horizontal navigation at the top of the page."),
scope=Scope.settings, scope=Scope.settings,
# it'd be nice to have a useful default but it screws up other things; so, # it'd be nice to have a useful default but it screws up other things; so,
# use display_name_with_default for those # use display_name_with_default for those
default="Text" default="Text"
) )
data = String(help="Html contents to display for this module", default=u"", scope=Scope.content) data = String(help=_("Html contents to display for this module"), default=u"", scope=Scope.content)
source_code = String(help="Source code for LaTeX documents. This feature is not well-supported.", scope=Scope.settings) source_code = String(help=_("Source code for LaTeX documents. This feature is not well-supported."), scope=Scope.settings)
use_latex_compiler = Boolean( use_latex_compiler = Boolean(
help="Enable LaTeX templates?", help=_("Enable LaTeX templates?"),
default=False, default=False,
scope=Scope.settings scope=Scope.settings
) )
editor = String( editor = String(
help="Select Visual to enter content and have the editor automatically create the HTML. Select Raw to edit HTML directly. If you change this setting, you must save the component and then re-open it for editing.", help=_("Select Visual to enter content and have the editor automatically create the HTML. Select Raw to edit HTML directly. If you change this setting, you must save the component and then re-open it for editing."),
display_name="Editor", display_name=_("Editor"),
default="visual", default="visual",
values=[ values=[
{"display_name": "Visual", "value": "visual"}, {"display_name": "Visual", "value": "visual"},
...@@ -234,12 +237,12 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor): ...@@ -234,12 +237,12 @@ class HtmlDescriptor(HtmlFields, XmlDescriptor, EditingDescriptor):
class AboutFields(object): class AboutFields(object):
display_name = String( display_name = String(
help="Display name for this module", help=_("Display name for this module"),
scope=Scope.settings, scope=Scope.settings,
default="overview", default="overview",
) )
data = String( data = String(
help="Html contents to display for this module", help=_("Html contents to display for this module"),
default=u"", default=u"",
scope=Scope.content scope=Scope.content
) )
...@@ -268,8 +271,8 @@ class StaticTabFields(object): ...@@ -268,8 +271,8 @@ class StaticTabFields(object):
The overrides for Static Tabs The overrides for Static Tabs
""" """
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="This name appears in the horizontal navigation at the top of the page.", help=_("This name appears in the horizontal navigation at the top of the page."),
scope=Scope.settings, scope=Scope.settings,
default="Empty", default="Empty",
) )
...@@ -278,7 +281,7 @@ class StaticTabFields(object): ...@@ -278,7 +281,7 @@ class StaticTabFields(object):
<p>Add the content you want students to see on this page.</p> <p>Add the content you want students to see on this page.</p>
"""), """),
scope=Scope.content, scope=Scope.content,
help="HTML for the additional pages" help=_("HTML for the additional pages")
) )
...@@ -305,12 +308,12 @@ class CourseInfoFields(object): ...@@ -305,12 +308,12 @@ class CourseInfoFields(object):
Field overrides Field overrides
""" """
items = List( items = List(
help="List of course update items", help=_("List of course update items"),
default=[], default=[],
scope=Scope.content scope=Scope.content
) )
data = String( data = String(
help="Html contents to display for this module", help=_("Html contents to display for this module"),
default=u"<ol></ol>", default=u"<ol></ol>",
scope=Scope.content scope=Scope.content
) )
......
...@@ -75,6 +75,9 @@ from xblock.fields import Boolean, Float ...@@ -75,6 +75,9 @@ from xblock.fields import Boolean, Float
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
DOCS_ANCHOR_TAG = ( DOCS_ANCHOR_TAG = (
"<a target='_blank'" "<a target='_blank'"
"href='http://edx.readthedocs.org/projects/ca/en/latest/exercises_tools/lti_component.html'>" "href='http://edx.readthedocs.org/projects/ca/en/latest/exercises_tools/lti_component.html'>"
...@@ -103,8 +106,8 @@ class LTIFields(object): ...@@ -103,8 +106,8 @@ class LTIFields(object):
https://github.com/idan/oauthlib/blob/master/oauthlib/oauth1/rfc5849/signature.py#L136 https://github.com/idan/oauthlib/blob/master/oauthlib/oauth1/rfc5849/signature.py#L136
""" """
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help=( help=_(
"Enter the name that students see for this component. " "Enter the name that students see for this component. "
"Analytics reports may also use the display name to identify this component." "Analytics reports may also use the display name to identify this component."
), ),
...@@ -112,8 +115,8 @@ class LTIFields(object): ...@@ -112,8 +115,8 @@ class LTIFields(object):
default="LTI", default="LTI",
) )
lti_id = String( lti_id = String(
display_name="LTI ID", display_name=_("LTI ID"),
help=( help=_(
"Enter the LTI ID for the external LTI provider. " "Enter the LTI ID for the external LTI provider. "
"This value must be the same LTI ID that you entered in the " "This value must be the same LTI ID that you entered in the "
"LTI Passports setting on the Advanced Settings page." "LTI Passports setting on the Advanced Settings page."
...@@ -123,8 +126,8 @@ class LTIFields(object): ...@@ -123,8 +126,8 @@ class LTIFields(object):
scope=Scope.settings scope=Scope.settings
) )
launch_url = String( launch_url = String(
display_name="LTI URL", display_name=_("LTI URL"),
help=( help=_(
"Enter the URL of the external tool that this component launches. " "Enter the URL of the external tool that this component launches. "
"This setting is only used when Hide External Tool is set to False." "This setting is only used when Hide External Tool is set to False."
"<br />See " + DOCS_ANCHOR_TAG + " for more details on this setting." "<br />See " + DOCS_ANCHOR_TAG + " for more details on this setting."
...@@ -132,16 +135,16 @@ class LTIFields(object): ...@@ -132,16 +135,16 @@ class LTIFields(object):
default='http://www.example.com', default='http://www.example.com',
scope=Scope.settings) scope=Scope.settings)
custom_parameters = List( custom_parameters = List(
display_name="Custom Parameters", display_name=_("Custom Parameters"),
help=( help=_(
"Add the key/value pair for any custom parameters, such as the page your e-book should open to or " "Add the key/value pair for any custom parameters, such as the page your e-book should open to or "
"the background color for this component." "the background color for this component."
"<br />See " + DOCS_ANCHOR_TAG + " for more details on this setting." "<br />See " + DOCS_ANCHOR_TAG + " for more details on this setting."
), ),
scope=Scope.settings) scope=Scope.settings)
open_in_a_new_page = Boolean( open_in_a_new_page = Boolean(
display_name="Open in New Page", display_name=_("Open in New Page"),
help=( help=_(
"Select True if you want students to click a link that opens the LTI tool in a new window. " "Select True if you want students to click a link that opens the LTI tool in a new window. "
"Select False if you want the LTI content to open in an IFrame in the current page. " "Select False if you want the LTI content to open in an IFrame in the current page. "
"This setting is only used when Hide External Tool is set to False. " "This setting is only used when Hide External Tool is set to False. "
...@@ -150,16 +153,16 @@ class LTIFields(object): ...@@ -150,16 +153,16 @@ class LTIFields(object):
scope=Scope.settings scope=Scope.settings
) )
has_score = Boolean( has_score = Boolean(
display_name="Scored", display_name=_("Scored"),
help=( help=_(
"Select True if this component will receive a numerical score from the external LTI system." "Select True if this component will receive a numerical score from the external LTI system."
), ),
default=False, default=False,
scope=Scope.settings scope=Scope.settings
) )
weight = Float( weight = Float(
display_name="Weight", display_name=_("Weight"),
help=( help=_(
"Enter the number of points possible for this component. " "Enter the number of points possible for this component. "
"The default value is 1.0. " "The default value is 1.0. "
"This setting is only used when Scored is set to True." "This setting is only used when Scored is set to True."
...@@ -169,18 +172,18 @@ class LTIFields(object): ...@@ -169,18 +172,18 @@ class LTIFields(object):
values={"min": 0}, values={"min": 0},
) )
module_score = Float( module_score = Float(
help="The score kept in the xblock KVS -- duplicate of the published score in django DB", help=_("The score kept in the xblock KVS -- duplicate of the published score in django DB"),
default=None, default=None,
scope=Scope.user_state scope=Scope.user_state
) )
score_comment = String( score_comment = String(
help="Comment as returned from grader, LTI2.0 spec", help=_("Comment as returned from grader, LTI2.0 spec"),
default="", default="",
scope=Scope.user_state scope=Scope.user_state
) )
hide_launch = Boolean( hide_launch = Boolean(
display_name="Hide External Tool", display_name=_("Hide External Tool"),
help=( help=_(
"Select True if you want to use this component as a placeholder for syncing with an external grading " "Select True if you want to use this component as a placeholder for syncing with an external grading "
"system rather than launch an external tool. " "system rather than launch an external tool. "
"This setting hides the Launch button and any IFrames for this component." "This setting hides the Launch button and any IFrames for this component."
......
...@@ -21,6 +21,9 @@ from django.utils.timezone import UTC ...@@ -21,6 +21,9 @@ from django.utils.timezone import UTC
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
EXTERNAL_GRADER_NO_CONTACT_ERROR = "Failed to contact external graders. Please notify course staff." EXTERNAL_GRADER_NO_CONTACT_ERROR = "Failed to contact external graders. Please notify course staff."
MAX_ALLOWED_FEEDBACK_LENGTH = 5000 MAX_ALLOWED_FEEDBACK_LENGTH = 5000
...@@ -28,57 +31,57 @@ MAX_ALLOWED_FEEDBACK_LENGTH = 5000 ...@@ -28,57 +31,57 @@ MAX_ALLOWED_FEEDBACK_LENGTH = 5000
class PeerGradingFields(object): class PeerGradingFields(object):
use_for_single_location = Boolean( use_for_single_location = Boolean(
display_name="Show Single Problem", display_name=_("Show Single Problem"),
help='When True, only the single problem specified by "Link to Problem Location" is shown. ' help=_('When True, only the single problem specified by "Link to Problem Location" is shown. '
'When False, a panel is displayed with all problems available for peer grading.', 'When False, a panel is displayed with all problems available for peer grading.'),
default=False, default=False,
scope=Scope.settings scope=Scope.settings
) )
link_to_location = Reference( link_to_location = Reference(
display_name="Link to Problem Location", display_name=_("Link to Problem Location"),
help='The location of the problem being graded. Only used when "Show Single Problem" is True.', help=_('The location of the problem being graded. Only used when "Show Single Problem" is True.'),
default="", default="",
scope=Scope.settings scope=Scope.settings
) )
graded = Boolean( graded = Boolean(
display_name="Graded", display_name=_("Graded"),
help='Defines whether the student gets credit for grading this problem. Only used when "Show Single Problem" is True.', help=_('Defines whether the student gets credit for grading this problem. Only used when "Show Single Problem" is True.'),
default=False, default=False,
scope=Scope.settings scope=Scope.settings
) )
due = Date( due = Date(
help="Due date that should be displayed.", help=_("Due date that should be displayed."),
scope=Scope.settings) scope=Scope.settings)
extended_due = Date( extended_due = Date(
help="Date that this problem is due by for a particular student. This " help=_("Date that this problem is due by for a particular student. This "
"can be set by an instructor, and will override the global due " "can be set by an instructor, and will override the global due "
"date if it is set to a date that is later than the global due " "date if it is set to a date that is later than the global due "
"date.", "date."),
default=None, default=None,
scope=Scope.user_state, scope=Scope.user_state,
) )
graceperiod = Timedelta( graceperiod = Timedelta(
help="Amount of grace to give on the due date.", help=_("Amount of grace to give on the due date."),
scope=Scope.settings scope=Scope.settings
) )
student_data_for_location = Dict( student_data_for_location = Dict(
help="Student data for a given peer grading problem.", help=_("Student data for a given peer grading problem."),
scope=Scope.user_state scope=Scope.user_state
) )
weight = Float( weight = Float(
display_name="Problem Weight", display_name=_("Problem Weight"),
help="Defines the number of points each problem is worth. If the value is not set, each problem is worth one point.", help=_("Defines the number of points each problem is worth. If the value is not set, each problem is worth one point."),
scope=Scope.settings, values={"min": 0, "step": ".1"}, scope=Scope.settings, values={"min": 0, "step": ".1"},
default=1 default=1
) )
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="Display name for this module", help=_("Display name for this module"),
scope=Scope.settings, scope=Scope.settings,
default="Peer Grading Interface" default="Peer Grading Interface"
) )
data = String( data = String(
help="Html contents to display for this module", help=_("Html contents to display for this module"),
default='<peergrading></peergrading>', default='<peergrading></peergrading>',
scope=Scope.content scope=Scope.content
) )
......
...@@ -10,10 +10,13 @@ from xmodule.annotator_token import retrieve_token ...@@ -10,10 +10,13 @@ from xmodule.annotator_token import retrieve_token
import textwrap import textwrap
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
class AnnotatableFields(object): class AnnotatableFields(object):
"""Fields for `TextModule` and `TextDescriptor`.""" """Fields for `TextModule` and `TextDescriptor`."""
data = String(help="XML data for the annotation", scope=Scope.content, default=textwrap.dedent("""\ data = String(help=_("XML data for the annotation"), scope=Scope.content, default=textwrap.dedent("""\
<annotatable> <annotatable>
<instructions> <instructions>
<p> <p>
...@@ -26,25 +29,25 @@ class AnnotatableFields(object): ...@@ -26,25 +29,25 @@ class AnnotatableFields(object):
</annotatable> </annotatable>
""")) """))
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="Display name for this module", help=_("Display name for this module"),
scope=Scope.settings, scope=Scope.settings,
default='Text Annotation', default='Text Annotation',
) )
instructor_tags = String( instructor_tags = String(
display_name="Tags for Assignments", display_name=_("Tags for Assignments"),
help="Add tags that automatically highlight in a certain color using the comma-separated form, i.e. imagery:red,parallelism:blue", help=_("Add tags that automatically highlight in a certain color using the comma-separated form, i.e. imagery:red,parallelism:blue"),
scope=Scope.settings, scope=Scope.settings,
default='imagery:red,parallelism:blue', default='imagery:red,parallelism:blue',
) )
source = String( source = String(
display_name="Source/Citation", display_name=_("Source/Citation"),
help="Optional for citing source of any material used. Automatic citation can be done using <a href=\"http://easybib.com\">EasyBib</a>", help=_("Optional for citing source of any material used. Automatic citation can be done using <a href=\"http://easybib.com\">EasyBib</a>"),
scope=Scope.settings, scope=Scope.settings,
default='None', default='None',
) )
annotation_storage_url = String(help="Location of Annotation backend", scope=Scope.settings, default="http://your_annotation_storage.com", display_name="Url for Annotation Storage") annotation_storage_url = String(help=_("Location of Annotation backend"), scope=Scope.settings, default="http://your_annotation_storage.com", display_name=_("Url for Annotation Storage"))
annotation_token_secret = String(help="Secret string for annotation storage", scope=Scope.settings, default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", display_name="Secret Token String for Annotation") annotation_token_secret = String(help=_("Secret string for annotation storage"), scope=Scope.settings, default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", display_name=_("Secret Token String for Annotation"))
class TextAnnotationModule(AnnotatableFields, XModule): class TextAnnotationModule(AnnotatableFields, XModule):
......
...@@ -11,10 +11,13 @@ from xmodule.annotator_token import retrieve_token ...@@ -11,10 +11,13 @@ from xmodule.annotator_token import retrieve_token
import textwrap import textwrap
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
class AnnotatableFields(object): class AnnotatableFields(object):
""" Fields for `VideoModule` and `VideoDescriptor`. """ """ Fields for `VideoModule` and `VideoDescriptor`. """
data = String(help="XML data for the annotation", scope=Scope.content, default=textwrap.dedent("""\ data = String(help=_("XML data for the annotation"), scope=Scope.content, default=textwrap.dedent("""\
<annotatable> <annotatable>
<instructions> <instructions>
<p> <p>
...@@ -24,15 +27,15 @@ class AnnotatableFields(object): ...@@ -24,15 +27,15 @@ class AnnotatableFields(object):
</annotatable> </annotatable>
""")) """))
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="Display name for this module", help=_("Display name for this module"),
scope=Scope.settings, scope=Scope.settings,
default='Video Annotation', default='Video Annotation',
) )
sourceurl = String(help="The external source URL for the video.", display_name="Source URL", scope=Scope.settings, default="http://video-js.zencoder.com/oceans-clip.mp4") sourceurl = String(help=_("The external source URL for the video."), display_name=_("Source URL"), scope=Scope.settings, default="http://video-js.zencoder.com/oceans-clip.mp4")
poster_url = String(help="Poster Image URL", display_name="Poster URL", scope=Scope.settings, default="") poster_url = String(help=_("Poster Image URL"), display_name=_("Poster URL"), scope=Scope.settings, default="")
annotation_storage_url = String(help="Location of Annotation backend", scope=Scope.settings, default="http://your_annotation_storage.com", display_name="Url for Annotation Storage") annotation_storage_url = String(help=_("Location of Annotation backend"), scope=Scope.settings, default="http://your_annotation_storage.com", display_name=_("Url for Annotation Storage"))
annotation_token_secret = String(help="Secret string for annotation storage", scope=Scope.settings, default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", display_name="Secret Token String for Annotation") annotation_token_secret = String(help=_("Secret string for annotation storage"), scope=Scope.settings, default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", display_name=_("Secret Token String for Annotation"))
class VideoAnnotationModule(AnnotatableFields, XModule): class VideoAnnotationModule(AnnotatableFields, XModule):
'''Video Annotation Module''' '''Video Annotation Module'''
......
...@@ -18,6 +18,9 @@ from xblock.fields import Scope, Dict, Boolean, List, Integer, String ...@@ -18,6 +18,9 @@ from xblock.fields import Scope, Dict, Boolean, List, Integer, String
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Make '_' a no-op so we can scrape strings
_ = lambda text: text
def pretty_bool(value): def pretty_bool(value):
"""Check value for possible `True` value. """Check value for possible `True` value.
...@@ -32,49 +35,49 @@ def pretty_bool(value): ...@@ -32,49 +35,49 @@ def pretty_bool(value):
class WordCloudFields(object): class WordCloudFields(object):
"""XFields for word cloud.""" """XFields for word cloud."""
display_name = String( display_name = String(
display_name="Display Name", display_name=_("Display Name"),
help="Display name for this module", help=_("Display name for this module"),
scope=Scope.settings, scope=Scope.settings,
default="Word cloud" default="Word cloud"
) )
num_inputs = Integer( num_inputs = Integer(
display_name="Inputs", display_name=_("Inputs"),
help="Number of text boxes available for students to input words/sentences.", help=_("Number of text boxes available for students to input words/sentences."),
scope=Scope.settings, scope=Scope.settings,
default=5, default=5,
values={"min": 1} values={"min": 1}
) )
num_top_words = Integer( num_top_words = Integer(
display_name="Maximum Words", display_name=_("Maximum Words"),
help="Maximum number of words to be displayed in generated word cloud.", help=_("Maximum number of words to be displayed in generated word cloud."),
scope=Scope.settings, scope=Scope.settings,
default=250, default=250,
values={"min": 1} values={"min": 1}
) )
display_student_percents = Boolean( display_student_percents = Boolean(
display_name="Show Percents", display_name=_("Show Percents"),
help="Statistics are shown for entered words near that word.", help=_("Statistics are shown for entered words near that word."),
scope=Scope.settings, scope=Scope.settings,
default=True default=True
) )
# Fields for descriptor. # Fields for descriptor.
submitted = Boolean( submitted = Boolean(
help="Whether this student has posted words to the cloud.", help=_("Whether this student has posted words to the cloud."),
scope=Scope.user_state, scope=Scope.user_state,
default=False default=False
) )
student_words = List( student_words = List(
help="Student answer.", help=_("Student answer."),
scope=Scope.user_state, scope=Scope.user_state,
default=[] default=[]
) )
all_words = Dict( all_words = Dict(
help="All possible words from all students.", help=_("All possible words from all students."),
scope=Scope.user_state_summary scope=Scope.user_state_summary
) )
top_words = Dict( top_words = Dict(
help="Top num_top_words words for word cloud.", help=_("Top num_top_words words for word cloud."),
scope=Scope.user_state_summary scope=Scope.user_state_summary
) )
......
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