diff --git a/.gitignore b/.gitignore index b3ba0b7b..302584e6 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,9 @@ htmlcov/ node_modules/ .next/ example/db.sqlite3 + +# Emacs Temp/Autosaves +*~ +\#*\# +.#*.* +*_flymake* \ No newline at end of file diff --git a/djedi/admin/api.py b/djedi/admin/api.py index e18d0560..223853fb 100644 --- a/djedi/admin/api.py +++ b/djedi/admin/api.py @@ -1,4 +1,6 @@ from collections import defaultdict +from djedi.plugins.base import DjediPlugin + from django.core.exceptions import PermissionDenied from django.http import HttpResponse, Http404, HttpResponseBadRequest from django.utils.http import urlunquote @@ -193,11 +195,16 @@ def get(self, request, uri): try: uri = self.decode_uri(uri) uri = URI(uri) - plugins.resolve(uri) + plugin = plugins.resolve(uri) + plugin_context = self.get_context_data(uri=uri) + + if isinstance(plugin, DjediPlugin): + plugin_context = plugin.get_editor_context(**plugin_context) + except UnknownPlugin: raise Http404 else: - return self.render_plugin(request, self.get_context_data(uri=uri)) + return self.render_plugin(request, plugin_context) @never_cache def post(self, request, uri): diff --git a/djedi/plugins/base.py b/djedi/plugins/base.py new file mode 100644 index 00000000..d6796236 --- /dev/null +++ b/djedi/plugins/base.py @@ -0,0 +1,9 @@ +from cio.plugins.base import BasePlugin + + +class DjediPlugin(BasePlugin): + def get_editor_context(self, **kwargs): + """ + Returns custom context + """ + return kwargs diff --git a/djedi/plugins/form.py b/djedi/plugins/form.py new file mode 100644 index 00000000..e2ba83ae --- /dev/null +++ b/djedi/plugins/form.py @@ -0,0 +1,67 @@ +import json +from djedi.plugins.base import DjediPlugin +from django import forms + + +def deprefix(s): + # Remove prefix (anything including and before __) + return s.rpartition('__')[-1] + + +def get_custom_render_widget(cls): + class CustomRenderWidget(cls): + def render(self, *args, **kwargs): + name = kwargs.pop("name", None) + + if not name: + name = args[0] + args = args[1:] + + name = deprefix(name) + + return super(CustomRenderWidget, self).render( + "data[%s]" % name, + *args, + **kwargs + ) + + return CustomRenderWidget + + +class BaseEditorForm(forms.Form): + def __init__(self, *args, **kwargs): + super(BaseEditorForm, self).__init__(*args, **kwargs) + + for field in list(self.fields.keys()): + self.fields[field].widget.__class__ = get_custom_render_widget( + self.fields[field].widget.__class__ + ) + + +class FormsBasePlugin(DjediPlugin): + ext = None + + @property + def forms(self): + return {} + + def get_editor_context(self, **context): + context.update( + {"forms": { + tab: form() + for tab, form in self.forms.items() + }} + ) + + return context + + def save(self, data, dumps=True): + data = self.collect_forms_data(data) + return json.dumps(data) if dumps else data + + def collect_forms_data(self, data): + return { + deprefix(field): data.get(deprefix(field)) + for tab, form in self.forms.items() + for field in form.base_fields.keys() + } diff --git a/djedi/plugins/img.py b/djedi/plugins/img.py index ea5f4c91..69debb15 100644 --- a/djedi/plugins/img.py +++ b/djedi/plugins/img.py @@ -1,16 +1,44 @@ import json import six from django.utils.html import escape -from cio.plugins.base import BasePlugin from django.core.files.uploadedfile import InMemoryUploadedFile +from django import forms from hashlib import sha1 from os import path +from .form import FormsBasePlugin, BaseEditorForm -class ImagePluginBase(BasePlugin): +class DataForm(BaseEditorForm): + data__id = forms.CharField( + label="ID", + max_length=255, + required=False, + widget=forms.TextInput(attrs={"class": "form-control"}), + ) + + data__alt = forms.CharField( + label="Alt text", + max_length=255, + required=False, + widget=forms.TextInput(attrs={"class": "form-control"}), + ) + + data__class = forms.CharField( + label="Class", + max_length=255, + required=False, + widget=forms.TextInput(attrs={"class": "form-control"}), + ) + + +class ImagePluginBase(FormsBasePlugin): ext = 'img' + @property + def forms(self): + return {'HTML': DataForm} + def _open(self, filename): raise NotImplementedError @@ -101,14 +129,12 @@ def save(self, data): if file: file.close() - content = { + content = super(ImagePluginBase, self).save(data, dumps=False) + content.update({ 'filename': filename, 'width': width, 'height': height, - 'id': data.get('id') or None, - 'class': data.get('class') or None, - 'alt': data.get('alt') or None - } + }) return json.dumps(content) @@ -126,23 +152,27 @@ def render(self, data): 'width': 160, 'height': 90 } + if data: url = data.get('url') - width = data.get('width') or 0 - height = data.get('height') or 0 - alt = data.get('alt') or '' - tag_id = data.get('id') - tag_class = data.get('class') if url: attrs['src'] = url - attrs['alt'] = alt + + width = data.get('width') or 0 + height = data.get('height') or 0 if width and height: attrs['width'] = width attrs['height'] = height - if tag_id: - attrs['id'] = tag_id - if tag_class: - attrs['class'] = tag_class + + attrs['alt'] = data.get('alt') or '' + + attr_id = data.get('id') + if attr_id: + attrs['id'] = attr_id + + attr_class = data.get('class') + if attr_class: + attrs['class'] = attr_class html_attrs = (u'{0}="{1}"'.format(attr, escape(attrs[attr])) for attr in sorted(attrs.keys())) return u''.format(u' '.join(html_attrs)) diff --git a/djedi/static/djedi/plugins/img/js/img.coffee b/djedi/static/djedi/plugins/img/js/img.coffee index 1f0ae0df..29b407e1 100644 --- a/djedi/static/djedi/plugins/img/js/img.coffee +++ b/djedi/static/djedi/plugins/img/js/img.coffee @@ -375,13 +375,19 @@ class window.ImageEditor extends window.Editor @firstRender = false updateForm: (data) -> + # Hardcoded fields $("input[name='data[filename]']").val data.filename + $("input[name='data[crop]']").val '' $("input[name='data[width]']").val data.width $("input[name='data[height]']").val data.height - $("input[name='data[crop]']").val '' - $("input[name='data[id]']").val data.id - $("input[name='data[class]']").val data.class - $("input[name='data[alt]']").val data.alt + delete data.filename + delete data.width + delete data.height + + # Form fields + for k, v of data + $("input[name='data[#{k}]']").val v + @ratioButton.removeClass 'active' renderThumbnail: (url) -> diff --git a/djedi/static/djedi/plugins/img/js/img.js b/djedi/static/djedi/plugins/img/js/img.js index 990aed44..419e8b4e 100644 --- a/djedi/static/djedi/plugins/img/js/img.js +++ b/djedi/static/djedi/plugins/img/js/img.js @@ -425,13 +425,18 @@ }; ImageEditor.prototype.updateForm = function(data) { + var k, v; $("input[name='data[filename]']").val(data.filename); + $("input[name='data[crop]']").val(''); $("input[name='data[width]']").val(data.width); $("input[name='data[height]']").val(data.height); - $("input[name='data[crop]']").val(''); - $("input[name='data[id]']").val(data.id); - $("input[name='data[class]']").val(data["class"]); - $("input[name='data[alt]']").val(data.alt); + delete data.filename; + delete data.width; + delete data.height; + for (k in data) { + v = data[k]; + $("input[name='data[" + k + "]']").val(v); + } return this.ratioButton.removeClass('active'); }; diff --git a/djedi/templates/djedi/plugins/img/editor.html b/djedi/templates/djedi/plugins/img/editor.html index 4b94ff3c..5769f38b 100644 --- a/djedi/templates/djedi/plugins/img/editor.html +++ b/djedi/templates/djedi/plugins/img/editor.html @@ -9,7 +9,9 @@ {% block tabs %}
{% endblock tabs %} @@ -29,28 +31,21 @@ -