Repository: kartoza/prj.app

Issue:
We need an about page for lessons
I often get asked and try to explain how the lessons app works. Lets put some nice content into an about page like we have for certification. Here is content from an email I wrote to the dev list about it that we can tweak into an about page.

--------
Basically the things you find in the lessons app are worksheets we developed for our own training courses. We tried to come up with a new approach where the worksheets are focussed on the learners doing things and figuring things out themselves and not so much ‘follow the bouncing ball’ instructions. The latter are ok but very hard to maintain and IMHO the learners don’t learn as much as when they have to work stuff out themselves more. The lessons are also much more intended to be instructor lead - you need a competent person guiding the learners through the materials and filling in extra bits of info beyond what is presented on the sheets. I’d be interested to hear feedback from those using them for self-study to see how they work for them, but that wasnt the design intent. We first started working doing the materials in libreoffice but it was very cumbersome dealing with docs in git. The original repo is here:

https://github.com/kartoza/QGISTrainingWorkshop

And you can get an idea of the intended structure of the worksheets here:

training-approach.pdf

We wanted to make it so that each worksheet could be used independently and that it fits on two sides of an A4 sheet so that the activities are in nice bite-sized chunks. We devised a fairly tight structure to the sheets so that learners get the rythmn of the training and start to move through the materials easily. Another design intent was that we could quickly assemble courses customised to the user’s needs. So if a group wants to focus on digitising we can pull out a set of sheets relating to that topic area. We have run quite a few training courses with these (and we made similar sheets for InaSAFE) and they work pretty well for us and, once they grasp the fact that they are not being spoon fed, most of our learners feedback say they enjoy using their brain more during the training. Each lesson has an exercise with a list of specifications. We really try to avoid making particular reference to Gui elements, and rather give instructions like ‘open the vector layer properties and set your line thickness to 4pt, colour to red and opacity to 50%’. This makes the content less vulnerable to a dev tidying up the UI and breaking all the documentation for it, and makes it more fun for the learner to hunt around in the Gui for the different options. We didnt always succeed completely in avoiding specific Gui references but we try our best to do so.

One of the other motivations for shifting to the web is to make it easier for people to get the content formatted nicely - the lessons are created using as structured form that asks for different elements (intro, further reading etc.) and then we assemble the content into the lesson layout. You can also use markdown in the lesson content for basic styling. We have some work in progress to have a ‘curriculum designer’ that will let you tick off one ore more sheets on a form and assemble your own PDF and unique URL with your curriculum so that when you present a course you can link to the sheets being used for the course. At some point it would be nice to link this to the certification app too so that you can say ‘Joe did our course and it covered these modules’.

I don’t know if our approach will work for everyone, but if others are interested to use the platform for QGIS everything we made is open content and the platform is open so feel free to use it - and if you are interested contribute new content. If QGIS.ORG as a whole is interested in making it an official part of the project (e.g. to replace our old training manual work) that is fine with us too - though we dont have the same level of coverege for QGIS as the manual has yet. Also we would probably want to move the translation system into QGIS.ORG sphinx since it will probably be tedious to support ~26 languages or whatever the count we have currently in QGIS.ORG. If anyone wants edit rights to tweak and improve what you see in the lessons app, just pop me a note and I will give you the needed access.

I hope that gives a better background, and thanks to Etienne Trimaille, Ismail Sunni, Rohmat Muhammad, Alison Mukoma and Anita Hapsari who are great examples of people that you may not have heard of who are working away to make cool stuff for QGIS :-)



Discussion:

Resolving patch:
diff --git a/django_project/certification/views/certifying_organisation.py b/django_project/certification/views/certifying_organisation.py
--- a/django_project/certification/views/certifying_organisation.py
+++ b/django_project/certification/views/certifying_organisation.py
@@ -799,7 +799,7 @@ def get_redirect_url(self, project_slug, slug):
 
 
 class AboutView(TemplateView):
