Commits

Ahmad Khayyat  committed 8001d00

Support optinal server-side previews

- Configurable through the `PAGEDOWN_SERVER_SIDE_PREVIEW` boolean
setting
- Uses ajax post requests to update the preview in real-time
- Uses Ben Alman's debounce jquery plugin to limit the ajax requests

  • Participants
  • Parent commits 953e960

Comments (0)

Files changed (6)

File mezzanine_pagedown/defaults.py

+from mezzanine.conf import register_setting
+
+register_setting(
+    name="PAGEDOWN_SERVER_SIDE_PREVIEW",
+    description="Generate previews of the rendered HTML on the server using ajax requests.",
+    editable=False,
+    default=False,
+)

File mezzanine_pagedown/static/mezzanine_pagedown/js/jquery.ba-throttle-debounce.min.js

+/*
+ * jQuery throttle / debounce - v1.1 - 3/7/2010
+ * http://benalman.com/projects/jquery-throttle-debounce-plugin/
+ * 
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);

File mezzanine_pagedown/templates/mezzanine_pagedown/editor.html

     <div id="wmd-button-bar-{{ id }}"></div>
     <textarea id="wmd-input-{{ id }}" class="wmd-input" {{ final_attrs|safe }}>{{ value }}</textarea>
   </div>
+  {% if server_side_preview %}
+  <div id="server-preview-{{ id }}" class="wmd-preview"></div>
+  {% else %}
   <div id="wmd-preview-{{ id }}" class="wmd-panel wmd-preview"></div>
+  {% endif %}
   <script type="text/javascript">
     (function () {
-    var converter_{{ id }} = Markdown.getSanitizingConverter();
-    var editor_{{ id }} = new Markdown.Editor(converter_{{ id }}, "-{{ id }}");
-    editor_{{ id }}.hooks.set("insertImageDialog", browseMediaLibrary);
-    editor_{{ id }}.run();
+      var converter_{{ id }} = Markdown.getSanitizingConverter();
+      var editor_{{ id }} = new Markdown.Editor(converter_{{ id }}, "-{{ id }}");
+      editor_{{ id }}.hooks.set("insertImageDialog", browseMediaLibrary);
+      editor_{{ id }}.run();
+
+      preview = function() {
+        $.post('/pagedown/preview/',
+          {text:$('#wmd-input-{{ id }}').val()},
+          function(data,status) {
+            $('#server-preview-{{ id }}').html(data);
+        });
+      };
+      // update the preview on textarea input
+      $('#wmd-input-{{ id }}').on('input onpropertychange', $.debounce(250,preview));
+      // update the preview on pagedown editor button clicks
+      $('#wmd-button-bar-{{ id }}').on('click', preview);
+      // initial preview on loading the page
+      $(document).ready(preview);
     })();
   </script>
 </div>

File mezzanine_pagedown/urls.py

+from django.conf.urls import patterns, url
+
+from .views import MarkupPreview
+
+urlpatterns = patterns('',
+    url(r'^preview/$', MarkupPreview.as_view(), name='preview'),
+)

File mezzanine_pagedown/views.py

+from django.http import HttpResponse
+from django.views.generic import View
+
+from markdown import markdown
+
+class MarkupPreview(View):
+    """Renders markdown content to HTML for preview purposes."""
+
+    http_method_names = ['post']
+
+    def post(self, request, *args, **kwargs):
+        text = self.request.POST.get('text', u"")
+        return HttpResponse(markdown(text), content_type='text/html')

File mezzanine_pagedown/widgets.py

 
 class PageDownWidget(forms.Textarea):
     """
-    Widget providing Markdown preview using PageDown JavaScript
+    Widget providing Markdown editor using PageDown JavaScript, and live
+    preview.
+    Live preview can be generated client-side using PageDown, or
+    server-side using python-markdown.
     """
     class Media:
         css = {'all': (
               'mezzanine_pagedown/pagedown/Markdown.Editor.js',
               'mezzanine/js/%s' % settings.JQUERY_FILENAME,
               'mezzanine/js/jquery-ui-1.9.1.custom.min.js',
-              'filebrowser/js/filebrowser-popup.js',)
+              'filebrowser/js/filebrowser-popup.js',
+              'mezzanine_pagedown/js/jquery.ba-throttle-debounce.min.js')
 
     def __init__(self, template=None, *args, **kwargs):
         self.template = template or 'mezzanine_pagedown/editor.html'
             'final_attrs': flatatt(final_attrs),
             'value': conditional_escape(force_unicode(value)),
             'id': final_id,
+            'server_side_preview': settings.PAGEDOWN_SERVER_SIDE_PREVIEW,
         }))
 
 class PlainWidget(forms.Textarea):