From 45baccae858fa8bd9e9fdd4a555ff6c53455c195 Mon Sep 17 00:00:00 2001
From: Bridger Maxwell <bridgeyman@gmail.com>
Date: Fri, 10 Aug 2012 11:31:29 -0400
Subject: [PATCH] Added a django template loader that can return Mako templates. Started pulling in new wiki.

---
 common/lib/mitxmako/mitxmako/makoloader.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 common/lib/mitxmako/mitxmako/template.py   | 33 +++++++++++++++++++++++++++++++--
 lms/envs/common.py                         | 24 +++++++++++++++++++++---
 lms/templates/wiki/article.html            | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 lms/urls.py                                | 15 +++++++++++----
 requirements.txt                           |  1 +
 6 files changed, 175 insertions(+), 9 deletions(-)
 create mode 100644 common/lib/mitxmako/mitxmako/makoloader.py
 create mode 100644 lms/templates/wiki/article.html

diff --git a/common/lib/mitxmako/mitxmako/makoloader.py b/common/lib/mitxmako/mitxmako/makoloader.py
new file mode 100644
index 0000000..fc1633c
--- /dev/null
+++ b/common/lib/mitxmako/mitxmako/makoloader.py
@@ -0,0 +1,63 @@
+
+from django.template.base import TemplateDoesNotExist
+from django.template.loader import make_origin, get_template_from_string
+from django.template.loaders.filesystem import Loader as FilesystemLoader
+from django.template.loaders.app_directories import Loader as AppDirectoriesLoader
+
+from mitxmako.template import Template
+
+class MakoLoader(object):
+    """
+    This is a Django loader object which will load the template as a
+    Mako template if the first line is "## mako". It is based off BaseLoader
+    in django.template.loader.
+    """
+    
+    is_usable = False
+
+    def __init__(self, base_loader):
+        # base_loader is an instance of a BaseLoader subclass
+        self.base_loader = base_loader
+    
+    def __call__(self, template_name, template_dirs=None):
+        return self.load_template(template_name, template_dirs)
+
+    def load_template(self, template_name, template_dirs=None):
+        source, display_name = self.base_loader.load_template_source(template_name, template_dirs)
+        
+        if source.startswith("## mako\n"):
+            # This is a mako template
+            template = Template(text=source, uri=template_name)
+            return template, None
+        else:
+            # This is a regular template
+            origin = make_origin(display_name, self.load_template_source, template_name, template_dirs)
+            try:
+                template = get_template_from_string(source, origin, template_name)
+                return template, None
+            except TemplateDoesNotExist:
+                # If compiling the template we found raises TemplateDoesNotExist, back off to
+                # returning the source and display name for the template we were asked to load.
+                # This allows for correct identification (later) of the actual template that does
+                # not exist.
+                return source, display_name
+    
+    def load_template_source(self):
+        # Just having this makes the template load as an instance, instead of a class.
+        raise NotImplementedError
+
+    def reset(self):
+        self.base_loader.reset()
+    
+
+class MakoFilesystemLoader(MakoLoader):
+    is_usable = True
+    
+    def __init__(self):
+        MakoLoader.__init__(self, FilesystemLoader())
+        
+class MakoAppDirectoriesLoader(MakoLoader):
+    is_usable = True
+    
+    def __init__(self):
+        MakoLoader.__init__(self, AppDirectoriesLoader())
diff --git a/common/lib/mitxmako/mitxmako/template.py b/common/lib/mitxmako/mitxmako/template.py
index 911f5a5..e8fc24a 100644
--- a/common/lib/mitxmako/mitxmako/template.py
+++ b/common/lib/mitxmako/mitxmako/template.py
@@ -12,18 +12,47 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 
+from django.conf import settings
 from mako.template import Template as MakoTemplate
 
-from . import middleware
+from mitxmako import middleware
 
-django_variables = ['lookup', 'template_dirs', 'output_encoding',
+django_variables = ['lookup', 'output_encoding',
                     'module_directory', 'encoding_errors']
 
 
 class Template(MakoTemplate):
+    """
+    This bridges the gap between a Mako template and a djano template. It can
+    be rendered like it is a django template because the arguments are transformed
+    in a way that MakoTemplate can understand.
+    """
+    
     def __init__(self, *args, **kwargs):
         """Overrides base __init__ to provide django variable overrides"""
         if not kwargs.get('no_django', False):
             overrides = dict([(k, getattr(middleware, k, None),) for k in django_variables])
+            overrides['lookup'] = overrides['lookup']['main']
             kwargs.update(overrides)
         super(Template, self).__init__(*args, **kwargs)
+    
+    
+    def render(self, context_instance):
+        """
+        This takes a render call with a context (from Django) and translates
+        it to a render call on the mako template.
+        """
+        # collapse context_instance to a single dictionary for mako
+        context_dictionary = {}
+        
+        # In various testing contexts, there might not be a current request context.
+        if middleware.requestcontext is not None:
+            for d in middleware.requestcontext:
+                context_dictionary.update(d)
+        for d in context_instance:
+            context_dictionary.update(d)
+        context_dictionary['settings'] = settings
+        context_dictionary['MITX_ROOT_URL'] = settings.MITX_ROOT_URL
+        
+        return super(Template, self).render(**context_dictionary)
+        
diff --git a/lms/envs/common.py b/lms/envs/common.py
index 487e2ef..6354d58 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -111,6 +111,12 @@ TEMPLATE_CONTEXT_PROCESSORS = (
     'askbot.user_messages.context_processors.user_messages',#must be before auth
     'django.contrib.auth.context_processors.auth', #this is required for admin
     'django.core.context_processors.csrf', #necessary for csrf protection
+    
+    # Added for django-wiki
+    'django.core.context_processors.media',
+    'django.core.context_processors.tz',
+    'django.contrib.messages.context_processors.messages',
+    'sekizai.context_processors.sekizai',
 )
 
 
@@ -281,9 +287,13 @@ STATICFILES_FINDERS = (
 
 # List of callables that know how to import templates from various sources.
 TEMPLATE_LOADERS = (
-    'django.template.loaders.filesystem.Loader',
-    'django.template.loaders.app_directories.Loader',
-    'askbot.skins.loaders.filesystem_load_template_source',
+    'mitxmako.makoloader.MakoFilesystemLoader',
+    'mitxmako.makoloader.MakoAppDirectoriesLoader',
+ 
+    # 'django.template.loaders.filesystem.Loader',
+    # 'django.template.loaders.app_directories.Loader',
+    
+    #'askbot.skins.loaders.filesystem_load_template_source',
     # 'django.template.loaders.eggs.Loader',
 )
 
@@ -514,6 +524,14 @@ INSTALLED_APPS = (
     'track',
     'util',
     'certificates',
+    
+    #For the wiki
+    'wiki', # The new django-wiki from benjaoming
+    'django_notify',
+    'mptt',
+    'sekizai',
+    'wiki.plugins.attachments',
+    'wiki.plugins.notifications',
 
     # For testing
     'django_jasmine',
diff --git a/lms/templates/wiki/article.html b/lms/templates/wiki/article.html
new file mode 100644
index 0000000..45b3071
--- /dev/null
+++ b/lms/templates/wiki/article.html
@@ -0,0 +1,48 @@
+## mako
+<%inherit file="../main.html"/>
+<%namespace name='static' file='../static_content.html'/>
+
+<%block name="bodyextra">
+
+This is a mako template with inheritance!
+
+</%block>
+
+
+<!-- {% extends "wiki/base.html" %}
+{% load wiki_tags i18n %}
+{% load url from future %}
+
+{% block pagetitle %}{{ article.current_revision.title }}{% endblock %}
+
+{% block wiki_breadcrumbs %}
+{% include "wiki/includes/breadcrumbs.html" %}
+{% endblock %}
+
+{% block wiki_contents %}
+  <h1> Did it work? </h1>
+  <div class="tabbable tabs-top" style="margin-top: 20px;">
+    <ul class="nav nav-tabs">
+      <li style="float: left">
+        <h1 style="margin-top: -10px;">{{ article.current_revision.title }}</h1>
+      </li>
+      {% with "view" as selected %}
+        {% include "wiki/includes/article_menu.html" %}
+      {% endwith %}
+    </ul>
+    <div class="tab-content">
+      {% wiki_render article %}
+    </div>
+  </div>
+
+  <div class="tabbable tabs-below" style="margin-top: 20px;">
+    <ul class="nav nav-tabs">
+      {% with "view" as selected %}
+        {% include "wiki/includes/article_menu.html" %}
+      {% endwith %}
+      <li style="margin-top: 10px;"><em>{% trans "Article last modified:" %} {{ article.current_revision.modified }}</em></li>
+    </ul>
+  </div>
+    
+{% endblock %} -->
+
diff --git a/lms/urls.py b/lms/urls.py
index bb3952b..44523dd 100644
--- a/lms/urls.py
+++ b/lms/urls.py
@@ -2,7 +2,6 @@ from django.conf import settings
 from django.conf.urls import patterns, include, url
 from django.contrib import admin
 from django.conf.urls.static import static
-
 import django.contrib.auth.views
 
 # Uncomment the next two lines to enable the admin:
@@ -144,9 +143,17 @@ if settings.COURSEWARE_ENABLED:
 
     # Multicourse wiki
 if settings.WIKI_ENABLED:
-    urlpatterns += (
-        url(r'^wiki/', include('simplewiki.urls')),
-        url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/wiki/', include('simplewiki.urls')),
+    from wiki.urls import get_pattern as wiki_pattern
+    from django_notify.urls import get_pattern as notify_pattern
+    
+    # urlpatterns += (
+    #     url(r'^wiki/', include('simplewiki.urls')),
+    #     url(r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/wiki/', include('simplewiki.urls')),
+    # )
+    urlpatterns += (        
+    
+        url(r'wiki/', include(wiki_pattern())),
+        url(r'^notify/', include(notify_pattern())),
     )
 
 if settings.QUICKEDIT:
diff --git a/requirements.txt b/requirements.txt
index ef16d2c..5905aa8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -43,4 +43,5 @@ django-robots
 django-ses
 django-storages
 django-threaded-multihost
+-e git+git://github.com/benjaoming/django-wiki.git#egg=django-wiki
 -r repo-requirements.txt
--
libgit2 0.26.0