Commit 45b67b27 by benjaoming

Adding RevisionPlugin. Images plugin becoming a plugin with its own revision…

Adding RevisionPlugin. Images plugin becoming a plugin with its own revision system. Fixing anonymous settings for attachments plugin.
parent d58dcbc7
......@@ -9,9 +9,11 @@ ADMINS = (
# ('Your Name', 'your_email@example.com'),
)
from django.core.urlresolvers import reverse_lazy
#from django.core.urlresolvers import reverse_lazy
#LOGIN_REDIRECT_URL = reverse_lazy('wiki:get', kwargs={'path': ''})
LOGIN_REDIRECT_URL = reverse_lazy('wiki:get', kwargs={'path': ''})
# This forces the wiki login view to redirect to the referer...
LOGIN_REDIRECT_URL = None
LOGIN_URL = '/_accounts/login/'
LOGOUT_URL = '/_accounts/logout/'
......@@ -140,3 +142,5 @@ LOGGING = {
},
}
}
WIKI_ANONYMOUS_WRITE = True
\ No newline at end of file
......@@ -4,11 +4,7 @@ from django.utils.translation import ugettext_lazy as _
from mptt.admin import MPTTModelAdmin
from django import forms
from django.forms.widgets import HiddenInput
from django.core.urlresolvers import get_callable
import models
from conf import settings
import editors
class ArticleObjectAdmin(GenericTabularInline):
......@@ -56,7 +52,7 @@ class ArticleForm(forms.ModelForm):
self.fields['current_revision'].queryset = revisions
else:
self.fields['current_revision'].queryset = models.ArticleRevision.objects.get_empty_query_set()
self.fields['current_revision'].widget = HiddenInput()
self.fields['current_revision'].widget = forms.HiddenInput()
class ArticleAdmin(admin.ModelAdmin):
inlines = [ArticleRevisionInline]
......
......@@ -102,7 +102,7 @@ class Article(models.Model):
for decendant in self.decendant_objects():
if decendant.INHERIT_PERMISSIONS:
decendant.owner = self.owner
def add_revision(self, new_revision, save=True):
"""
Sets the properties of a revision and ensures its the current
......
......@@ -65,14 +65,14 @@ class ReusablePlugin(ArticlePlugin):
articles = models.ManyToManyField(Article, related_name='shared_plugins_set')
# Permission methods - you may override these, if they don't fit your logic.
def can_read(self, *args, **kwargs):
def can_read(self, **kwargs):
if self.article:
return self.article.can_read(*args, **kwargs)
return self.article.can_read(**kwargs)
return False
def can_write(self, *args, **kwargs):
def can_write(self, **kwargs):
if self.article:
return self.article.can_write(*args, **kwargs)
return self.article.can_write(**kwargs)
return False
def save(self, *args, **kwargs):
......@@ -151,9 +151,36 @@ class RevisionPlugin(ArticlePlugin):
'If you need to do a roll-back, simply change the value of this field.'),
)
# Permissions... overwrite if necessary
def can_read(self, **kwargs):
return self.article.can_read(self, **kwargs)
def can_write(self, **kwargs):
return self.article.can_write(self, **kwargs)
def add_revision(self, new_revision, save=True):
"""
Sets the properties of a revision and ensures its the current
revision.
"""
assert self.id or save, ('RevisionPluginRevision.add_revision: Sorry, you cannot add a'
'revision to a plugin that has not been saved '
'without using save=True')
if not self.id: self.save()
revisions = self.revision_set.all()
try:
new_revision.revision_number = revisions.latest().revision_number + 1
except RevisionPluginRevision.DoesNotExist:
new_revision.revision_number = 0
new_revision.plugin = self
new_revision.previous_revision = self.current_revision
if save: new_revision.save()
self.current_revision = new_revision
if save: self.save()
class Meta:
app_label = settings.APP_LABEL
class RevisionPluginRevision(BaseRevisionMixin, models.Model):
"""
If you want your plugin to maintain revisions, make an extra model
......@@ -162,7 +189,7 @@ class RevisionPluginRevision(BaseRevisionMixin, models.Model):
(this class is very much copied from wiki.models.article.ArticleRevision
"""
plugin = models.ForeignKey(RevisionPlugin)
plugin = models.ForeignKey(RevisionPlugin, related_name='revision_set')
def save(self, *args, **kwargs):
if (not self.id and
......@@ -175,9 +202,9 @@ class RevisionPluginRevision(BaseRevisionMixin, models.Model):
if not self.revision_number:
try:
previous_revision = self.article.articlerevision_set.latest()
previous_revision = self.plugin.revision_set.latest()
self.revision_number = previous_revision.revision_number + 1
except ArticleRevision.DoesNotExist:
except RevisionPluginRevision.DoesNotExist:
self.revision_number = 1
super(RevisionPluginRevision, self).save(*args, **kwargs)
......@@ -187,29 +214,9 @@ class RevisionPluginRevision(BaseRevisionMixin, models.Model):
self.plugin.current_revision = self
self.plugin.save()
def add_revision(self, new_revision, save=True):
"""
Sets the properties of a revision and ensures its the current
revision.
"""
assert self.id or save, ('RevisionPluginRevision.add_revision: Sorry, you cannot add a'
'revision to a plugin that has not been saved '
'without using save=True')
if not self.id: self.save()
revisions = self.pluginrevision_set.all()
try:
new_revision.revision_number = revisions.latest().revision_number + 1
except RevisionPlugin.DoesNotExist:
new_revision.revision_number = 0
new_revision.plugin = self
new_revision.previous_revision = self.current_revision
if save: new_revision.save()
self.current_revision = new_revision
if save: self.save()
class Meta:
app_label = settings.APP_LABEL
get_latest_by = ('revision_number',)
######################################################
# SIGNAL HANDLERS
......
......@@ -23,6 +23,12 @@ class Attachment(ReusablePlugin):
original_filename = models.CharField(max_length=256, verbose_name=_(u'original filename'), blank=True, null=True)
def can_write(self, **kwargs):
user = kwargs.get('user', None)
if not settings.ANONYMOUS and (not user or user.is_anonymous()):
return False
return ReusablePlugin.can_write(self, **kwargs)
class Meta:
verbose_name = _(u'attachment')
verbose_name_plural = _(u'attachments')
......
......@@ -11,6 +11,7 @@ from django.views.generic.base import TemplateView, View
from django.views.generic.edit import FormView
from django.views.generic.list import ListView
from wiki.conf import settings as wiki_settings
from wiki.core.http import send_file
from wiki.decorators import get_article
from wiki.plugins.attachments import models, settings, forms
......@@ -94,6 +95,8 @@ class AttachmentReplaceView(ArticleMixin, FormView):
@method_decorator(get_article(can_read=True))
def dispatch(self, request, article, attachment_id, *args, **kwargs):
self.attachment = get_object_or_404(models.Attachment.objects.active(), id=attachment_id, articles=article)
if not self.attachment.can_write(user=request.user):
return redirect(wiki_settings.LOGIN_URL)
return super(AttachmentReplaceView, self).dispatch(request, article, *args, **kwargs)
def form_valid(self, form):
......
from django.contrib import admin
from django import forms
import models
class ImageForm(forms.ModelForm):
class Meta:
model = models.Image
def __init__(self, *args, **kwargs):
super(ImageForm, self).__init__(*args, **kwargs)
if self.instance.pk:
revisions = models.ImageRevision.objects.filter(plugin=self.instance)
self.fields['current_revision'].queryset = revisions
else:
self.fields['current_revision'].queryset = models.ImageRevision.objects.get_empty_query_set()
self.fields['current_revision'].widget = forms.HiddenInput()
class ImageRevisionInline(admin.TabularInline):
model = models.ImageRevision
extra = 1
fields = ('image', 'locked', 'deleted')
class ImageAdmin(admin.ModelAdmin):
form = ImageForm
inlines = (ImageRevisionInline,)
admin.site.register(models.Image, ImageAdmin)
\ No newline at end of file
......@@ -7,13 +7,24 @@ from wiki.plugins.images import models
class SidebarForm(forms.ModelForm, PluginSidebarFormMixin):
def __init__(self, *args, **kwargs):
self.article = kwargs.pop('article')
def __init__(self, article, user, *args, **kwargs):
self.article = article
self.user = user
super(SidebarForm, self).__init__(*args, **kwargs)
def get_usermessage(self):
return _(u"New image %s was successfully uploaded. You can use it by selecting it from the list of available images.") % self.instance.get_filename()
def save(self, *args, **kwargs):
if not self.instance.id:
image = models.Image()
image.article = self.article
kwargs['commit'] = False
revision = super(SidebarForm, self).save(*args, **kwargs)
image.add_revision(self.instance, save=True)
return revision
return super(SidebarForm, self).save(*args, **kwargs)
class Meta:
model = models.ImageRevision
fields = ('image',)
\ No newline at end of file
......@@ -10,28 +10,54 @@ from wiki.models.pluginbase import RevisionPlugin, RevisionPluginRevision
if not "sorl.thumbnail" in django_settings.INSTALLED_APPS:
raise ImproperlyConfigured('wiki.plugins.images: needs sorl.thumbnail in INSTALLED_APPS')
def upload_path(instance, filename):
from os import path
# Has to match original extension filename
upload_path = settings.UPLOAD_PATH
upload_path = upload_path.replace('%aid', str(instance.image.article.id))
if settings.UPLOAD_PATH_OBSCURIFY:
import random, hashlib
m=hashlib.md5(str(random.randint(0,100000000000000)))
upload_path = path.join(upload_path, m.hexdigest())
return path.join(upload_path, filename)
class Image(RevisionPlugin):
# The plugin system is so awesome that the inheritor doesn't need to do
# anything! :D
def can_write(self, **kwargs):
user = kwargs.get('user', None)
if not settings.ANONYMOUS and (not user or user.is_anonymous()):
return False
return RevisionPlugin.can_write(self, **kwargs)
class Meta:
verbose_name = _(u'image')
verbose_name_plural = _(u'images')
app_label = settings.APP_LABEL
def __unicode__(self):
return _(u'Image: %s') % self.current_revision.get_filename()
title = (_(u'Image: %s') % self.current_revision.imagerevision.get_filename()) if self.current_revision else _(u'Current revision not set!!')
return unicode(title)
class ImageRevision(RevisionPluginRevision):
image = models.ImageField(upload_to=settings.IMAGE_PATH,
image = models.ImageField(upload_to=upload_path,
max_length=2000)
def get_filename(self):
if self.image:
return self.image.path.split('/')[-1]
def get_size(self):
"""Used to retrieve the file size and not cause exceptions."""
try:
return self.file.size
except ValueError:
return None
class Meta:
verbose_name = _(u'image revision')
verbose_name_plural = _(u'image revisions')
......
from django.conf import settings as django_settings
# Where to store images
IMAGE_PATH = getattr(django_settings, 'WIKI_IMAGE_PATH', "wiki/images/%aid/")
UPLOAD_PATH = getattr(django_settings, 'WIKI_IMAGE_PATH', "wiki/images/%aid/")
# Should the upload path be obscurified? If so, a random hash will be added to the path
# such that someone can not guess the location of files (if you have
# restricted permissions and the files are still located within the web server's
UPLOAD_PATH_OBSCURIFY = getattr(django_settings, 'WIKI_UPLOAD_PATH_OBSCURIFY', True)
# Allow anonymous users to upload (not nice on an open network)
ANONYMOUS = getattr(django_settings, 'WIKI_ATTACHMENTS_ANONYMOUS', False)
......
{% extends "wiki/article.html" %}
{% load wiki_tags i18n humanize %}
{% load url from future %}
{% block pagetitle %}{% trans "Images" %}: {{ article.current_revision.title }}{% endblock %}
{% block wiki_contents_tab %}
<p class="lead">{% trans "The following images are available for this article. Copy the markdown tag to directly refer to an image from the article text." %}</p>
<p>
<a href="{% url 'wiki:edit' path=urlpath.path article_id=article.id %}" class="btn btn-large">
<span class="icon-arrow-left"></span>
{% trans "Back to edit page" %}
</a>
</p>
<table class="table table-bordered table-striped" style="width: 100%;">
<tr>
<th>{% trans "Image" %}</th>
<th>{% trans "Markdown tag" %}</th>
<th>{% trans "Uploaded by" %}</th>
<th>{% trans "Size" %}</th>
</tr>
{% for image in images %}
<tr>
<td><code>[image:{{ image.id }}]</code></td>
<td>
{% if image.current_revision.user %}{{ image.current_revision.user }}{% else %}{% if user|is_moderator %}{{ image.current_revision.ip_address|default:"anonymous (IP not logged)" }}{% else %}{% trans "anonymous (IP logged)" %}{% endif %}{% endif %}
</td>
<td>{{ image.current_revision.get_size|filesizeformat }}</td>
</tr>
{% empty %}
<tr>
<td colspan="100">
<p style="margin-bottom: 20px;"><em>{% trans "There are no images for this article." %}</em></p>
</td>
{% endfor %}
</table>
{% endblock %}
......@@ -5,57 +5,83 @@
<p>{% trans "Click on an image below to insert in your text. The format of the code inserted is:" %}<br /><code>[image:id alignment caption text]</code></p>
<table class="table table-striped">
{% for image in article|images_for_article %}
<tr>
<td>
{% thumbnail image.image "100x50" crop="center" as thumb %}
<img src="{{ thumb.url }}" alt="{{ image.get_filename }}" width="{{ thumb.width }}" height="{{ thumb.height }}" />
<div style="max-height: 300px; overflow: auto;">
<table class="table table-striped">
{% for image in article|images_for_article %}
{% thumbnail image.image "150x50" crop="center" as thumb %}
<tr>
<td>
<div class="thumbnail">
<img src="{{ thumb.url }}" alt="{{ image.get_filename }}" />
</div>
</td>
<td>
<span class="label">
{% trans "uploaded" %} {{ image.created|naturaltime }}
</span>
</td>
</tr>
{% endthumbnail %}
</td>
<td><span class="label">{{ image.created|naturaltime }}</span></td>
</tr>
{% endfor %}
</table>
{% empty %}
<tr>
<td><em>{% trans "No images found for this article" %}</em></td>
</tr>
{% endfor %}
</table>
</div>
<p>
<a href="{% url 'wiki:images_index' path=urlpath.path article_id=article.id %}">
{% trans "Manage images" %} &raquo;
</a>
</p>
{% if article|can_write:user %}
<hr />
<h4>{% trans "Add new image" %}</h4>
{% if form.non_field_errors %}
{% if form_error_title %}<h4 class="alert-heading">{{ form_error_title }}</h4>{% endif %}
{% for error_message in form.non_field_errors %}
<div class="alert alert-block alert-error">
{{ error_message }}
</div>
{% endfor %}
{% endif %}
{% for field in form %}
<p id="div_{{ field.auto_id }}" class="fields {% if field.errors %} error{% endif %}">
{% if field.label %}
<!--<label for="{{ field.id_for_label }}" class="{% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}
</label>-->
{% endif %}
{{ field }}
{% if field.errors %}
{% for error in field.errors %}
<div id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-block"><strong>{{ error }}</strong></div>
{% if article|images_can_add:user %}
{% if form.non_field_errors %}
{% if form_error_title %}<h4 class="alert-heading">{{ form_error_title }}</h4>{% endif %}
{% for error_message in form.non_field_errors %}
<div class="alert alert-block alert-error">
{{ error_message }}
</div>
{% endfor %}
{% endif %}
</p>
{% if field.help_text %}
<p id="hint_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</p>
{% endif %}
{% endfor %}
<p>
<button type="submit" name="{{ plugin.slug }}_save" value="1" class="btn btn-large">
<span class="icon-upload"></span>
{% trans "Add image" %}
</button>
</p>
{% for field in form %}
<fieldset id="div_{{ field.auto_id }}" class="control-group fields {% if field.errors %} error{% endif %}">
{% if field.label %}
<!--<label for="{{ field.id_for_label }}" class="{% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}
</label>-->
{% endif %}
{{ field }}
{% if field.errors %}
<div id="error_{{ forloop.counter }}_{{ field.auto_id }}" class="help-block">
{% for error in field.errors %}
<div>{{ error }}</div>
{% endfor %}
</div>
{% endif %}
</fieldset>
{% if field.help_text %}
<p id="hint_{{ field.auto_id }}" class="help-block">{{ field.help_text|safe }}</p>
{% endif %}
{% endfor %}
<p>
<button type="submit" name="{{ plugin.slug }}_save" value="1" class="btn btn-large">
<span class="icon-upload"></span>
{% trans "Add image" %}
</button>
</p>
{% else %}
{% if user.is_anonymous %}
{% include "wiki/includes/anonymous_blocked.html" %}
{% else %}
<p><em>{% trans "You do not have permissions to add images." %}</em></p>
{% endif %}
{% endif %}
from django import template
from wiki.plugins.images import models
from wiki.plugins.images import settings
register = template.Library()
@register.filter
def images_for_article(article):
return models.Image.objects.filter(article=article).order_by('-created')
return models.ImageRevision.objects.filter(plugin__article=article).order_by('-created')
@register.filter
def images_can_add(article, user):
if not settings.ANONYMOUS and (not user or user.is_anonymous()):
return False
return article.can_write(user)
\ No newline at end of file
from django.views.generic.base import TemplateView
from django.views.generic.list import ListView
from django.utils.decorators import method_decorator
from wiki.decorators import get_article
from wiki.views.mixins import ArticleMixin
class ImageView(ArticleMixin, TemplateView):
from wiki.plugins.images import models
class ImageView(ArticleMixin, ListView):
template_name = 'wiki/plugins/images/index.html'
allow_empty = True
context_object_name = 'images'
paginate_by = 10
@method_decorator(get_article(can_read=True))
def dispatch(self, request, article, *args, **kwargs):
return super(ImageView, self).dispatch(request, article, *args, **kwargs)
def get_queryset(self):
return models.Image.objects.filter(article=self.article)
def get_context_data(self, **kwargs):
kwargs.update(ArticleMixin.get_context_data(self, **kwargs))
return ListView.get_context_data(self, **kwargs)
\ No newline at end of file
......@@ -28,9 +28,13 @@ class ImagePlugin(plugins.BasePlugin):
'message': lambda obj: _(u"An image was added: %s") % obj.get_filename(),
'key': ARTICLE_EDIT,
'created': True,
'get_article': lambda obj: obj.revision.article}
'get_article': lambda obj: obj.article}
]
urlpatterns = patterns('',
url('^$', views.ImageView.as_view(), name='images_index'),
)
#markdown_extensions = [AttachmentExtension()]
def __init__(self):
......
......@@ -14,9 +14,13 @@ class SubscriptionForm(PluginSettingsFormMixin, forms.Form):
settings_order = 1
settings_write_access = False
edit = forms.BooleanField(required=False, label=_(u'When this article is edited'))
edit_email = forms.BooleanField(required=False, label=_(u'Also receive emails about article edits'),
widget=forms.CheckboxInput(attrs={'onclick': mark_safe("$('#id_edit').attr('checked', $(this).is(':checked'));")}))
def __init__(self, article, user, *args, **kwargs):
# This has to be here to avoid unresolved imports in wiki_plugins
import models
from wiki.plugins.notifications import models
self.article = article
self.user = user
initial = kwargs.pop('initial', None)
......@@ -32,10 +36,6 @@ class SubscriptionForm(PluginSettingsFormMixin, forms.Form):
kwargs['initial'] = initial
super(SubscriptionForm, self).__init__(*args, **kwargs)
edit = forms.BooleanField(required=False, label=_(u'When this article is edited'))
edit_email = forms.BooleanField(required=False, label=_(u'Also receive emails about article edits'),
widget=forms.CheckboxInput(attrs={'onclick': mark_safe("$('#id_edit').attr('checked', $(this).is(':checked'));")}))
def get_usermessage(self):
if self.changed_data:
return _('Your notification settings were updated.')
......
......@@ -8,7 +8,9 @@
<div style="width: 67%; min-width: 600px; float: left;">
<form method="POST" class="form-horizontal" id="article_edit_form">
{% include "wiki/includes/editor.html" %}
{% with edit_form as form %}
{% include "wiki/includes/editor.html" %}
{% endwith %}
<div class="form-actions">
<button type="submit" name="preview" value="1" class="btn btn-large" onclick="$('#previewModal').modal('show'); this.form.target='previewWindow'; this.form.action='{% url 'wiki:preview' path=urlpath.path article_id=article.id %}'">
<span class="icon-eye-open"></span>
......
{% load wiki_tags i18n %}
{% include "wiki/includes/editormedia.html" %}
{% wiki_form edit_form %}
{% wiki_form form %}
<script language="javascript">
$(document).ready(function() {
$("#id_revision").val('{{ article.current_revision.id }}');
......
{% for plugin in sidebar %}
{% for plugin, plugin_form in sidebar %}
<div class="accordion" id="accordion_{{ plugin.slug }}">
......@@ -10,12 +10,13 @@
</a>
</div>
<div id="collapse_{{ plugin.slug }}" class="accordion-body collapse{% if form_images.errors %} in{% endif %}">
<div id="collapse_{{ plugin.slug }}" class="accordion-body collapse{% if plugin_form.errors %} in{% endif %}">
<div class="accordion-inner form-vertical">
{% if plugin.sidebar.template %}
{% with form_images as form and plugin as plugin %}
<form method="POST" class="form-horizontal" enctype="multipart/form-data">
{% include plugin.sidebar.template %}
{% with plugin_form as form and plugin as plugin %}
<form method="POST" class="form-horizontal" action="?f={{ plugin_form.form_id }}" enctype="multipart/form-data">
{% csrf_token %}
{% include plugin.sidebar.template %}
</form>
{% endwith %}
{% endif %}
......
......@@ -54,12 +54,12 @@ def wiki_form(context, form_obj):
@register.filter
def can_read(obj, user):
"""Articles and plugins have a can_read method..."""
return obj.can_read(user)
return obj.can_read(user=user)
@register.filter
def can_write(obj, user):
"""Articles and plugins have a can_write method..."""
return obj.can_write(user)
return obj.can_write(user=user)
@register.filter
def is_moderator(user):
......
......@@ -36,17 +36,29 @@ class Login(FormView):
form_class = AuthenticationForm
template_name = "wiki/accounts/login.html"
def get_form_kwargs(self):
self.request.session.set_test_cookie()
kwargs = super(Login, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def post(self, request, *args, **kwargs):
self.referer = request.session.get('login_referer', '')
return FormView.post(self, request, *args, **kwargs)
def get(self, request, *args, **kwargs):
self.referer = request.META.get('HTTP_REFERER', '')
request.session['login_referer'] = self.referer
return FormView.get(self, request, *args, **kwargs)
def form_valid(self, form, *args, **kwargs):
auth_login(self.request, form.get_user())
messages.info(self.request, _(u"You are now logged in! Have fun!"))
if self.request.GET.get("next", None):
return redirect(self.request.GET['next'])
return redirect(django_settings.LOGIN_REDIRECT_URL)
if django_settings.LOGIN_REDIRECT_URL:
return redirect(django_settings.LOGIN_REDIRECT_URL)
else:
return redirect(self.referer)
\ No newline at end of file
......@@ -216,6 +216,7 @@ class Delete(FormView, ArticleMixin):
class Edit(FormView, ArticleMixin):
"""Edit an article and process sidebar plugins."""
form_class = forms.EditForm
template_name="wiki/edit.html"
......@@ -223,54 +224,64 @@ class Edit(FormView, ArticleMixin):
@method_decorator(get_article(can_write=True))
def dispatch(self, request, article, *args, **kwargs):
self.sidebar_plugins = plugins_registry.get_sidebar()
self.sidebar_forms = {}
for plugin in self.sidebar_plugins:
sidebar_form_class = plugin.sidebar.get('form_class', None)
if sidebar_form_class:
form_kwargs = {}
form_kwargs['prefix'] = plugin.slug
form_kwargs['article'] = article
form_kwargs.update(plugin.sidebar['get_form_kwargs'](article))
plugin.sidebar_form_context = 'form_' + plugin.slug
if request.POST.get(plugin.slug+'_save', '') == '1':
form_kwargs['data'] = request.POST
form_kwargs['files'] = request.FILES
self.sidebar_forms[plugin.sidebar_form_context] = sidebar_form_class(**form_kwargs)
self.sidebar_forms = []
return super(Edit, self).dispatch(request, article, *args, **kwargs)
def get_form(self, form_class):
"""
Returns an instance of the form to be used in this view.
Checks from querystring data that the edit form is actually being saved,
otherwise removes the 'data' and 'files' kwargs from form initialisation.
"""
kwargs = self.get_form_kwargs()
if self.request.POST.get('save', '') != '1':
kwargs['data'] = None
kwargs['files'] = None
kwargs['no_clean'] = True
return form_class(self.article.current_revision, **kwargs)
def get_sidebar_form_classes(self):
"""Returns dictionary of form classes for the sidebar. If no form class is
specified, puts None in dictionary. Keys in the dictionary are used
to identify which form is being saved."""
form_classes = {}
for cnt, plugin in enumerate(self.sidebar_plugins):
form_classes['form%d' % cnt] = plugin.sidebar.get('form_class', None)
return form_classes
def get(self, request, *args, **kwargs):
# Generate sidebar forms
self.sidebar_forms = []
for form_id, Form in self.get_sidebar_form_classes().items():
form = Form(self.article, self.request.user)
setattr(form, 'form_id', form_id)
self.sidebar_forms.append(form)
return super(Edit, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
# Check if any of the plugin form data is supposed to be saved
for plugin in self.sidebar_plugins:
if self.request.POST.get(plugin.slug+'_save', '') == '1':
form = self.sidebar_forms[plugin.sidebar_form_context]
# Generate sidebar forms
self.sidebar_forms = []
for form_id, Form in self.get_sidebar_form_classes().items():
if form_id == self.request.GET.get('f', None):
form = Form(self.article, self.request.user, data=self.request.POST, files=self.request.FILES)
if form.is_valid():
form.save()
message = form.get_usermessage()
if message:
messages.success(request, message)
#if self.urlpath:
# return redirect('wiki:edit', path=self.urlpath.path)
#else:
# return redirect('wiki:edit', article_id=self.article.id)
if self.request.POST.get('save', '') == '1':
return super(Edit, self).post(request, *args, **kwargs)
else:
return super(Edit, self).get(request, *args, **kwargs)
usermessage = form.get_usermessage()
if usermessage:
messages.success(self.request, usermessage)
else:
messages.success(self.request, _(u'Your changes were saved.'))
if self.urlpath:
return redirect('wiki:edit', path=self.urlpath.path)
return redirect('wiki:edit', article_id=self.article.id)
else:
form = Form(self.article, self.request.user)
setattr(form, 'form_id', form_id)
self.sidebar_forms.append(form)
return super(Edit, self).post(request, *args, **kwargs)
def form_valid(self, form):
"""Create a new article revision when the edit form is valid
(does not concern any sidebar forms!)."""
revision = models.ArticleRevision()
revision.inherit_predecessor(self.article)
revision.title = form.cleaned_data['title']
......@@ -283,24 +294,22 @@ class Edit(FormView, ArticleMixin):
return self.get_success_url()
def get_success_url(self):
"""Go to the article view page when the article has been saved"""
if self.urlpath:
return redirect("wiki:get", path=self.urlpath.path)
return redirect('wiki:get', article_id=self.article.id)
def get_context_data(self, **kwargs):
kwargs['edit_form'] = kwargs.pop('form', None)
kwargs['editor'] = editors.editor
kwargs['selected_tab'] = 'edit'
kwargs['sidebar'] = self.sidebar_plugins
kwargs.update(self.sidebar_forms)
kwargs['sidebar'] = zip(self.sidebar_plugins, self.sidebar_forms)
return super(Edit, self).get_context_data(**kwargs)
# TODO: ...
class Deleted(Delete):
"""Tell a user that an article has been deleted. If user has permissions,
let user restore and possibly purge the deleted article and children."""
template_name="wiki/deleted.html"
form_class = forms.DeleteForm
......@@ -404,6 +413,9 @@ class Settings(ArticleMixin, TemplateView):
settings_forms.append(self.permission_form_class)
settings_forms.sort(key=lambda form: form.settings_order)
for i in range(len(settings_forms)):
# TODO: Do not set an attribute on a form class - this
# could be mixed up with a different instance
# Use strategy from Edit view...
setattr(settings_forms[i], 'action', 'form%d' % i)
return settings_forms
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment