Better integration of wiki pages on clubs

This commit is contained in:
Antoine Bartuccio 2017-10-01 20:52:29 +02:00
parent 2c1cf2d7af
commit baa7be69e4
Signed by: klmp200
GPG Key ID: E7245548C53F904B
13 changed files with 203 additions and 52 deletions

View File

@ -6,10 +6,10 @@
{% if club.logo %} {% if club.logo %}
<div class="club_logo"><img src="{{ club.logo.url }}" alt="{{ club.unix_name }}"></div> <div class="club_logo"><img src="{{ club.logo.url }}" alt="{{ club.unix_name }}"></div>
{% endif %} {% endif %}
{% if club.page and club.page.revisions.exists() %} {% if page_revision %}
{{ club.page.revisions.last().content|markdown }} {{ page_revision|markdown }}
{% else %} {% else %}
<h3>{% trans %}Club{% endtrans %}</h3> <h3>{% trans %}Club{% endtrans %}</h3>
{% endif %} {% endif %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,13 @@
{% extends "core/base.jinja" %}
{% from 'core/macros_pages.jinja' import page_history %}
{% block content %}
{% if club.page %}
{{ page_history(club.page) }}
{% else %}
{% trans %}No page existing for this club{% endtrans %}
{% endif %}
{% endblock %}

View File

@ -0,0 +1,14 @@
{% extends "core/base.jinja" %}
{% from 'core/macros_pages.jinja' import markdown_preview_script, page_edit_form %}
{% block head %}
{{ super() }}
{{ markdown_preview_script(csrf_token) }}
{% endblock %}
{% block content %}
{{ page_edit_form(page, form, url('club:club_edit_page', club_id=page.club.id), csrf_token) }}
{% endblock %}

View File

@ -32,7 +32,10 @@ urlpatterns = [
url(r'^new$', ClubCreateView.as_view(), name='club_new'), url(r'^new$', ClubCreateView.as_view(), name='club_new'),
url(r'^stats$', ClubStatView.as_view(), name='club_stats'), url(r'^stats$', ClubStatView.as_view(), name='club_stats'),
url(r'^(?P<club_id>[0-9]+)/$', ClubView.as_view(), name='club_view'), url(r'^(?P<club_id>[0-9]+)/$', ClubView.as_view(), name='club_view'),
url(r'^(?P<club_id>[0-9]+)/rev/(?P<rev_id>[0-9]+)/$', ClubRevView.as_view(), name='club_view_rev'),
url(r'^(?P<club_id>[0-9]+)/hist$', ClubPageHistView.as_view(), name='club_hist'),
url(r'^(?P<club_id>[0-9]+)/edit$', ClubEditView.as_view(), name='club_edit'), url(r'^(?P<club_id>[0-9]+)/edit$', ClubEditView.as_view(), name='club_edit'),
url(r'^(?P<club_id>[0-9]+)/edit/page$', ClubPageEditView.as_view(), name='club_edit_page'),
url(r'^(?P<club_id>[0-9]+)/members$', ClubMembersView.as_view(), name='club_members'), url(r'^(?P<club_id>[0-9]+)/members$', ClubMembersView.as_view(), name='club_members'),
url(r'^(?P<club_id>[0-9]+)/elderlies$', ClubOldMembersView.as_view(), name='club_old_members'), url(r'^(?P<club_id>[0-9]+)/elderlies$', ClubOldMembersView.as_view(), name='club_old_members'),
url(r'^(?P<club_id>[0-9]+)/sellings$', ClubSellingView.as_view(), name='club_sellings'), url(r'^(?P<club_id>[0-9]+)/sellings$', ClubSellingView.as_view(), name='club_sellings'),

View File

@ -28,7 +28,7 @@ from django.views.generic import ListView, DetailView, TemplateView
from django.views.generic.edit import DeleteView from django.views.generic.edit import DeleteView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from django.views.generic.edit import UpdateView, CreateView from django.views.generic.edit import UpdateView, CreateView
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.core.urlresolvers import reverse, reverse_lazy from django.core.urlresolvers import reverse, reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -37,12 +37,12 @@ from ajax_select.fields import AutoCompleteSelectField
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin, PageEditViewBase
from core.views.forms import SelectDate, SelectDateTime from core.views.forms import SelectDate, SelectDateTime
from club.models import Club, Membership, Mailing, MailingSubscription from club.models import Club, Membership, Mailing, MailingSubscription
from sith.settings import SITH_MAXIMUM_FREE_ROLE from sith.settings import SITH_MAXIMUM_FREE_ROLE
from counter.models import Selling, Counter from counter.models import Selling, Counter
from core.models import User from core.models import User, PageRev
from django.conf import settings from django.conf import settings
@ -86,6 +86,8 @@ class MailingSubscriptionForm(forms.ModelForm):
class ClubTabsMixin(TabedViewMixin): class ClubTabsMixin(TabedViewMixin):
def get_tabs_title(self): def get_tabs_title(self):
if isinstance(self.object, PageRev):
self.object = self.object.page.club
return self.object.get_display_name() return self.object.get_display_name()
def get_list_of_tabs(self): def get_list_of_tabs(self):
@ -106,6 +108,12 @@ class ClubTabsMixin(TabedViewMixin):
'slug': 'elderlies', 'slug': 'elderlies',
'name': _("Old members"), 'name': _("Old members"),
}) })
if self.object.page:
tab_list.append({
'url': reverse('club:club_hist', kwargs={'club_id': self.object.id}),
'slug': 'history',
'name': _("History"),
})
if self.request.user.can_edit(self.object): if self.request.user.can_edit(self.object):
tab_list.append({ tab_list.append({
'url': reverse('club:tools', kwargs={'club_id': self.object.id}), 'url': reverse('club:tools', kwargs={'club_id': self.object.id}),
@ -117,7 +125,7 @@ class ClubTabsMixin(TabedViewMixin):
'slug': 'edit', 'slug': 'edit',
'name': _("Edit"), 'name': _("Edit"),
}) })
if self.object.page: if self.object.page and self.request.user.can_edit(self.object.page):
tab_list.append({ tab_list.append({
'url': reverse('core:page_edit', kwargs={'page_name': self.object.page.get_full_name()}), 'url': reverse('core:page_edit', kwargs={'page_name': self.object.page.get_full_name()}),
'slug': 'page_edit', 'slug': 'page_edit',
@ -159,6 +167,55 @@ class ClubView(ClubTabsMixin, DetailView):
template_name = 'club/club_detail.jinja' template_name = 'club/club_detail.jinja'
current_tab = "infos" current_tab = "infos"
def get_context_data(self, **kwargs):
kwargs = super(ClubView, self).get_context_data(**kwargs)
if self.object.page and self.object.page.revisions.exists():
kwargs['page_revision'] = self.object.page.revisions.last().content
return kwargs
class ClubRevView(ClubView):
"""
Display a specific page revision
"""
def dispatch(self, request, *args, **kwargs):
obj = self.get_object()
self.revision = get_object_or_404(PageRev, pk=kwargs['rev_id'], page__club=obj)
return super(ClubRevView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
kwargs = super(ClubRevView, self).get_context_data(**kwargs)
kwargs['page_revision'] = self.revision.content
return kwargs
class ClubPageEditView(ClubTabsMixin, PageEditViewBase):
template_name = 'club/pagerev_edit.jinja'
current_tab = "page_edit"
def dispatch(self, request, *args, **kwargs):
self.club = get_object_or_404(Club, pk=kwargs['club_id'])
if not self.club.page:
raise Http404
return super(ClubPageEditView, self).dispatch(request, *args, **kwargs)
def get_object(self):
self.page = self.club.page
return self._get_revision()
def get_success_url(self, **kwargs):
return reverse_lazy('club:club_view', kwargs={'club_id': self.club.id})
class ClubPageHistView(ClubTabsMixin, CanViewMixin, DetailView):
"""
Modification hostory of the page
"""
model = Club
pk_url_kwarg = "club_id"
template_name = 'club/page_history.jinja'
current_tab = "history"
class ClubToolsView(ClubTabsMixin, CanEditMixin, DetailView): class ClubToolsView(ClubTabsMixin, CanEditMixin, DetailView):
""" """

View File

@ -103,6 +103,7 @@ class Command(BaseCommand):
launderette_club = Club(id=84, name=settings.SITH_LAUNDERETTE_MANAGER['name'], launderette_club = Club(id=84, name=settings.SITH_LAUNDERETTE_MANAGER['name'],
unix_name=settings.SITH_LAUNDERETTE_MANAGER['unix_name'], unix_name=settings.SITH_LAUNDERETTE_MANAGER['unix_name'],
address=settings.SITH_LAUNDERETTE_MANAGER['address']) address=settings.SITH_LAUNDERETTE_MANAGER['address'])
launderette_club.save() launderette_club.save()
self.reset_index("club") self.reset_index("club")
for b in settings.SITH_COUNTER_BARS: for b in settings.SITH_COUNTER_BARS:

View File

@ -896,6 +896,13 @@ class Page(models.Model):
if hasattr(self, 'club') and self.club.can_be_edited_by(user): if hasattr(self, 'club') and self.club.can_be_edited_by(user):
# Override normal behavior for clubs # Override normal behavior for clubs
return True return True
if self.name == settings.SITH_CLUB_ROOT_PAGE and user.is_board_member:
return True
return False
def can_be_viewed_by(self, user):
if self.is_club_page:
return True
return False return False
def get_parent_list(self): def get_parent_list(self):
@ -1005,11 +1012,15 @@ class Page(models.Model):
except: except:
return self.name return self.name
@property @cached_property
def is_club_page(self): def is_club_page(self):
club_root_page = Page.objects.filter(name=settings.SITH_CLUB_ROOT_PAGE).first() club_root_page = Page.objects.filter(name=settings.SITH_CLUB_ROOT_PAGE).first()
return club_root_page is not None and (self == club_root_page or club_root_page in self.get_parent_list()) return club_root_page is not None and (self == club_root_page or club_root_page in self.get_parent_list())
@cached_property
def need_club_redirection(self):
return self.is_club_page and self.name != settings.SITH_CLUB_ROOT_PAGE
def delete(self): def delete(self):
self.unset_lock_recursive() self.unset_lock_recursive()
self.set_lock_recursive(User.objects.get(id=0)) self.set_lock_recursive(User.objects.get(id=0))
@ -1059,6 +1070,9 @@ class PageRev(models.Model):
else: else:
return object.__getattribute__(self, attr) return object.__getattribute__(self, attr)
def can_be_edited_by(self, user):
return self.page.can_be_edited_by(user)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if self.revision is None: if self.revision is None:
self.revision = self.page.revisions.all().count() + 1 self.revision = self.page.revisions.all().count() + 1

View File

@ -0,0 +1,50 @@
{% from "core/macros.jinja" import user_profile_link %}
{% macro page_history(page) %}
<p>{% trans page_name=page.name %}You're seeing the history of page "{{ page_name }}"{% endtrans %}</p>
<ul>
{% for r in (page.revisions.all()|sort(attribute='date', reverse=True)) %}
{% if loop.index < 2 %}
<li><a href="{{ url('core:page', page_name=page.get_full_name()) }}">{% trans %}last{% endtrans %}</a> -
{{ user_profile_link(page.revisions.last().author) }} -
{{ page.revisions.last().date|localtime|date(DATETIME_FORMAT) }} {{ page.revisions.last().date|localtime|time(DATETIME_FORMAT) }}</a></li>
{% else %}
<li><a href="{{ url('core:page_rev', page_name=page.get_full_name(), rev=r['id']) }}">{{ r.revision }}</a> -
{{ user_profile_link(r.author) }} -
{{ r.date|localtime|date(DATETIME_FORMAT) }} {{ r.date|localtime|time(DATETIME_FORMAT) }}</a></li>
{% endif %}
{% endfor %}
</ul>
{% endmacro %}
{% macro page_edit_form(page, form, url, token) %}
<h2>{% trans %}Edit page{% endtrans %}</h2>
<form action="{{ url }}" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ token }}">
{{ form.as_p() }}
{{ markdown_preview_button() }}
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
</form>
<div id="preview" class="page_content">
</div>
{% endmacro %}
{% macro markdown_preview_script(token) %}
<script>
function make_preview() {
text = $("#id_content").val();
console.log("Rendering text: " + text);
$.ajax({
url: "{{ url('api:api_markdown') }}",
method: "POST",
data: { text: text, csrfmiddlewaretoken: "{{ token }}"}
}).done(function (msg) {
$("#preview").html(msg);
});
}
</script>
{% endmacro %}
{% macro markdown_preview_button() %}
<p><input type="button" value="{% trans %}Preview{% endtrans %}" onclick="javascript:make_preview();" /></p>
{% endmacro %}

View File

@ -26,7 +26,7 @@
<div class="tools"> <div class="tools">
{% if page %} {% if page %}
{% if page.club %} {% if page.club %}
<a href="{{ url('club:club_view', club_id=page.club.id) }}">{% trans %}Infos{% endtrans %}</a> <a href="{{ url('club:club_view', club_id=page.club.id) }}">{% trans %}Return to club management{% endtrans %}</a>
{% else %} {% else %}
<a href="{{ url('core:page', page.get_full_name()) }}">{% trans %}View{% endtrans %}</a> <a href="{{ url('core:page', page.get_full_name()) }}">{% trans %}View{% endtrans %}</a>
{% endif %} {% endif %}

View File

@ -1,23 +1,10 @@
{% extends "core/page.jinja" %} {% extends "core/page.jinja" %}
{% from "core/macros.jinja" import user_profile_link %} {% from "core/macros_pages.jinja" import page_history %}
{% block page %} {% block page %}
<h3>{% trans %}Page history{% endtrans %}</h3> <h3>{% trans %}Page history{% endtrans %}</h3>
<p>{% trans page_name=page.name %}You're seeing the history of page "{{ page_name }}"{% endtrans %}</p> {{ page_history(page) }}
<ul>
{% for r in (page.revisions.all()|sort(attribute='date', reverse=True)) %}
{% if loop.index < 2 %}
<li><a href="{{ url('core:page', page_name=page.get_full_name()) }}">{% trans %}last{% endtrans %}</a> -
{{ user_profile_link(page.revisions.last().author) }} -
{{ page.revisions.last().date|localtime|date(DATETIME_FORMAT) }} {{ page.revisions.last().date|localtime|time(DATETIME_FORMAT) }}</a></li>
{% else %}
<li><a href="{{ url('core:page_rev', page_name=page.get_full_name(), rev=r['id']) }}">{{ r.revision }}</a> -
{{ user_profile_link(r.author) }} -
{{ r.date|localtime|date(DATETIME_FORMAT) }} {{ r.date|localtime|time(DATETIME_FORMAT) }}</a></li>
{% endif %}
{% endfor %}
</ul>
{% endblock %} {% endblock %}

View File

@ -1,32 +1,13 @@
{% extends "core/page.jinja" %} {% extends "core/page.jinja" %}
{% from 'core/macros_pages.jinja' import markdown_preview_script, page_edit_form %}
{% block head %} {% block head %}
{{ super() }} {{ super() }}
<script> {{ markdown_preview_script(csrf_token) }}
function make_preview() {
text = $("#id_content").val();
console.log("Rendering text: " + text);
$.ajax({
url: "{{ url('api:api_markdown') }}",
method: "POST",
data: { text: text, csrfmiddlewaretoken: "{{ csrf_token }}"}
}).done(function (msg) {
$("#preview").html(msg);
});
}
</script>
{% endblock %} {% endblock %}
{% block page %} {% block page %}
<h2>{% trans %}Edit page{% endtrans %}</h2> {{ page_edit_form(page, form, url('core:page_edit', page_name=page.get_full_name()), csrf_token) }}
<form action="{{ url('core:page_edit', page_name=page.get_full_name()) }}" method="post">
{% csrf_token %}
{{ form.as_p() }}
<p><input type="button" value="{% trans %}Preview{% endtrans %}" onclick="javascript:make_preview();" /></p>
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
</form>
<div id="preview" class="page_content">
</div>
{% endblock %} {% endblock %}

View File

@ -28,6 +28,7 @@ from django.views.generic import ListView, DetailView
from django.views.generic.edit import UpdateView, CreateView, DeleteView from django.views.generic.edit import UpdateView, CreateView, DeleteView
from django.forms.models import modelform_factory from django.forms.models import modelform_factory
from django.http import Http404 from django.http import Http404
from django.shortcuts import redirect
from core.models import Page, PageRev, LockError from core.models import Page, PageRev, LockError
from core.views.forms import MarkdownInput, PageForm, PagePropForm from core.views.forms import MarkdownInput, PageForm, PagePropForm
@ -52,6 +53,12 @@ class PageView(CanViewMixin, DetailView):
model = Page model = Page
template_name = 'core/page_detail.jinja' template_name = 'core/page_detail.jinja'
def dispatch(self, request, *args, **kwargs):
res = super(PageView, self).dispatch(request, *args, **kwargs)
if self.object and self.object.need_club_redirection:
return redirect('club:club_view', club_id=self.object.club.id)
return res
def get_object(self): def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name']) self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
return self.page return self.page
@ -67,6 +74,12 @@ class PageHistView(CanViewMixin, DetailView):
model = Page model = Page
template_name = 'core/page_hist.jinja' template_name = 'core/page_hist.jinja'
def dispatch(self, request, *args, **kwargs):
res = super(PageHistView, self).dispatch(request, *args, **kwargs)
if self.object.need_club_redirection:
return redirect('club:club_hist', club_id=self.object.club.id)
return res
def get_object(self): def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name']) self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
return self.page return self.page
@ -76,6 +89,12 @@ class PageRevView(CanViewMixin, DetailView):
model = Page model = Page
template_name = 'core/page_detail.jinja' template_name = 'core/page_detail.jinja'
def dispatch(self, request, *args, **kwargs):
res = super(PageRevView, self).dispatch(request, *args, **kwargs)
if self.object.need_club_redirection:
return redirect('club:club_view_rev', club_id=self.object.club.id, rev_id=kwargs['rev'])
return res
def get_object(self): def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name']) self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
return self.page return self.page
@ -148,17 +167,20 @@ class PagePropView(CanEditPagePropMixin, UpdateView):
return self.page return self.page
class PageEditView(CanEditMixin, UpdateView): class PageEditViewBase(CanEditMixin, UpdateView):
model = PageRev model = PageRev
form_class = modelform_factory(model=PageRev, fields=['title', 'content', ], widgets={'content': MarkdownInput}) form_class = modelform_factory(model=PageRev, fields=['title', 'content', ], widgets={'content': MarkdownInput})
template_name = 'core/pagerev_edit.jinja' template_name = 'core/pagerev_edit.jinja'
def get_object(self): def get_object(self):
self.page = Page.get_page_by_full_name(self.kwargs['page_name']) self.page = Page.get_page_by_full_name(self.kwargs['page_name'])
return self._get_revision()
def _get_revision(self):
if self.page is not None: if self.page is not None:
# First edit # First edit
if self.page.revisions.all() is None: if self.page.revisions.all() is None:
rev = PageRev(author=request.user) rev = PageRev(author=self.request.user)
rev.save() rev.save()
self.page.revisions.add(rev) self.page.revisions.add(rev)
try: try:
@ -169,7 +191,7 @@ class PageEditView(CanEditMixin, UpdateView):
return None return None
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(PageEditView, self).get_context_data(**kwargs) context = super(PageEditViewBase, self).get_context_data(**kwargs)
if self.page is not None: if self.page is not None:
context['page'] = self.page context['page'] = self.page
else: else:
@ -185,7 +207,16 @@ class PageEditView(CanEditMixin, UpdateView):
new_rev.author = self.request.user new_rev.author = self.request.user
new_rev.page = self.page new_rev.page = self.page
form.instance = new_rev form.instance = new_rev
return super(PageEditView, self).form_valid(form) return super(PageEditViewBase, self).form_valid(form)
class PageEditView(PageEditViewBase):
def dispatch(self, request, *args, **kwargs):
res = super(PageEditView, self).dispatch(request, *args, **kwargs)
if self.object.page.need_club_redirection:
return redirect('club:club_edit_page', club_id=self.object.page.club.id)
return res
class PageDeleteView(CanEditPagePropMixin, DeleteView): class PageDeleteView(CanEditPagePropMixin, DeleteView):