-    template_name = 'about.html'
+    template_name = 'about_lesson_app.html'
 
     def get_context_data(self, **kwargs):
         """Get the context data which is passed to a template.
diff --git a/django_project/lesson/urls.py b/django_project/lesson/urls.py
--- a/django_project/lesson/urls.py
+++ b/django_project/lesson/urls.py
@@ -28,6 +28,7 @@
     SectionDeleteView,
     SectionUpdateView,
     SectionOrderView,
+    AboutLessonsApp,
     SectionOrderSubmitView,
 )
 from lesson.views.worksheet import (
@@ -50,6 +51,9 @@
 
 urlpatterns = patterns(
     '',
+    url(regex='^(?P<project_slug>[\w-]+)/section/about/$',
+        view=AboutLessonsApp.as_view(),
+        name='about-lesson-app'),
     # Section
     url(regex='^(?P<project_slug>[\w-]+)/section/create/$',
         view=SectionCreateView.as_view(),
diff --git a/django_project/lesson/views/section.py b/django_project/lesson/views/section.py
--- a/django_project/lesson/views/section.py
+++ b/django_project/lesson/views/section.py
@@ -6,6 +6,7 @@
 from django.core.urlresolvers import reverse
 from django.views.generic import (
     ListView,
+    TemplateView,
     CreateView,
     DeleteView,
     UpdateView,
@@ -243,3 +244,20 @@ def post(self, request, *args, **kwargs):
         project = Project.objects.get(slug=kwargs.get('project_slug'))
         sections = Section.objects.filter(project=project)
         return re_order_features(request, sections)
+
+
+class AboutLessonsApp(TemplateView):
+    """About page for the lessons app."""
+
+    template_name = 'about_lesson_app.html'
+
+    def get_form_kwargs(self):
+        """Get keyword arguments.
+
+        :returns keyword argument
+        :rtype dict
+        """
+        kwargs = super(AboutLessonsApp, self).get_form_kwargs()
+        project_slug = self.kwargs['project_slug']
+        kwargs['project'] = get_object_or_404(Project, slug=project_slug)
+        return kwargs


Test patch:
diff --git a/django_project/lesson/tests/test_section_view.py b/django_project/lesson/tests/test_section_view.py
--- a/django_project/lesson/tests/test_section_view.py
+++ b/django_project/lesson/tests/test_section_view.py
@@ -232,3 +232,64 @@ def test_SectionDelete_no_login(self):
 
         }))
         self.assertEqual(response.status_code, 302)
+
+    @override_settings(VALID_DOMAIN = ['testserver', ])
+    def test_SectionOrderView_no_login(self):
+        """Test section ordering without login."""
+
+        client = Client()
+        response = client.get(reverse(
+                'section-order', kwargs = self.kwargs_project))
+        self.assertEqual(response.status_code, 302)
+
+    @override_settings(VALID_DOMAIN = ['testserver', ])
+    def test_SectionOrderView_with_login(self):
+        """Test section ordering with login."""
+
+        client = Client()
+        status = client.login(username='timlinux', password='password')
+        self.assertTrue(status)
+        response = client.get(reverse(
+                'section-order', kwargs = self.kwargs_project))
+        self.assertEqual(response.status_code, 200)
+
+    @override_settings(VALID_DOMAIN=['testserver', ])
+    def test_SectionOrderSubmitView_no_login(self):
+        """Test section order submit view with no login."""
+
+        client = Client()
+        response = client.get(
+                reverse('section-submit-order', kwargs = self.kwargs_project))
+        self.assertEqual(response.status_code, 302)
+
+    @override_settings(VALID_DOMAIN=['testserver', ])
+    def test_AboutLessonsApp_no_login(self):
+        """
+        Test accessing Lesson about page without login.
+        Access is granted to anonymous users.
+        """
+
+        client = Client()
+        response = client.get(
+                reverse('about-lesson-app', kwargs = self.kwargs_project))
+        self.assertEqual(response.status_code, 200)
+        expected_templates = [
+            'about_lesson_app.html'
+        ]
+        self.assertEqual(response.template_name, expected_templates)
+
+    @override_settings(VALID_DOMAIN = ['testserver', ])
+    def test_AboutLessonsApp_with_login(self):
+        """Test accessing Lesson about page with login."""
+
+        client = Client()
+        status = client.login(username='timlinux', password='password')
+        self.assertTrue(status)
+
+        response = client.get(
+                reverse('about-lesson-app', kwargs = self.kwargs_project))
+        self.assertEqual(response.status_code, 200)
+        expected_templates = [
+            'about_lesson_app.html'
+        ]
+        self.assertEqual(response.template_name, expected_templates)