From 15ac4767818ef2048f8cfad5ba8bc4602c1e0d49 Mon Sep 17 00:00:00 2001
From: Calen Pennington <calen.pennington@gmail.com>
Date: Sun, 15 Jul 2012 14:59:32 -0400
Subject: [PATCH] Display preview html on the module edit page. Javascript for
 previews doesn't yet function

---
 cms/djangoapps/contentstore/views.py    |  90 +++++++++++-
 cms/envs/common.py                      |   4 +
 cms/static/coffee/unit.coffee           |  15 --
 cms/templates/unit.html                 |  41 ++++++
 cms/templates/widgets/html-edit.html    |  42 ------
 cms/templates/widgets/problem-edit.html |  48 ------
 cms/templates/widgets/problem-new.html  |  51 -------
 cms/templates/widgets/raw-edit.html     |  42 ------
 cms/templates/widgets/raw-videos.html   |   3 -
 cms/templates/widgets/sequnce-edit.html | 187 ------------------------
 cms/urls.py                             |   1 +
 common/lib/xmodule/xmodule/x_module.py  |   7 +
 12 files changed, 141 insertions(+), 390 deletions(-)
 delete mode 100644 cms/static/coffee/unit.coffee
 delete mode 100644 cms/templates/widgets/problem-edit.html
 delete mode 100644 cms/templates/widgets/problem-new.html
 delete mode 100644 cms/templates/widgets/raw-videos.html
 delete mode 100644 cms/templates/widgets/sequnce-edit.html

diff --git a/cms/djangoapps/contentstore/views.py b/cms/djangoapps/contentstore/views.py
index d24eabd780b..dd4b36d788b 100644
--- a/cms/djangoapps/contentstore/views.py
+++ b/cms/djangoapps/contentstore/views.py
@@ -8,9 +8,11 @@ from django_future.csrf import ensure_csrf_cookie
 from django.core.urlresolvers import reverse
 
 from xmodule.modulestore import Location
+from xmodule.x_module import ModuleSystem
 from github_sync import export_to_github
+from static_replace import replace_urls
 
-from mitxmako.shortcuts import render_to_response
+from mitxmako.shortcuts import render_to_response, render_to_string
 from xmodule.modulestore.django import modulestore
 
 
@@ -39,6 +41,9 @@ def login_page(request):
 @login_required
 @ensure_csrf_cookie
 def index(request):
