Partials improvementsmaster
@@ -191,16 +191,10 @@ class WikiPage(HookMixin): | |||
return len(cached_revs), True | |||
@property | |||
def partials(self): | |||
data = self.data | |||
if not data: | |||
return {} | |||
partials = {} | |||
meta = self._get_meta(data) | |||
if meta and 'import' in meta: | |||
for partial_name in meta['import']: | |||
partials[partial_name] = self.wiki.get_page(partial_name, sha=self.sha) | |||
return partials | |||
def imports(self): | |||
"""Names""" | |||
meta = self._get_meta(self.data) or {} | |||
return meta.get('import', []) | |||
@staticmethod | |||
def _get_meta(content): | |||
@@ -82,10 +82,26 @@ var deletePage = function() { | |||
bootbox.alert('Error deleting page!'); | |||
}); | |||
}; | |||
var last_imports = ''; | |||
var partials = []; | |||
var aced = new Aced({ | |||
editor: $('#entry-markdown-content').find('.editor').attr('id'), | |||
renderer: function(md) { return MDR.convert(md) }, | |||
renderer: function(md) { | |||
var doc = metaMarked(md); | |||
if (doc.meta && 'import' in doc.meta) { | |||
// If the imports have changed, refresh them from the server | |||
if (doc.meta['import'].toString() != last_imports) { | |||
last_imports = doc.meta['import'].toString(); | |||
$.getJSON('/_partials', {'imports': doc.meta['import']}, function (response) { | |||
partials = response['partials']; | |||
// TODO: Better way to force update of the preview here than this fake signal? | |||
aced.editor.session.doc._signal('change', | |||
{'action': 'insert', 'lines': [], 'start': {'row': 0}, 'end': {'row': 0}}); | |||
}); | |||
} | |||
} | |||
return MDR.convert(md, partials) | |||
}, | |||
info: Commit.info, | |||
submit: function(content) { | |||
var data = { | |||
@@ -8,22 +8,6 @@ | |||
</script> | |||
<script src="{{ url_for('wiki.static', filename='js/editor.js') }}"></script> | |||
{% if partials %} | |||
<script> | |||
$(function() { | |||
{% for name, value in partials.items() %} | |||
{% if name and value %} | |||
try { | |||
Handlebars.registerPartial({{ name|tojson|safe }}, {{ value.data|tojson|safe }}); | |||
} catch (e) { | |||
// no data? | |||
} | |||
{% endif %} | |||
{% endfor %} | |||
}); | |||
</script> | |||
{% endif %} | |||
{% if config.get('COLLABORATION') %} | |||
<script src="{{ url_for('wiki.static', filename='js/collaboration/main.js') }}"></script> | |||
{% endif %} | |||
@@ -23,12 +23,7 @@ | |||
{% block js %} | |||
<script> | |||
$(function(){ | |||
{% if partials %} | |||
{% for name, value in partials.items() %} | |||
Handlebars.registerPartial({{ name|tojson|safe }}, {{ value.data|tojson|safe }}); | |||
{% endfor %} | |||
{% endif %} | |||
$("#page-content").html(MDR.convert({{ page.data|tojson|safe }})).show(); | |||
$("#page-content").html(MDR.convert({{ page.data|tojson|safe }}, {{ partials|d([])|tojson|safe }})).show(); | |||
}); | |||
</script> | |||
{% endblock %} | |||
{% endblock %} |
@@ -1,5 +1,6 @@ | |||
from __future__ import absolute_import | |||
import collections | |||
import itertools | |||
import sys | |||
from datetime import datetime | |||
@@ -27,7 +28,9 @@ def commit(name, sha): | |||
if not data: | |||
abort(404) | |||
return render_template('wiki/page.html', name=name, page=data, commit=sha) | |||
partials = _partials(data.imports, sha=sha) | |||
return render_template('wiki/page.html', name=name, page=data, commit=sha, partials=partials) | |||
@blueprint.route(r"/_compare/<path:name>/<regex('\w+'):fsha><regex('\.{2,3}'):dots><regex('\w+'):lsha>") | |||
@@ -103,7 +106,6 @@ def history_data(name): | |||
} | |||
@blueprint.route("/_edit/<path:name>") | |||
@login_required | |||
def edit(name): | |||
@@ -120,8 +122,32 @@ def edit(name): | |||
content=page.data, | |||
# TODO: Remove this? See #148 | |||
info=next(page.history), | |||
sha=page.sha, | |||
partials=page.partials) | |||
sha=page.sha) | |||
def _partials(imports, sha='HEAD'): | |||
page_queue = collections.deque(imports) | |||
partials = collections.OrderedDict() | |||
while page_queue: | |||
page_name = page_queue.popleft() | |||
if page_name in partials: | |||
continue | |||
page = g.current_wiki.get_page(page_name, sha=sha) | |||
try: | |||
partials[page_name] = page.data | |||
except KeyError: | |||
partials[page_name] = "`Error importing wiki page '{0}'`".format(page_name) | |||
continue | |||
page_queue.extend(page.imports) | |||
# We want to retain the order (and reverse it) so that combining metadata from the imports works | |||
return list(reversed(partials.items())) | |||
@blueprint.route("/_partials") | |||
def partials(): | |||
if current_app.config.get('PRIVATE_WIKI') and current_user.is_anonymous(): | |||
return current_app.login_manager.unauthorized() | |||
return {'partials': _partials(request.args.getlist('imports[]'))} | |||
@blueprint.route("/_create/", defaults={'name': None}) | |||
@@ -245,6 +271,6 @@ def page(name): | |||
data = g.current_wiki.get_page(cname) | |||
if data: | |||
return render_template('wiki/page.html', name=cname, page=data, partials=data.partials) | |||
return render_template('wiki/page.html', name=cname, page=data, partials=_partials(data.imports)) | |||
else: | |||
return redirect(url_for('wiki.create', name=cname)) |
@@ -70,11 +70,12 @@ var MDR = { | |||
parse: function(md){ | |||
return markdownit.render(md); | |||
}, | |||
convert: function(md, sanitize) { | |||
convert: function(md, partials, sanitize) { | |||
if (this.sanitize !== null) { | |||
sanitize = this.sanitize; | |||
} | |||
this.md = md; | |||
this.partials = partials; | |||
this.processMeta(); | |||
try { | |||
var html = this.parse(this.md); | |||
@@ -105,7 +106,15 @@ var MDR = { | |||
processMeta: function() { | |||
var doc = metaMarked(this.md); | |||
this.md = doc.md; | |||
this.meta = doc.meta; | |||
var meta = this.meta = {}; | |||
if (this.partials) { | |||
$.each(this.partials, function(index, item) { | |||
var doc = metaMarked(item[1]); | |||
Handlebars.registerPartial(item[0], doc.md); | |||
$.extend(meta, doc.meta); | |||
}) | |||
} | |||
$.extend(this.meta, doc.meta); | |||
if (this.meta) { | |||
try { | |||
var template = Handlebars.compile(this.md); | |||