1. Osiloke Emoekpere
  2. mezzanine_widgets

Commits

Osiloke Emoekpere  committed bcf6692

more enhancements

  • Participants
  • Parent commits acc3d1c
  • Branches enhancements

Comments (0)

Files changed (8)

File widget/forms.py

View file
  • Ignore whitespace
 from os.path import join
 
 from django import forms
+from django.forms.widgets import HiddenInput
 from mezzanine.core.models import CONTENT_STATUS_CHOICES, CONTENT_STATUS_DRAFT
 
 from widget.widget_pool import get_widget_options, WidgetHasNoOptions
 
 from mezzanine.pages.models import Page
 import option_fields as fields
+
+from easyweb.apps.core import widget_fields
 from mezzanine.conf import settings
-from mezzanine.forms.forms import fs
-
 from uuid import uuid4
 
 
     def __init__(self, *args, **kwargs):
         super(WidgetForm, self).__init__(*args, **kwargs)
         self.uuid = str(uuid4())
+        self.fields["page"].queryset = Page.objects.get_query_set()
+
 
     class Meta:
         model = Widget
                     option.value = value
                     option.save()
         return True
+
+
+def ModelFormForWidget(widget_model, fields=None, widget=None):
+    meta_data = { "model":widget_model, }
+    #Left over from mezzanine
+    try:
+        widget_overrides = settings.WIDGET_OVERRIDES
+    except AttributeError:
+        widget_overrides = {}
+
+    if fields:
+        meta_data.update({"fields": fields})
+
+    if widget:
+        widgets = {
+            'widget': HiddenInput(),
+            }
+        meta_data.update({"widgets": widgets})
+
+    meta = type('Meta', (), meta_data)
+
+    class WidgetModelForm(forms.ModelForm):
+        def __init__(self, *args, **kwargs):
+            super(WidgetModelForm, self).__init__(*args, **kwargs)
+            self.uuid = str(uuid4())
+            for f in self.fields.keys():
+#                'Make page model content type id a hidden field'
+#                if parent_model == f: self.fields[f].widget = forms.HiddenInput()
+#                if f in hidden_fields: self.fields[f].widget = forms.HiddenInput()
+                field_class = self.fields[f].__class__
+                try:
+                    field_type = widget_overrides[field_class]
+                except KeyError:
+                    pass
+                else:
+                    self.fields[f].widget = widget_fields.WIDGETS[field_type]()
+                css_class = self.fields[f].widget.attrs.get("class", "")
+                css_class += " " + field_class.__name__.lower()
+                self.fields[f].widget.attrs["class"] = css_class
+                self.fields[f].widget.attrs["id"] = "%s" % (f)
+
+    modelform_class = type('modelform', (WidgetModelForm,), {"Meta": meta})
+    return modelform_class

File widget/models.py

View file
  • Ignore whitespace
 from datetime import datetime
 
-from django.contrib.sites.managers import CurrentSiteManager
 from django.contrib.sites.models import Site
 from django.utils.translation import ugettext as _, ugettext
 from django.db import models
 
 from mezzanine.conf import settings
-from mezzanine.core.managers import PublishedManager, SearchableManager
+from mezzanine.core.managers import PublishedManager, SearchableManager, CurrentSiteManager
 from mezzanine.core.models import Orderable, Displayable, \
     CONTENT_STATUS_CHOICES, CONTENT_STATUS_DRAFT, Ownable, SiteRelated
+from easyweb.utilities.admin import reversion_models
 from .option_fields import TEXT
 from mezzanine.pages.models import Page
 
     """
     Base class for all widget plugin classes
     """
+    editableFields = ""
     template = None
     raw = False 
 
     widget = models.ForeignKey('widget.Widget')
 
     def __unicode__(self):
-        return u'Model for widget <%s>' % widget.widget_class
+        return u'Model for widget <%s>' % self.widget.widget_class
 
 
 class WidgetManager(CurrentSiteManager, PublishedManager, SearchableManager):
     and ``SearchableManager`` for the ``Widget`` model.
 
     """
-    pass
+    def widget_models(self):
+        return WidgetModel.objects.filter(widget=self)
 
 
 class Widget(Orderable, Ownable, SiteRelated):
     expiry_date = models.DateTimeField(_("Expires on"),
         help_text=_("With published checked, won't be shown after this time"),
         blank=True, null=True)
-#    site = models.ForeignKey(Site, editable=False)
+
 
     objects = WidgetManager()
     search_fields = {"keywords": 10, "display_title": 5}

File widget/static/widget/css/widget.css

View file
  • Ignore whitespace
 
 .widget_holder { -moz-transition:border-top-width 0.1s ease-in; -webkit-transition:border-top-width 0.1s ease-in; border-top:0px solid rgba(0,0,0,0); }
 .marker {
+    width:100%;
     float:left;
     opacity:0.0;
     background: #f0f0f0;
-    border:1px dashed #ddd;
+    border:1px dashed #000;
     visibility: visible !important;
+}
+.placeholder {
+    width: 100%;
+    /*margin: -2px;*/
+    background: #717ca1;
+    height: 1em;
 }

File widget/templates/widget/options.html

View file
  • Ignore whitespace
         {% endif %}
     </div>
 {% endfor %}
-
+{% for field in model_form %}
+    <div class="controls" {% if field.is_hidden %} style="display:none;"{% endif %}>
+    {{ field.label_tag }}{{ field }}{{ field.errors }}
+    {% if field.help_text %}
+    <p class="helptext">{{ field.help_text }}</p>
+    {% endif %}
+    </div>
+{% endfor %}

File widget/utilities.py

View file
  • Ignore whitespace
 from copy import copy
+from exceptions import Exception
 from django.http import HttpResponse
- 
+from django.template import Template
+from widget.forms import ModelFormForWidget
+from widget.models import WidgetModel
+
 
 __author__ = 'osilocks'
 
         'valid': False,
         'errors': final_errors,
     })
-    return data
+    return data
+
+
+def get_model_form_for_widget(widget_class_obj, data={}, widget=None, instance=None):
+    if hasattr(widget_class_obj, "model") and hasattr(widget_class_obj, "single"):
+        if widget:
+            fields = widget_class_obj.editableFields + ",widget"
+        else:
+            fields = widget_class_obj.editableFields
+
+        data_data = data.get("POST",None)
+        if data_data:
+            data_data = dict((key,value) for key, value in data_data.iteritems())
+            if widget:
+                data_data.update({"widget":widget.id})
+
+        model_form = ModelFormForWidget(widget_class_obj.model, fields=tuple(fields.split(',')), widget=widget) \
+                            (data_data, files=data.get("FILES", None), instance=instance)
+
+        return model_form
+    return None
+
+
+def get_widget_list_for_widget(widget):
+    try:
+        all_classes = get_all_widget_widgets()
+        list = Template('widget/list.html')
+        c = {'widgets': all_classes, 'widget_id': widget.id}
+
+        return c
+    except Exception:
+        return None
+
+
+def hasModel(widget_class_obj):
+    return hasattr(widget_class_obj, "model") and hasattr(widget_class_obj, "single")
+
+
+def get_widget_model_queryset(widget, widget_class):
+    try:
+        if hasattr(widget_class, 'model'):
+            'Widget class is associated with a model'
+            model = widget_class.model
+            if model and WidgetModel in (model.__bases__):
+                'The widget model has to subclass the WidgetModel class'
+                model_queryset = model.objects.filter(widget=widget)
+                if len(model_queryset):
+                    if hasattr(widget_class, 'single'):
+                        return model_queryset[0]
+                    return model_queryset
+    except Exception:
+        raise
+    return None

File widget/views.py

View file
  • Ignore whitespace
 from django.http import HttpResponse, HttpResponseRedirect
 from django.shortcuts import render_to_response
 from django.template import RequestContext
-from django.template.base import Template
-from django.views.decorators.csrf import ensure_csrf_cookie
 from django.views.decorators.http import require_POST
 from django.utils.translation import ugettext_lazy as _
 from django.views.decorators.http import require_http_methods
 from mezzanine.utils.views import is_editable
 from mezzanine.core.models import CONTENT_STATUS_PUBLISHED, CONTENT_STATUS_DRAFT
 
-from widget.utilities import  LazyEncoder, ajax_view
+from widget.utilities import  LazyEncoder, ajax_view, get_model_form_for_widget, hasModel, get_widget_model_queryset
 from widget.forms import WidgetForm, WidgetOptionsForm
-from widget.widget_pool import get_all_page_widgets, get_widget, WidgetHasNoOptions
+from widget.widget_pool import  get_widget, WidgetHasNoOptions
 from widget.utilities import admin_can
 from widget.models import Widget
 from widget.utilities import ajaxerror
 
 json_serializer = LazyEncoder()
 
-
-def get_widget_list_for_widget(widget):
-    try:
-        all_classes = get_all_widget_widgets()
-        list = Template('widget/list.html')
-        c = {'widgets': all_classes, 'widget_id': widget.id}
-
-        return c
-    except Exception:
-        return None
-
 @login_required
 @admin_can(Widget, action="change", fail404=True)
 def edit_widget(request, **kwargs):
     try:
+
+        widget = Widget.objects.get(id=kwargs.get("id"))
+        widget_class_obj = get_widget(widget.widget_class)
+        containsModel = hasModel(widget_class_obj)
+
         if request.POST:
             "get form populated with widget options"
-            widget = Widget.objects.get(id=kwargs.get("id"))
             options_form = WidgetOptionsForm(widget.widget_class, \
                                 request.POST)
             if options_form.is_valid():
                     data = {'valid': True, 'form': 'saved'}
             elif options_form.errors:
                 data = ajaxerror(options_form)
+            if containsModel:
+                obj = get_widget_model_queryset(widget, widget_class_obj)
+                model_form = get_model_form_for_widget(widget_class_obj, \
+                        {"POST":request.POST, "FILES":request.FILES}, instance=obj, widget=widget)
+                try:
+                    if model_form.is_valid():
+                        saved_obj=model_form.save()
+                        data.update({"obj": saved_obj.id})
+                    elif model_form.errors:
+                        model_data = ajaxerror(model_form)
+                        errors = dict(data.get("errors", {}), **model_data["errors"])
+                        data = {'valid': False, "errors": errors }
+                except Exception:
+                    raise
         else:
             "This is a request to get a form for widget"
             ctx = RequestContext(request)
-            "get widget form populated with widget options" 
-            widget = Widget.objects.get(id=kwargs.get("id"))
+            "get widget form populated with widget options"
+
             initial = {'status': widget.status}
             if widget.hasOptions:
                 initial.update(dict(("option_%s" % option.name, option.value) \
 
             o = get_template("widget/options.html")
             ctx.update({'options_form': options_form})
+            if containsModel:
+                obj = get_widget_model_queryset(widget, widget_class_obj)
+                model_form = get_model_form_for_widget(widget_class_obj, instance=obj, widget=widget)
+                if model_form:
+                    ctx.update({'model_form': model_form})
 
             options = o.render(ctx)
 
                             mimetype='application/json')
     except Exception:
         raise
+
+
 @login_required
 @admin_can(Widget)
 def widget_list(request):
             widget_class = request.POST["widget_class"]
             widget_class_obj = get_widget(widget_class)
 
-#            if hasattr(widget_class_obj, "options"):
+
             "Widget has options, lets generate the options form"
             options_form = WidgetOptionsForm(widget_class)
             if widget_form.is_valid():
                 o = get_template("widget/options.html")
                 ctx.update({'options_form': options_form,
                             'widget_class': widget_class_obj })
+                model_form = get_model_form_for_widget(widget_class_obj)
+                if model_form:
+                    ctx.update({'model_form': model_form})
 
                 options = o.render(ctx)
                 data = {'valid': False, 'type':'fi', 'data':options}
     else:
         if request.POST:
             widget_class = request.POST["widget_class"]
+            widget_class_obj = get_widget(widget_class)
+            containsModel = hasModel(widget_class_obj)
+
             slot = request.POST["widgetslot"]
             try:
-#                widget_obj = Page.objects.published(request.user)\
-#                                .get(id=request.POST["widget"])
                 page = Page.objects.get(id=request.POST["page"])
+                print page
+                ### HANDLE OPTIONS FORM ####
                 options_form = WidgetOptionsForm(widget_class, request.POST, request.FILES)
+                widget = None
                 if options_form.is_valid():
                     try:
                         "update widget if it exists"
                         data = {'valid': True, 'form': 'saved'}
                 elif options_form.errors:
                     data = ajaxerror(options_form)
+
+
+                if widget is None and not options_form.hasOptions and containsModel:
+                    try:
+                        "update widget if it exists"
+                        widget = Widget.objects.get(id=request.POST["widget"])
+                    except Exception:
+                        widget = Widget(widgetslot=slot,
+                            widget_class=widget_class,
+                            user=request.user, page=page)
+                        widget.save()
+
+
+                model_widget = None
+                if widget: model_widget = widget
+                model_form = get_model_form_for_widget(widget_class_obj, {"POST":request.POST, "FILES":request.FILES}, widget=model_widget)
+                if model_form:
+                    try:
+                        if model_form.is_valid():
+                            saved_obj=model_form.save()
+                            data.update({"obj": saved_obj.id})
+                        elif model_form.errors:
+                            model_data = ajaxerror(model_form)
+                            errors = dict(data.get("errors", {}), **model_data["errors"])
+                            data = {'valid': False, "errors": errors }
+                    except Exception:
+                        raise
             except Exception, e:
-                data = {"valid": "false", "error": { "_all_": ["Something went wrong, please refresh the widget"], "exception": e.message}}
+                data = {"valid": False, "errors": { "_all_": ["Something went wrong, please refresh the page"], "exception": e.message}}
 
     return HttpResponse(json_serializer.encode(data),\
                                  mimetype='application/json')
 
 
 @login_required
-@admin_can(Widget, action="change")
+@admin_can(Widget, action="delete")
 def delete_widget(request, id):
+
+    data = {'valid': False}
     try:
         obj = Widget.objects.get(id=id)
         obj.delete()
+        data = {'valid': True}
     except Exception:
         pass
+    return HttpResponse(json_serializer.encode(data),\
+        mimetype='application/json')
 
 @login_required
 @ajax_view()
             data = {'status':False, 'error':str(e)}
     return HttpResponse(json_serializer.encode(data),\
         mimetype='application/json')
+
+
 @login_required
 @require_http_methods(["POST"])
 @admin_can(Widget, action="change")

File widget/widget_pool.py

View file
  • Ignore whitespace
     except Exception:
         raise WidgetNotFound
 
+def get_widget_model(name):
+    try:
+        w = get_widget(name)
+        return w.model
+    except WidgetNotFound:
+        raise
+    except Exception:
+        return None
 
 def get_all_page_widgets():
     autodiscover()

File widget/widget_renderer.py

View file
  • Ignore whitespace
 
-from widget.models import  Widget, WidgetModel
+from widget.models import  Widget
+from widget.utilities import get_widget_model_queryset
 from widget.widget_pool import get_widget
 
 from django.template.loader import render_to_string, get_template_from_string
 
     return rendered_widgets
 
-def get_widget_model_queryset(widget, widget_class):
-    try:
-        if hasattr(widget_class, 'model'):
-            'Widget class is associated with a model'
-            model = widget_class.model
-            if model and WidgetModel in (model.__bases__):
-                'The widget model has to subclass the WidgetModel class'
-                model_queryset = model.objects.filter(widget=widget)
-                if len(model_queryset):
-                    return model_queryset
-    except Exception:
-        raise
-    return None
+