+    """
+    List all courses available to the logged in user
+    """
     courses = modulestore().get_items(['i4x', None, None, 'course', None])
     return render_to_response('index.html', {
         'courses': [(course.metadata['display_name'],
@@ -61,6 +66,11 @@ def has_access(user, location):
 @login_required
 @ensure_csrf_cookie
 def course_index(request, org, course, name):
+    """
+    Display an editable course overview.
+
+    org, course, name: Attributes of the Location for the item to edit
+    """
     location = ['i4x', org, course, 'course', name]
     if not has_access(request.user, location):
         raise Http404  # TODO (vshnayder): better error
@@ -73,6 +83,13 @@ def course_index(request, org, course, name):
 
 @login_required
 def edit_item(request):
+    """
+    Display an editing page for the specified module.
+
+    Expects a GET request with the parameter 'id'.
+
+    id: A Location URL
+    """
     # TODO (vshnayder): change name from id to location in coffee+html as well.
     item_location = request.GET['id']
     print item_location, request.GET
@@ -85,6 +102,7 @@ def edit_item(request):
         'js_module': item.js_module_name(),
         'category': item.category,
         'name': item.name,
+        'previews': get_module_previews(item),
     })
 
 
@@ -105,6 +123,71 @@ def user_author_string(user):
 
 
 @login_required
+def preview_dispatch(request, module_id, dispatch):
+    """
+    Dispatch an AJAX action to a preview XModule
+
+    Expects a POST request, and passes the arguments to the module
+
+    module_id: The Location of the module to dispatch to
+    dispatch: The action to execute
+    """
+    pass
+
+
+def render_from_lms(template_name, dictionary, context=None, namespace='main'):
+    """
+    Render a template using the LMS MAKO_TEMPLATES
+    """
+    return render_to_string(template_name, dictionary, context, namespace="lms." + namespace)
+
+
+def sample_module_system(descriptor):
+    """
+    Returns a ModuleSystem for the specified descriptor that is specialized for
+    rendering module previews.
+    """
+    return ModuleSystem(
+        ajax_url=reverse('preview_dispatch', args=[descriptor.location.url(), '']),
+        # TODO (cpennington): Do we want to track how instructors are using the preview problems?
+        track_function=lambda x: None,
+        filestore=descriptor.system.resources_fs,
+        get_module=get_sample_module,
+        render_template=render_from_lms,
+        debug=True,
+        replace_urls=replace_urls
+    )
+
+
+def get_sample_module(location):
+    """
+    Returns a sample XModule at the specified location. The sample_data is chosen arbitrarily
+    from the set of sample data for the descriptor specified by Location
+
+    location: A Location
+    """
+    descriptor = modulestore().get_item(location)
+    instance_state, shared_state = descriptor.get_sample_state()[0]
+    system = sample_module_system(descriptor)
+    module = descriptor.xmodule_constructor(system)(instance_state, shared_state)
+    return module
+
+
+def get_module_previews(descriptor):
+    """
+    Returns a list of preview XModule html contents. One preview is returned for each
+    pair of states returned by get_sample_state() for the supplied descriptor.
+
+    descriptor: An XModuleDescriptor
+    """
+    preview_html = []
+    system = sample_module_system(descriptor)
+    for instance_state, shared_state in descriptor.get_sample_state():
+        module = descriptor.xmodule_constructor(system)(instance_state, shared_state)
+        preview_html.append(module.get_html())
+    return preview_html
+
+
 @expect_json
 def save_item(request):
     item_location = request.POST['id']
@@ -124,4 +207,7 @@ def save_item(request):
         author_string = user_author_string(request.user)
         export_to_github(course, "CMS Edit", author_string)
 
-    return HttpResponse(json.dumps({}))
+    descriptor = modulestore().get_item(item_id)
+    preview_html = get_module_previews(descriptor)
+
+    return HttpResponse(json.dumps(preview_html))
diff --git a/cms/envs/common.py b/cms/envs/common.py
index 896c4515a26..5fb0c82bb72 100644
--- a/cms/envs/common.py
+++ b/cms/envs/common.py
@@ -25,6 +25,7 @@ import os.path
 import os
 import errno
 import glob2
+import lms.envs.common
 from path import path
 
 ############################ FEATURE CONFIGURATION #############################
@@ -64,6 +65,9 @@ MAKO_TEMPLATES['main'] = [
     COMMON_ROOT / 'djangoapps' / 'pipeline_mako' / 'templates'
 ]
 
+for namespace, template_dirs in lms.envs.common.MAKO_TEMPLATES.iteritems():
+    MAKO_TEMPLATES['lms.' + namespace] = template_dirs
+
 TEMPLATE_DIRS = (
     PROJECT_ROOT / "templates",
 )
diff --git a/cms/static/coffee/unit.coffee b/cms/static/coffee/unit.coffee
deleted file mode 100644
index dda41fe42b4..00000000000
--- a/cms/static/coffee/unit.coffee
+++ /dev/null
@@ -1,15 +0,0 @@
-class @Unit
-    constructor: (@element_id, @module_id) ->
-        @module = new window[$("##{@element_id}").attr('class')] 'module-html'
-
-        $("##{@element_id} .save-update").click (event) =>
-            event.preventDefault()
-            $.post("/save_item", {
-                id: @module_id
-                data: JSON.stringify(@module.save())
-            })
-
-        $("##{@element_id} .cancel").click (event) =>
-            event.preventDefault()
-            CMS.edit_item(@module_id)
-
diff --git a/cms/templates/unit.html b/cms/templates/unit.html
index cd921d2be25..1d525400c5e 100644
--- a/cms/templates/unit.html
+++ b/cms/templates/unit.html
@@ -12,6 +12,47 @@
   </header>
 
   <section>
+    <section class="meta wip">
+      <section class="status-settings">
+        <ul>
+          <li><a href="#" class="current">Scrap</a></li>
+          <li><a href="#">Draft</a></li>
+          <li><a href="#">Proofed</a></li>
+          <li><a href="#">Published</a></li>
+        </ul>
+        <a href="#" class="settings">Settings</a>
+      </section>
+      <section class="author">
+        <dl>
+          <dt>Last modified:</dt>
+          <dd>mm/dd/yy</dd>
+          <dt>By</dt>
+          <dd>Anant Agarwal</dd>
+        </dl>
+      </section>
+      <section class="tags">
+        <div>
+          <h2>Tags:</h2>
+          <p class="editable">Click to edit</p>
+        </div>
+        <div>
+          <h2>Goal</h2>
+          <p class="editable">Click to edit</p>
+        </div>
+      </section>
+    </section>
     ${contents}
+    <section class="previews">
+      % for preview in previews:
+        <section class="preview">
+          ${preview}
+        </section>
+      % endfor
+    </section>
+    <div class="actions wip">
+      <a href="" class="save-update">Save &amp; Update</a>
+      <a href="#" class="cancel">Cancel</a>
+    </div>
+    <%include file="widgets/notes.html"/>
   </section>
 </section>
diff --git a/cms/templates/widgets/html-edit.html b/cms/templates/widgets/html-edit.html
index 47a6a55cba1..1e86c6c734e 100644
--- a/cms/templates/widgets/html-edit.html
+++ b/cms/templates/widgets/html-edit.html
@@ -1,45 +1,3 @@
 <section class="html-edit">
-  <section class="meta wip">
-
-    <section class="status-settings">
-      <ul>
-        <li><a href="#" class="current">Scrap</a></li>
-        <li><a href="#">Draft</a></li>
-        <li><a href="#">Proofed</a></li>
-        <li><a href="#">Published</a></li>
-      </ul>
-      <a href="#" class="settings">Settings</a>
-    </section>
-
-    <section class="author">
-      <dl>
-        <dt>Last modified:</dt>
-        <dd>mm/dd/yy</dd>
-        <dt>By</dt>
-        <dd>Anant Agarwal</dd>
-      </dl>
-    </section>
-
-    <section class="tags">
-      <div>
-        <h2>Tags:</h2>
-        <p class="editable">Click to edit</p>
-      </div>
-
-      <div>
-        <h2>Goal</h2>
-        <p class="editable">Click to edit</p>
-      </div>
-    </section>
-  </section>
-
   <textarea name="" class="edit-box" rows="8" cols="40">${data}</textarea>
-  <div class="preview">${data}</div>
-
-  <div class="actions">
-    <a href="" class="save-update">Save &amp; Update</a>
-    <a href="#" class="cancel">Cancel</a>
-  </div>
-
-  <%include file="notes.html"/>
 </section>
diff --git a/cms/templates/widgets/problem-edit.html b/cms/templates/widgets/problem-edit.html
deleted file mode 100644
index a2da078927f..00000000000
--- a/cms/templates/widgets/problem-edit.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<section class="problem-edit">
-  <section class="meta">
-    <section class="status-settings">
-      <ul>
-        <li><a href="#" class="current">Scrap</a></li>
-        <li><a href="#">Draft</a></li>
-        <li><a href="#">Proofed</a></li>
-        <li><a href="#">Published</a></li>
-      </ul>
-      <a href="#" class="settings">Settings</a>
-    </section>
-
-    <section class="author">
-      <dl>
-        <dt>Last modified:</dt>
-        <dd>mm/dd/yy</dd>
-        <dt>By</dt>
-        <dd>Anant Agarwal</dd>
-      </dl>
-    </section>
-
-    <section class="tags">
-      <div>
-        <h2>Tags:</h2>
-        <p class="editable">Click to edit</p>
-      </div>
-
-      <div>
-        <h2>Goal</h2>
-        <p class="editable">Click to edit</p>
-      </div>
-    </section>
-  </section>
-
-  <section>
-    <textarea name="" id= rows="8" cols="40">Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.</textarea>
-    <div class="preview">
-      Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
-    </div>
-
-    <div class="actions">
-      <a href="#" class="cancel">Cancel</a>
-      <a href="" class="save-update">Save &amp; Update</a>
-    </div>
-  </section>
-
-  <%include file="notes.html"/>
-</section>
diff --git a/cms/templates/widgets/problem-new.html b/cms/templates/widgets/problem-new.html
deleted file mode 100644
index d986f5a9ef1..00000000000
--- a/cms/templates/widgets/problem-new.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<section class="problem-new">
-  <header>
-    <a href="#" class="cancel">Cancel</a>
-    <a href="#" class="save-update">Save &amp; Update</a>
-  </header>
-
-  <section>
-    <header>
-    <h1 class="editable">New Problem</h1>
-
-      <section class="status-settings">
-        <ul>
-          <li><a href="#" class="current">Scrap</a></li>
-          <li><a href="#">Draft</a></li>
-          <li><a href="#">Proofed</a></li>
-          <li><a href="#">Published</a></li>
-        </ul>
-        <a href="#" class="settings">Settings</a>
-
-        <select name="" id="">
-          <option>Global</option>
-        </select>
-      </section>
-      <section class="meta">
-        <div>
-          <h2>Tags:</h2>
-          <p class="editable">Click to edit</p>
-        </div>
-
-        <div>
-          <h2>Goal</h2>
-          <p class="editable">Click to edit</p>
-        </div>
-      </section>
-    </header>
-
-    <section>
-      <textarea name="" id= rows="8" cols="40"></textarea>
-      <div class="preview">
-      </div>
-    </section>
-
-    <section class="notes">
-      <h2>Add notes</h2>
-      <textarea name="" id= rows="8" cols="40"></textarea>
-      <input type="submit" name="" id="" value="post" />
-    </section>
-
-    <a href="" class="save-update">Save &amp; Update</a>
-  </section>
-</section>
diff --git a/cms/templates/widgets/raw-edit.html b/cms/templates/widgets/raw-edit.html
index dc0e99265ca..fbd1757be5c 100644
--- a/cms/templates/widgets/raw-edit.html
+++ b/cms/templates/widgets/raw-edit.html
@@ -1,45 +1,3 @@
 <section class="raw-edit">
-  <section class="meta wip">
-
-    <section class="status-settings">
-      <ul>
-        <li><a href="#" class="current">Scrap</a></li>
-        <li><a href="#">Draft</a></li>
-        <li><a href="#">Proofed</a></li>
-        <li><a href="#">Published</a></li>
-      </ul>
-      <a href="#" class="settings">Settings</a>
-    </section>
-
-    <section class="author">
-      <dl>
-        <dt>Last modified:</dt>
-        <dd>mm/dd/yy</dd>
-        <dt>By</dt>
-        <dd>Anant Agarwal</dd>
-      </dl>
-    </section>
-
-    <section class="tags">
-      <div>
-        <h2>Tags:</h2>
-        <p class="editable">Click to edit</p>
-      </div>
-
-      <div>
-        <h2>Goal</h2>
-        <p class="editable">Click to edit</p>
-      </div>
-    </section>
-  </section>
-
   <textarea name="" class="edit-box" rows="8" cols="40">${data | h}</textarea>
-  <pre class="preview">${data | h}</pre>
-
-  <div class="actions wip">
-    <a href="" class="save-update">Save &amp; Update</a>
-    <a href="#" class="cancel">Cancel</a>
-  </div>
-
-  <%include file="notes.html"/>
 </section>
diff --git a/cms/templates/widgets/raw-videos.html b/cms/templates/widgets/raw-videos.html
deleted file mode 100644
index f466fd59bca..00000000000
--- a/cms/templates/widgets/raw-videos.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<li>
-  <img src="http://placehold.it/300x180" alt="" /><h5>Video-file-name</h5>
-</li>
diff --git a/cms/templates/widgets/sequnce-edit.html b/cms/templates/widgets/sequnce-edit.html
deleted file mode 100644
index b69b523bc44..00000000000
--- a/cms/templates/widgets/sequnce-edit.html
+++ /dev/null
@@ -1,187 +0,0 @@
-<section class="sequence-edit">
-  <header>
-    <div class="week">
-      <h2><a href="">Week 1</a></h2>
-      <ul>
-        <li>
-          <p class="editable"><strong>Goal title:</strong> This is the goal body and is where the goal will be further explained</p>
-        </li>
-      </ul>
-    </div>
-    <div>
-      <h1 class="editable">Lecture sequence</h1>
-      <p><strong>Group type:</strong> Ordered Sequence</p>
-    </div>
-  </header>
-
-  <section class="content">
-    <section class="filters">
-      <ul>
-        <li>
-          <label for="">Sort by</label>
-          <select>
-            <option value="">Recently Modified</option>
-          </select>
-        </li>
-
-        <li>
-          <label for="">Display</label>
-          <select>
-            <option value="">All content</option>
-          </select>
-        </li>
-        <li>
-          <select>
-            <option value="">Internal Only</option>
-          </select>
-        </li>
-
-        <li class="advanced">
-          <a href="#">Advanced filters</a>
-        </li>
-
-        <li>
-          <input type="search" name="" id="" value="" />
-        </li>
-      </ul>
-    </section>
-
-    <div>
-      <section class="modules">
-        <ol>
-          <li>
-            <ol>
-              <li>
-                <a href="" class="problem-edit">Problem title 11</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="sequence-edit">Problem Group</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="problem-edit">Problem title 14</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="video-edit">Video 3</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li class="group">
-                <header>
-                  <h3>
-                    <a href="#" class="problem-edit">Problem group</a>
-                    <a href="#" class="draggable">handle</a>
-                  </h3>
-                </header>
-                <ol>
-                  <li>
-                    <a href="#" class="problem-edit">Problem title 11</a>
-                    <a href="#" class="draggable">handle</a>
-                  </li>
-                  <li>
-                    <a href="#" class="problem-edit">Problem title 11</a>
-                    <a href="#" class="draggable">handle</a>
-                  </li>
-                  <li>
-                    <a href="#" class="problem-edit">Problem title 11</a>
-                    <a href="#" class="draggable">handle</a>
-                  </li>
-                </ol>
-              </li>
-              <li>
-                <a href="#" class="problem-edit">Problem title 13</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="problem-edit">Problem title 14</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="video-edit">Video 3</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="" class="problem-edit">Problem title 11</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="sequence-edit">Problem Group</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="problem-edit">Problem title 14</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="video-edit">Video 3</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-            </ol>
-          </li>
-
-          <!-- <li class="new-module"> -->
-          <!--   <%include file="new-module.html"/> -->
-          <!-- </li> -->
-        </ol>
-      </section>
-
-      <section class="scratch-pad">
-        <ol>
-          <li>
-            <header>
-              <h2>Section Scratch</h2>
-            </header>
-            <ul>
-              <li>
-                <a href="#" class="problem-edit">Problem title 11</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="problem-edit">Problem title 13 </a>
-              <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="problem-edit"> Problem title 14</a>
-              <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="" class="video-edit">Video 3</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-            </ul>
-          </li>
-          <li>
-            <header>
-              <h2>Course Scratch</h2>
-            </header>
-
-            <ul>
-              <li>
-                <a href="#" class="problem-edit">Problem title 11</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="problem-edit">Problem title 13 </a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="#" class="problem-edit"> Problem title 14</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-              <li>
-                <a href="" class="video-edit">Video 3</a>
-                <a href="#" class="draggable">handle</a>
-              </li>
-            </ul>
-          </li>
-
-          <!-- <li class="new-module"> -->
-          <!--   <%include file="new-module.html"/> -->
-          <!-- </li> -->
-        </ol>
-      </section>
-    </div>
-  </section>
-</section>
-
diff --git a/cms/urls.py b/cms/urls.py
index b3dc9a48e9e..18e16b159cb 100644
--- a/cms/urls.py
+++ b/cms/urls.py
@@ -14,6 +14,7 @@ urlpatterns = ('',
     url(r'^(?P<org>[^/]+)/(?P<course>[^/]+)/course/(?P<name>[^/]+)$',
         'contentstore.views.course_index', name='course_index'),
     url(r'^github_service_hook$', 'github_sync.views.github_post_receive'),
+    url(r'^preview/modx/(?P<id>.*?)/(?P<dispatch>[^/]*)$', 'contentstore.views.preview_dispatch', name='preview_dispatch')
 )
 
 # User creation and updating views
diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py
index 20b58a69e70..ecdbb4e5328 100644
--- a/common/lib/xmodule/xmodule/x_module.py
+++ b/common/lib/xmodule/xmodule/x_module.py
@@ -411,6 +411,13 @@ class XModuleDescriptor(Plugin):
         """
         raise NotImplementedError("get_html() must be provided by specific modules")
 
+    # =============================== Testing ===================================
+    def get_sample_state(self):
+        """
+        Return a list of tuples of instance_state, shared_state. Each tuple defines a test/sample case for this module
+        """
+        return [('{}', '{}')]
+
     # =============================== BUILTIN METHODS ===========================
     def __eq__(self, other):
         eq = (self.__class__ == other.__class__ and
-- 
GitLab