Repository: translate/pootle

Issue:
Add live preview when editing static documents
When editing static document, let's split the screen vertically if it's width is more than 1920px, and horizontally otherwise, and add a live rendering when contents of the HTML editor area change. In the preview mode, use the same wrapper divs to make sure we pick up all styles and render the page as close to the final output as possible.

Quick illustration: http://www.htmlinstant.com/ or http://htmledit.squarefree.com/

Mockup screenshot:
![static_preview](https://cloud.githubusercontent.com/assets/1728158/7848828/1326968e-0484-11e5-856e-96a461976cdc.png)



Discussion:
@iafan be aware that this isn't always HTML but could be markdown or other format.  As long as there is a parser for those I guess it could also be rendered.  Would it not make sense to maybe drop HTML and force these to be written in something like markdown?

I strongly prefer HTML as it gives you the full control of the final rendering, and also allows you to set custom CSS styles and so on. Also, HTML means no conversion between source and preview => faster preview.

What's the reason for using Markdown there?

I'm +1 on markdown over html here. It's easier to write and if the user wants _that much control_ over the output, then custom templates can be written by that point.

Don't want to hijack this feature, but the reason for markdown is this:
1. Its simpler to write.
2. Its hard to create a broken page
3. Its hard to create a malicious page (which is critical in some of our instances)

My feeling is customisation should happen in the sidebar styling CSS not in custom CSS within a staticpage.

Markdown is definitely faster to write, but its primary use case is dynamic user-generated content (to avoid broken/malicious HTML code), the content which is mostly plain-text with some rare formatting. Comments on Github is one great example where Markdown is a perfect fit.

Static pages in Pootle are, err, _static_ (they are updated not often). And the content authoring is done by admins, not random users, so there's no need to artificially limit admins in what they can achieve.

Couple of examples:

1) When adding documentation/guides as static pages (this is the primary use case), we insert pictures there. In Markdown, there's no way to specify the width and height of the image, which would result in page reflow and thus poor user experience. In HTML, you can specify image size naturally.

2) In Pootle we have a simple contact form API to invoke contact form with pre-filled subject/body: 

``` html
<a data-action="contact" data-subject="I want to become a contributor">Contact Us</a>
```

With Markdown, we're losing this option.

When it comes to CSS, it's pretty strange to give admins the rights to add static content from the UI, and at the same time ask someone else to update Pootle deployment in case they need a particular string in a different style/color. Of course, if one uses the same styles over and over again in multiple static pages, they can eventually be externalized into a custom CSS. But people who author static pages need at least a way to prototype/tweak the rendering of static pages right from the UI.

If you feel that Markdown is absolutely necessary for some setups, we can add the support for it as an override plugin (which is, convert it on the fly to HTML in various places, including live preview, and add an override syntax highlighting profile for the editor). My gut feeling is that this is not worth doing, however (given the engineering effort to develop/maintain it and that in the end you will get a feature that is inherently limited as compared to what we have now).

I wonder if we should limit the height of the editor **and** the preview areas.

As a matter of fact, the CodeMirror editor defaults to a 300px height. It can be set to `auto` so it grows infinitely, and it can also be limited so it only grows up to a `max-height`.

We'll definitely want to limit the height of both components when the viewport is `< 1920px` (horizontal split), I'm unsure about the vertical split though.

Any feedback on this @iafan?

Yes, the height of both panes is supposed to fully fit into the window. You can adjust the height right away on window size change, disregarding the actual content height.


Resolving patch:
diff --git a/pootle/apps/staticpages/urls.py b/pootle/apps/staticpages/urls.py
--- a/pootle/apps/staticpages/urls.py
+++ b/pootle/apps/staticpages/urls.py
@@ -39,7 +39,16 @@
 )
 
 
+xhr_patterns = patterns('',
+    url(r'^preview/?$',
+        'staticpages.views.preview_content',
+        name='pootle-xhr-preview'),
+)
+
+
 urlpatterns = patterns('',
     url(r'^pages/',
         include(page_patterns)),
+    url(r'^xhr/',
+        include(xhr_patterns)),
 )
diff --git a/pootle/apps/staticpages/views.py b/pootle/apps/staticpages/views.py
--- a/pootle/apps/staticpages/views.py
+++ b/pootle/apps/staticpages/views.py
@@ -17,6 +17,7 @@
                                   UpdateView)
 
 from pootle.core.http import JsonResponse, JsonResponseBadRequest
+from pootle.core.markup.filters import apply_markup_filter
 from pootle.core.views import SuperuserRequiredMixin
 from pootle_misc.util import ajax_required
 
@@ -223,3 +224,16 @@ def legal_agreement(request):
 
     rendered_form = _get_rendered_agreement(request, form_class())
     return JsonResponse({'form': rendered_form})
+
+
+@ajax_required
+def preview_content(request):
+    """Returns content rendered based on the configured markup settings."""
+    if 'text' not in request.POST:
+        return JsonResponseBadRequest({
+            'msg': _('Text is missing'),
+        })
+
+    return JsonResponse({
+        'rendered': apply_markup_filter(request.POST['text']),
+    })


Test patch: