Repository: apluslms/a-plus

Issue:
LTI Tool: fix multilingual exercise titles in the LTI Platform/Moodle (gradebook grade items and activity titles)
Not sure if this is something to be fixed on A+ side or MyCourses side (or both), but I noticed the following peculiarities when adding an A+ activity and related gradebook behavior:

- On multilingual courses, the task label appears at MyCourses in raw format, e.g.: "8.1 |en:Round 2, exercise 1: If-statement - Temperature|fi:Kierros 2, tehtävä 1: If-käsky - Lämpötila|" for one task on Y1 course. Some parsing would need to be done to pick one of the language versions (not sure at which end)
- <strike>After adding the above, I manually renamed the task to "Round 2, exercise 1" in MyCourses</strike>
- <strike>Now gradebook has columns for both "8.1 |en:Round 2, exercise 1: If-statement - Temperature|fi:Kierros 2, tehtävä 1: If-käsky - Lämpötila|" and "Round 2, exercise 1". The former shows as "Manual item" and latter as "External activity"</strike>
- <strike>When I submit a solution, the grades appear on the first column, even though it should not even be visible after renaming the activity</strike>


Discussion:
When retesting this issue this week, we couldn't repeat the problem related to extra gradebook columns, so it seems to remain mystery for now. However the titles in multilingual courses are still a problem.

Resolving patch:
diff --git a/lti_tool/views.py b/lti_tool/views.py
--- a/lti_tool/views.py
+++ b/lti_tool/views.py
@@ -19,6 +19,7 @@
 from exercise.viewbase import ExerciseBaseView
 from exercise.models import LearningObject, BaseExercise
 from exercise.views import ExerciseView, SubmissionView
+from lib.localization_syntax import pick_localized
 from lib.viewbase import BaseTemplateView, BaseRedirectView, BaseMixin
 from authorization.permissions import ACCESS
 from .utils import get_tool_conf, get_launch_data_storage, get_launch_url
@@ -257,7 +258,7 @@ def post(self, request, *args, **kwargs):
             lineitem_exists = bool([li for li in lineitems if li['tag'] == str(e.id)])
             if e.max_points > 0 and not lineitem_exists:
                 li = LineItem()
-                li.set_tag(str(e.id)).set_score_maximum(e.max_points).set_label(str(e))
+                li.set_tag(str(e.id)).set_score_maximum(e.max_points).set_label(pick_localized(str(e), 'en'))
                 ags.find_or_create_lineitem(li)
 
         # Send activity settings
@@ -268,7 +269,7 @@ def post(self, request, *args, **kwargs):
                 "course_slug": kwargs['course_slug'],
                 "instance_slug": kwargs['instance_slug']
             })
-            .set_title("{}: {}".format(self.course.name, self.instance.instance_name)))
+            .set_title("{}: {}".format(pick_localized(self.course.name, 'en'), pick_localized(self.instance.instance_name, 'en'))))
         return HttpResponse(deep_link.output_response_form([resource]))
 
     # Get list of modules in course
@@ -291,7 +292,7 @@ def post(self, request, *args, **kwargs):
             lineitem_exists = bool([li for li in lineitems if li['tag'] == str(e.id)])
             if e.max_points > 0 and not lineitem_exists:
                 li = LineItem()
-                li.set_tag(str(e.id)).set_score_maximum(e.max_points).set_label(str(e))
+                li.set_tag(str(e.id)).set_score_maximum(e.max_points).set_label(pick_localized(str(e), 'en'))
                 ags.find_or_create_lineitem(li)
 
         # Send activity settings
@@ -303,7 +304,7 @@ def post(self, request, *args, **kwargs):
                 "instance_slug": kwargs['instance_slug'],
                 "module_slug": kwargs['module_slug']
             })
-            .set_title(str(self.module)))
+            .set_title(pick_localized(str(self.module), 'en')))
         return HttpResponse(deep_link.output_response_form([resource]))
 
     # Get list of exercises in module
@@ -329,7 +330,7 @@ def post(self, request, *args, **kwargs):
             for e in children:
                 if e.max_points > 0:
                     li = LineItem()
-                    li.set_tag(str(e.id)).set_score_maximum(e.max_points).set_label(str(e))
+                    li.set_tag(str(e.id)).set_score_maximum(e.max_points).set_label(pick_localized(str(e), 'en'))
                     ags.find_or_create_lineitem(li)
         else:
             try:
@@ -337,7 +338,7 @@ def post(self, request, *args, **kwargs):
                     li = LineItem()
                     (li.set_tag(str(self.exercise.id))
                         .set_score_maximum(self.exercise.max_points)
-                        .set_label(str(self.exercise)))
+                        .set_label(pick_localized(str(self.exercise), 'en')))
                     ags.find_or_create_lineitem(li)
             except AttributeError as e:
                 logger.info("Importing LTI exercise with no max_points attribute")
@@ -352,5 +353,5 @@ def post(self, request, *args, **kwargs):
                 "module_slug": kwargs['module_slug'],
                 "exercise_path": kwargs['exercise_path']
             })
-            .set_title(str(self.exercise)))
+            .set_title(pick_localized(str(self.exercise), 'en')))
         return HttpResponse(deep_link.output_response_form([resource]))


Test patch: