forked from rc/aircox
		
	remove old ProxyPost; comments posting managed by sections.Comments; support for messages; change how menus works in Website
This commit is contained in:
		@ -16,34 +16,6 @@ from taggit.managers import TaggableManager
 | 
			
		||||
from aircox.cms import routes
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ProxyPost:
 | 
			
		||||
    """
 | 
			
		||||
    Class used to simulate a Post model when it is required to render an
 | 
			
		||||
    item linked to a Post but that is not that itself. This is to ensure
 | 
			
		||||
    the right attributes are set.
 | 
			
		||||
    """
 | 
			
		||||
    detail_url = None
 | 
			
		||||
    date = None
 | 
			
		||||
    image = None
 | 
			
		||||
    title = None
 | 
			
		||||
    content = None
 | 
			
		||||
 | 
			
		||||
    def __init__(self, post = None, **kwargs):
 | 
			
		||||
        if post:
 | 
			
		||||
            self.update_empty(post)
 | 
			
		||||
        self.__dict__.update(**kwargs)
 | 
			
		||||
 | 
			
		||||
    def update_empty(self, thread):
 | 
			
		||||
        """
 | 
			
		||||
        Update empty fields using thread object
 | 
			
		||||
        """
 | 
			
		||||
        for i in ('date', 'image', 'title', 'content'):
 | 
			
		||||
            if not getattr(self, i):
 | 
			
		||||
                setattr(self, i, getattr(thread, i))
 | 
			
		||||
        if not self.detail_url:
 | 
			
		||||
            self.detail_url = thread.detail_url()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Comment(models.Model):
 | 
			
		||||
    thread_type = models.ForeignKey(
 | 
			
		||||
        ContentType,
 | 
			
		||||
@ -134,12 +106,6 @@ class Post (models.Model):
 | 
			
		||||
 | 
			
		||||
    search_fields = [ 'title', 'content' ]
 | 
			
		||||
 | 
			
		||||
    def as_proxy(self):
 | 
			
		||||
        """
 | 
			
		||||
        Return a ProxyPost instance using this post
 | 
			
		||||
        """
 | 
			
		||||
        return ProxyPost(self)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def children_of(cl, thread, queryset = None):
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ import re
 | 
			
		||||
from django.templatetags.static import static
 | 
			
		||||
from django.template.loader import render_to_string
 | 
			
		||||
from django.views.generic.base import View
 | 
			
		||||
from django.contrib import messages
 | 
			
		||||
from django.utils.html import escape
 | 
			
		||||
from django.utils.translation import ugettext as _, ugettext_lazy
 | 
			
		||||
 | 
			
		||||
@ -214,16 +215,18 @@ class List(Section):
 | 
			
		||||
 | 
			
		||||
class Comments(List):
 | 
			
		||||
    """
 | 
			
		||||
    Section used to render comment form and comments list. It only render
 | 
			
		||||
    the form if the comments are enabled on the target object.
 | 
			
		||||
 | 
			
		||||
    It does not handle comment posts, this is directly done at the
 | 
			
		||||
    level of the detail view.
 | 
			
		||||
    Section used to render comment form and comments list. It renders the
 | 
			
		||||
    form and comments, and save them.
 | 
			
		||||
    """
 | 
			
		||||
    css_class="comments"
 | 
			
		||||
    truncate = 0
 | 
			
		||||
    fields = [ 'date', 'time', 'author', 'content' ]
 | 
			
		||||
 | 
			
		||||
    success_message = ( _('Your message is awaiting for approval'),
 | 
			
		||||
                        _('Your message has been published') )
 | 
			
		||||
    error_message = _('There was an error while saving your post. '
 | 
			
		||||
                      'Please check errors below')
 | 
			
		||||
 | 
			
		||||
    def get_object_list(self):
 | 
			
		||||
        qs = self.object.get_comments().filter(published=True). \
 | 
			
		||||
                         order_by('-date')
 | 
			
		||||
@ -232,16 +235,37 @@ class Comments(List):
 | 
			
		||||
                 for comment in qs ]
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self):
 | 
			
		||||
        context = super().get_context_data()
 | 
			
		||||
        post = self.object
 | 
			
		||||
        if hasattr(post, 'allow_comments') and post.allow_comments:
 | 
			
		||||
            comment_form = (self.comment_form or CommentForm())
 | 
			
		||||
        else:
 | 
			
		||||
            comment_form = None
 | 
			
		||||
 | 
			
		||||
        context = super().get_context_data()
 | 
			
		||||
        context.update({
 | 
			
		||||
            'base_template': 'aircox/cms/comments.html',
 | 
			
		||||
            'comment_form': CommentForm() \
 | 
			
		||||
                if hasattr(post, 'allow_comments') and post.allow_comments \
 | 
			
		||||
                else None
 | 
			
		||||
            'comment_form': comment_form,
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        self.comment_form = None
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
    def post(self, view, request, object):
 | 
			
		||||
        """
 | 
			
		||||
        Forward data to this view
 | 
			
		||||
        """
 | 
			
		||||
        comment_form = CommentForm(request.POST)
 | 
			
		||||
        if comment_form.is_valid():
 | 
			
		||||
            comment = comment_form.save(commit=False)
 | 
			
		||||
            comment.thread = self.object
 | 
			
		||||
            comment.published = view.website.auto_publish_comments
 | 
			
		||||
            comment.save()
 | 
			
		||||
 | 
			
		||||
            messages.success(request, self.success_message[comment.published],
 | 
			
		||||
                             fail_silently=True)
 | 
			
		||||
        else:
 | 
			
		||||
            messages.error(request, self.error_message, fail_silently=True)
 | 
			
		||||
        self.comment_form = comment_form
 | 
			
		||||
 | 
			
		||||
class Menu(Section):
 | 
			
		||||
    template_name = 'aircox/cms/section.html'
 | 
			
		||||
@ -249,7 +273,6 @@ class Menu(Section):
 | 
			
		||||
    classes = ''
 | 
			
		||||
    attrs = ''
 | 
			
		||||
    name = ''
 | 
			
		||||
    enabled = True
 | 
			
		||||
    position = ''   # top, left, bottom, right, header, footer, page_top, page_bottom
 | 
			
		||||
    sections = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,16 @@
 | 
			
		||||
 | 
			
		||||
                <main>
 | 
			
		||||
{% endif %}
 | 
			
		||||
                    {% if messages %}
 | 
			
		||||
                    <ul class="messages">
 | 
			
		||||
                        {% for message in messages %}
 | 
			
		||||
                            <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>
 | 
			
		||||
                            {{ message }}
 | 
			
		||||
                            </li>
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
                    </ul>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
 | 
			
		||||
                    {% block pre_title %}
 | 
			
		||||
                    {% endblock %}
 | 
			
		||||
                    <h1>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								cms/views.py
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								cms/views.py
									
									
									
									
									
								
							@ -3,11 +3,10 @@ from django.template.loader import render_to_string
 | 
			
		||||
from django.views.generic import ListView, DetailView
 | 
			
		||||
from django.views.generic.base import View
 | 
			
		||||
from django.utils.translation import ugettext as _, ugettext_lazy
 | 
			
		||||
from django.contrib import messages
 | 
			
		||||
from django.http import Http404
 | 
			
		||||
 | 
			
		||||
from honeypot.decorators import verify_honeypot_value
 | 
			
		||||
 | 
			
		||||
from aircox.cms.forms import CommentForm
 | 
			
		||||
import aircox.cms.sections as sections
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PostBaseView:
 | 
			
		||||
@ -31,10 +30,7 @@ class PostBaseView:
 | 
			
		||||
            object = self.object if hasattr(self, 'object') else None
 | 
			
		||||
            context['menus'] = {
 | 
			
		||||
                k: v.get(self.request, object = object, **kwargs)
 | 
			
		||||
                for k, v in {
 | 
			
		||||
                    k: self.website.get_menu(k)
 | 
			
		||||
                    for k in self.website.menu_layouts
 | 
			
		||||
                }.items() if v
 | 
			
		||||
                for k, v in self.website.menus.items()
 | 
			
		||||
            }
 | 
			
		||||
        context['view'] = self
 | 
			
		||||
        return context
 | 
			
		||||
@ -128,6 +124,7 @@ class PostDetailView(DetailView, PostBaseView):
 | 
			
		||||
    template_name = 'aircox/cms/detail.html'
 | 
			
		||||
 | 
			
		||||
    sections = []
 | 
			
		||||
    comments = None
 | 
			
		||||
 | 
			
		||||
    def __init__(self, sections = None, *args, **kwargs):
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
@ -162,17 +159,13 @@ class PostDetailView(DetailView, PostBaseView):
 | 
			
		||||
        """
 | 
			
		||||
        Handle new comments
 | 
			
		||||
        """
 | 
			
		||||
        if not self.comments:
 | 
			
		||||
            for section in self.sections:
 | 
			
		||||
                if issubclass(type(section), sections.Comments):
 | 
			
		||||
                    self.comments = section
 | 
			
		||||
 | 
			
		||||
        self.object = self.get_object()
 | 
			
		||||
        if not self.object:
 | 
			
		||||
            raise Http404()
 | 
			
		||||
 | 
			
		||||
        comment_form = CommentForm(request.POST)
 | 
			
		||||
        if not comment_form.is_valid() or verify_honeypot_value(request, 'hp_website'):
 | 
			
		||||
            raise Http404()
 | 
			
		||||
        comment = comment_form.save(commit=False)
 | 
			
		||||
        comment.thread = self.object
 | 
			
		||||
        comment.save()
 | 
			
		||||
 | 
			
		||||
        self.comments.post(self, request, object)
 | 
			
		||||
        return self.get(request, *args, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,25 +2,41 @@ import aircox.cms.routes as routes
 | 
			
		||||
import aircox.cms.views as views
 | 
			
		||||
 | 
			
		||||
class Website:
 | 
			
		||||
    """
 | 
			
		||||
    Describe a website and all its settings that are used for its rendering.
 | 
			
		||||
    """
 | 
			
		||||
    # metadata
 | 
			
		||||
    name = ''
 | 
			
		||||
    domain = ''
 | 
			
		||||
    description = 'An aircox website'   # public description (used in meta info)
 | 
			
		||||
    tags = 'aircox,radio,music'         # public keywords (used in meta info)
 | 
			
		||||
    description = 'An aircox website'
 | 
			
		||||
    tags = 'aircox,radio,music'
 | 
			
		||||
 | 
			
		||||
    styles = ''                         # relative url to stylesheet file
 | 
			
		||||
    menus = None                        # list of menus
 | 
			
		||||
    menu_layouts = ['top', 'left',      # available positions
 | 
			
		||||
                    'right', 'bottom',
 | 
			
		||||
                    'header', 'footer']
 | 
			
		||||
    router = None
 | 
			
		||||
    # rendering
 | 
			
		||||
    styles = ''
 | 
			
		||||
    menus = None
 | 
			
		||||
 | 
			
		||||
    # user interaction
 | 
			
		||||
    allow_comments = True
 | 
			
		||||
    auto_publish_comments = False
 | 
			
		||||
 | 
			
		||||
    # components
 | 
			
		||||
    urls = []
 | 
			
		||||
    registry = {}
 | 
			
		||||
 | 
			
		||||
    def __init__ (self, **kwargs):
 | 
			
		||||
    def __init__ (self, menus = None, **kwargs):
 | 
			
		||||
        """
 | 
			
		||||
        * menus: a list of menus to add to the website
 | 
			
		||||
        """
 | 
			
		||||
        self.registry = {}
 | 
			
		||||
        self.urls = []
 | 
			
		||||
        self.menus = {}
 | 
			
		||||
        self.__dict__.update(kwargs)
 | 
			
		||||
 | 
			
		||||
        if menus:
 | 
			
		||||
            for menu in menus:
 | 
			
		||||
                self.set_menu(menu)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def name_of_model (self, model):
 | 
			
		||||
        for name, _model in self.registry.items():
 | 
			
		||||
            if model is _model:
 | 
			
		||||
@ -67,6 +83,8 @@ class Website:
 | 
			
		||||
        self.registry[name] = model
 | 
			
		||||
 | 
			
		||||
    def register (self, name, model, sections = None, routes = None,
 | 
			
		||||
                  list_view = views.PostListView,
 | 
			
		||||
                  detail_view = views.PostDetailView,
 | 
			
		||||
                  list_kwargs = {}, detail_kwargs = {}):
 | 
			
		||||
        """
 | 
			
		||||
        Register a detail and list view for a given model, using
 | 
			
		||||
@ -86,22 +104,20 @@ class Website:
 | 
			
		||||
                **list_kwargs
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
    def set_menu (self, menu):
 | 
			
		||||
        """
 | 
			
		||||
        Set a menu, and remove any previous menu at the same position
 | 
			
		||||
        """
 | 
			
		||||
        if menu.position in ('footer','header'):
 | 
			
		||||
            menu.tag = menu.position
 | 
			
		||||
        elif menu.position in ('left', 'right'):
 | 
			
		||||
            menu.tag = 'side'
 | 
			
		||||
        self.menus[menu.position] = menu
 | 
			
		||||
 | 
			
		||||
    def get_menu (self, position):
 | 
			
		||||
        """
 | 
			
		||||
        Get an enabled menu by its position
 | 
			
		||||
        """
 | 
			
		||||
        for menu in self.menus:
 | 
			
		||||
            if menu.enabled and menu.position == position:
 | 
			
		||||
                self.check_menu_tag(menu)
 | 
			
		||||
                return menu
 | 
			
		||||
 | 
			
		||||
    def check_menu_tag (self, menu):
 | 
			
		||||
        """
 | 
			
		||||
        Update menu tag if it is a footer or a header
 | 
			
		||||
        """
 | 
			
		||||
        if menu.position in ('footer','header'):
 | 
			
		||||
            menu.tag = menu.position
 | 
			
		||||
        if menu.position in ('left', 'right'):
 | 
			
		||||
            menu.tag = 'side'
 | 
			
		||||
        return self.menus.get(position)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user