kaputtnik has proposed merging lp:~widelands-dev/widelands-website/hidden_topics into lp:widelands-website.
Commit message: Implement possibility to hide whole topics Requested reviews: Widelands Developers (widelands-dev) For more details, see: https://code.launchpad.net/~widelands-dev/widelands-website/hidden_topics/+merge/358944 Implement possibility to hide whole topics. The hiding is done by hiding the first post of a topic. This is implemented as follows: - Beside the buttons "Stick Topic"/"Close Topic" an additional button "Toggle Visibility" was added, this button is only shown for forum moderators or superusers - Showing hidden topics or it's last post is prevented in all forum related pages, like forum categories, in the "Latest Post" box and the Feeds - Moderators can see hidden topics ONLY in a forums list of topics as a row showing "Hidden Topic: topics_name", and can enter this topic to toggle visibility. In all other places showing hidden topics, or the last post of a hidden topic is prevented - Because topics are hidden also if it was caught by our spam filter, an additional sentence is shown if this topic was caught by the spam filter. - If one try's to open a hidden topic by URL (e.g. by a link in another topic), a page with an explanation is shown. Spam posts appended to an existing topics are now shown for moderators and superusers with a grayish background. For all other users they are not shown. Showing the forums categories is much faster now by preventing unneeded queries to the database. -- Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands-website/hidden_topics into lp:widelands-website.
=== added file 'media/forum/img/topic_hide.png' Binary files media/forum/img/topic_hide.png 1970-01-01 00:00:00 +0000 and media/forum/img/topic_hide.png 2018-11-17 11:25:00 +0000 differ === added file 'media/forum/img/topic_show.png' Binary files media/forum/img/topic_show.png 1970-01-01 00:00:00 +0000 and media/forum/img/topic_show.png 2018-11-17 11:25:00 +0000 differ === modified file 'pybb/feeds.py' --- pybb/feeds.py 2018-09-12 07:45:35 +0000 +++ pybb/feeds.py 2018-11-17 11:25:00 +0000 @@ -56,10 +56,10 @@ title_template = 'pybb/feeds/posts_title.html' description_template = 'pybb/feeds/posts_description.html' - all_objects = Post.objects.filter(hidden=False) + all_objects = Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(hidden=False) def items_for_object(self, obj): - return Post.objects.filter(hidden=False, topic__forum=obj).order_by('-created')[:15] + return Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(hidden=False, topic__forum=obj).order_by('-created')[:15] # Validated through http://validator.w3.org/feed/ === modified file 'pybb/models.py' --- pybb/models.py 2018-10-03 09:01:09 +0000 +++ pybb/models.py 2018-11-17 11:25:00 +0000 @@ -17,6 +17,8 @@ from django.conf import settings from notification.models import send from django.contrib.auth.models import User +from check_input.models import SuspiciousInput + try: from notification import models as notification @@ -91,8 +93,16 @@ @property def last_post(self): - posts = self.posts.exclude(hidden=True).order_by( + # This is performanter than using the posts manager hidden_topics + # We search only for the last 10 topics + topics = self.topics.order_by('-updated')[:10] + for topic in topics: + if topic.is_hidden: + continue + posts = topic.posts.exclude(hidden=True).order_by( '-created').select_related() + break + try: return posts[0] except IndexError: @@ -122,21 +132,22 @@ @property def head(self): - return self.posts.all().order_by('created').select_related()[0] + try: + return self.posts.all().order_by('created').select_related()[0] + except: + return None @property def last_post(self): return self.posts.exclude(hidden=True).order_by('-created').select_related()[0] - # If the first post of this topic is hidden, the topic is hidden @property def is_hidden(self): + # If the first post of this topic is hidden, the topic is hidden try: - p = self.posts.order_by('created').filter( - hidden=False).select_related()[0] - except IndexError: - return True - return False + return self.posts.first().hidden + except: + return False @property def post_count(self): @@ -191,6 +202,30 @@ self.body_html = urlize(self.body_html) +class HiddenTopicsManager(models.Manager): + """Find all hidden topics by posts. + + A whole topic is hidden, if the first post is hidden. + This manager returns the hidden topics and can be used to filter them out + like so: + + Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(...) + + Use this with caution, because it effects performance, see: + https://docs.djangoproject.com/en/dev/ref/models/querysets/#in + """ + + def get_queryset(self, *args, **kwargs): + qs = super(HiddenTopicsManager, + self).get_queryset().filter(hidden=True) + + hidden_topics = [] + for post in qs: + if post.topic.is_hidden: + hidden_topics.append(post.topic) + return hidden_topics + + class Post(RenderableItem): topic = models.ForeignKey( Topic, related_name='posts', verbose_name=_('Topic')) @@ -205,6 +240,9 @@ body_text = models.TextField(_('Text version')) hidden = models.BooleanField(_('Hidden'), blank=True, default=False) + objects = models.Manager() # Normal manager + hidden_topics = HiddenTopicsManager() # Custom manager + class Meta: ordering = ['created'] verbose_name = _('Post') @@ -260,6 +298,14 @@ if self_id == head_post_id: self.topic.delete() + def is_spam(self): + try: + SuspiciousInput.objects.get(object_id = self.pk) + return True + except: + pass + return False + class Read(models.Model): """For each topic that user has entered the time is logged to this === modified file 'pybb/templatetags/pybb_extras.py' --- pybb/templatetags/pybb_extras.py 2018-09-11 20:16:31 +0000 +++ pybb/templatetags/pybb_extras.py 2018-11-17 11:25:00 +0000 @@ -82,14 +82,17 @@ @register.inclusion_tag('pybb/last_posts.html', takes_context=True) def pybb_last_posts(context, number=8): + last_posts = Post.objects.filter(hidden=False).order_by( '-created').select_related()[:45] + check = [] answer = [] for post in last_posts: - if (post.topic_id not in check) and len(check) < number: - check = check + [post.topic_id] - answer = answer + [post] + if not post.topic.is_hidden: + if (post.topic_id not in check) and len(check) < number: + check = check + [post.topic_id] + answer = answer + [post] return { 'posts': answer, } === modified file 'pybb/urls.py' --- pybb/urls.py 2018-04-08 15:20:01 +0000 +++ pybb/urls.py 2018-11-17 11:25:00 +0000 @@ -30,6 +30,8 @@ views.close_topic, name='pybb_close_topic'), url('^topic/(?P<topic_id>\d+)/open/$', views.open_topic, name='pybb_open_topic'), + url('^topic/(?P<topic_id>\d+)/unhide/$', + views.toggle_hidden_topic, name='pybb_toggle_hid_topic'), # Post url('^topic/(?P<topic_id>\d+)/post/add/$', views.add_post, === modified file 'pybb/views.py' --- pybb/views.py 2018-10-03 09:01:09 +0000 +++ pybb/views.py 2018-11-17 11:25:00 +0000 @@ -10,7 +10,7 @@ from django.urls import reverse from django.db import connection from django.utils import translation -from django.shortcuts import render +from django.shortcuts import render, redirect from pybb.util import render_to, paged, build_form, quote_text, ajax, urlize @@ -29,52 +29,32 @@ def index_ctx(request): - quick = {'posts': Post.objects.count(), - 'topics': Topic.objects.count(), - 'users': User.objects.count(), - 'last_topics': Topic.objects.all().select_related()[:pybb_settings.QUICK_TOPICS_NUMBER], - 'last_posts': Post.objects.order_by('-created').select_related()[:pybb_settings.QUICK_POSTS_NUMBER], - } - cats = Category.objects.all().select_related() - return {'cats': cats, - 'quick': quick, - } + return {'cats': cats } index = render_to('pybb/index.html')(index_ctx) def show_category_ctx(request, category_id): category = get_object_or_404(Category, pk=category_id) - quick = {'posts': category.posts.count(), - 'topics': category.topics.count(), - 'last_topics': category.topics.select_related()[:pybb_settings.QUICK_TOPICS_NUMBER], - 'last_posts': category.posts.order_by('-created').select_related() - [:pybb_settings.QUICK_POSTS_NUMBER], - } - return {'category': category, - 'quick': quick, - } + + return {'category': category } show_category = render_to('pybb/category.html')(show_category_ctx) def show_forum_ctx(request, forum_id): forum = get_object_or_404(Forum, pk=forum_id) - quick = {'posts': forum.post_count, - 'topics': forum.topics.count(), - 'last_topics': forum.topics.all().select_related()[:pybb_settings.QUICK_TOPICS_NUMBER], - 'last_posts': forum.posts.order_by('-created').select_related() - [:pybb_settings.QUICK_POSTS_NUMBER], - } + moderator = (request.user.is_superuser or + request.user in forum.moderators.all()) topics = forum.topics.order_by( - '-sticky', '-updated').exclude(posts__hidden=True).select_related() + '-sticky', '-updated').select_related() return {'forum': forum, 'topics': topics, - 'quick': quick, 'page_size': pybb_settings.FORUM_PAGE_SIZE, + 'moderator': moderator, } show_forum = render_to('pybb/forum.html')(show_forum_ctx) @@ -106,8 +86,16 @@ subscribed = (request.user.is_authenticated and request.user in topic.subscribers.all()) - posts = topic.posts.exclude(hidden=True).select_related() - + + is_spam = False + if topic.is_hidden: + is_spam = topic.posts.first().is_spam() + + if moderator: + posts = topic.posts.select_related() + else: + posts = topic.posts.exclude(hidden=True).select_related() + # TODO: fetch profiles # profiles = Profile.objects.filter(user__pk__in= # set(x.user.id for x in page.object_list)) @@ -127,6 +115,7 @@ 'posts': posts, 'page_size': pybb_settings.TOPIC_PAGE_SIZE, 'form_url': reverse('pybb_add_post', args=[topic.id]), + 'is_spam': is_spam, } show_topic = render_to('pybb/topic.html')(show_topic_ctx) @@ -393,3 +382,15 @@ def pybb_moderate_info(request): return render(request, 'pybb/pybb_moderate_info.html') + + +def toggle_hidden_topic(request, topic_id): + topic = get_object_or_404(Topic, pk=topic_id) + first_post = topic.posts.all()[0] + if first_post.hidden: + first_post.hidden = False + else: + first_post.hidden = True + first_post.save() + + return redirect(topic) \ No newline at end of file === modified file 'templates/pybb/forum.html' --- templates/pybb/forum.html 2018-10-15 16:11:43 +0000 +++ templates/pybb/forum.html 2018-11-17 11:25:00 +0000 @@ -51,6 +51,7 @@ <tbody> {% for topic in object_list %} <tr class="{% cycle 'odd' 'even' %}"> + {% if not topic.is_hidden %} <td class="forumIcon center"> {% if topic|pybb_has_unreads:user %} <img src="{{ MEDIA_URL }}forum/img/doc_big_work_star.png" style="margin: 0px;" alt="" class="middle" /> @@ -74,6 +75,9 @@ <span class="small">on {{ topic.last_post.created|custom_date:user }}</span> {% endif %} </td> + {% elif moderator %} + <td colspan="4" class="center errormessage">Hidden Topic: <a href="{{ topic.get_absolute_url }}">{{ topic.name }}</a></td> + {% endif %} </tr> {% endfor %} </tbody> === modified file 'templates/pybb/inlines/display_category.html' --- templates/pybb/inlines/display_category.html 2016-10-29 20:47:11 +0000 +++ templates/pybb/inlines/display_category.html 2018-11-17 11:25:00 +0000 @@ -30,13 +30,15 @@ Posts: {{ forum.posts.count }} </td> <td class="lastPost"> - {%if forum.last_post %} - <a href="{{forum.last_post.get_absolute_url}}">{{ forum.last_post.topic.name }}</a><br /> - <span class="small">by {{ forum.last_post.user|user_link }}<br /> - on {{ forum.last_post.created|custom_date:user}}</span> + {% with last_post=forum.last_post %} + {% if last_post %} + <a href="{{last_post.get_absolute_url}}">{{ last_post.topic.name }}</a><br /> + <span class="small">by {{ last_post.user|user_link }}<br /> + on {{ last_post.created|custom_date:user}}</span> {% else %} {% endif %} + {% endwith %} </td> </tr> {% endfor %} === modified file 'templates/pybb/topic.html' --- templates/pybb/topic.html 2018-10-14 13:24:15 +0000 +++ templates/pybb/topic.html 2018-11-17 11:25:00 +0000 @@ -24,281 +24,302 @@ {% block content_main %} <div class="blogEntry"> <div class="breadCrumb"> - <a href="{% url 'pybb_index' %}">Forums</a> » - {% pybb_link topic.forum.category %} » - <a href="{{ topic.forum.get_absolute_url }}">{{ topic.forum.name }}</a> » - {{ topic }} - </div> - - <div class="posRight"> - {% if moderator %} - {% if topic.sticky %} - <a class="button" href="{% url 'pybb_unstick_topic' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/unstick.png" alt ="" class="middle" /> - <span class="middle">{% trans "Unstick Topic" %}</span> - </a> - {% else %} - <a class="button" href="{% url 'pybb_stick_topic' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/sticky.png" alt ="" class="middle" /> - <span class="middle">{% trans "Stick Topic" %}</span> - </a> - {% endif %} - {% if topic.closed %} - <a class="button" href="{% url 'pybb_open_topic' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/open.png" alt ="" class="middle" /> - <span class="middle">{% trans "Open Topic" %}</span> - </a> - {% else %} - <a class="button" href="{% url 'pybb_close_topic' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/closed.png" alt ="" class="middle" /> - <span class="middle">{% trans "Close Topic" %}</span> - </a> - {% endif %} - {% endif %} - {% if user.is_authenticated %} - {% if subscribed %} - <a class="button" href="{% url 'pybb_delete_subscription' topic.id %}?from_topic"> - <img src="{{ MEDIA_URL }}forum/img/unsubscribe.png" alt ="" class="middle" /> - <span class="middle">{% trans "Unsubscribe" %}</span> - </a> - {% else %} - <a class="button" href="{% url 'pybb_add_subscription' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/subscribe.png" alt ="" class="middle" /> - <span class="middle">{% trans "Subscribe" %}</span> - </a> - {% endif %} - <a class="button" href="{% url 'pybb_add_post' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/send.png" alt ="" class="middle" /> - <span class="middle">{% trans "New Reply" %}</span> - </a> - {% endif %} - </div> - {% autopaginate posts page_size as object_list %} - {% paginate using "pagination/pagination_mod.html" %} - -{% if first_post %} - {% ifnotequal first_post posts.0 %} - {% with first_post as post %} - {% trans "First Post" %}: - <table class="forum"> - <tbody> - <tr class="odd"> - <td class="author"> - {{ post.user|user_link }}<br /> - {% if post.user.wlprofile_extras.avatar %} - <a href="{% url 'profile_view' post.user %}"> - <img src="{{ post.user.wlprofile.avatar.url }}" alt="Avatar" /> - </a> - {% endif %} - <div class="authorStats"> - <strong>Joined:</strong> {{ post.user.date_joined|custom_date:user|title }}<br /> - <strong>Posts:</strong> {{ post.user.wlprofile.post_count }}<br /> - <img src="{{ MEDIA_URL }}img/{{ post.user.wlprofile.user_status.image }}" alt="Ranking" /><br /> - <strong>{{ post.user.wlprofile.user_status.text }}</strong><br /> - {% if post.user.wlprofile.location %} - <strong>Location:</strong> {{ post.user.wlprofile.location }}<br /> - {% endif %} - </div> - </td> - <td class="post"> - <a id="post-{{ post.id }}" href="{{post.get_absolute_url}}" title="{% trans "Permalink" %}" class="posRight small permalink"> </a> - <span class="small">Posted at: {{ post.created|custom_date:user}}</span> - <hr /> - <div class="post"> - {{ post.body_html|safe }} - </div> - - {% if post.attachment_cache %} - {% for attach in post.attachment_cache %} - {% trans "Attachment" %}: <a href="{{ attach.get_absolute_url }}">{{ attach.name }}</a> ({{ attach.size_display }}) - {% endfor %} - {% endif %} - - {% if post.updated %} - <span class="small">{% trans "Edited" %}: {{ post.updated|custom_date:user|title}}</span> - {% endif %} - <hr /> - {% if user.is_authenticated %} - {% ifequal user.wlprofile.show_signatures 1 %} - {% if post.user.wlprofile.signature %} - {{ post.user.wlprofile.signature|urlize|linebreaks }} - {% endif %} - {% endifequal %} - {% else %} - {% if post.user.wlprofile.signature %} - {{ post.user.wlprofile.signature|urlize|linebreaks }} - {% endif %} - {% endif %} - - <button onclick="window.location.href='#top';" class="posRight"> - <img src="{{ MEDIA_URL }}forum/img/top.png" alt ="" class="middle" /> - <span class="middle">{% trans "Top" %}</span> - </button> - - <button onclick="window.location.href='{% url 'pybb_add_post' topic.id %}?quote_id={{ post.id }}';"> - <img src="{{ MEDIA_URL }}forum/img/quote.png" alt ="" class="middle" /> - <span class="middle">{% trans "Quote" %}</span> - </button> - {% if moderator or post|pybb_posted_by:user %} - <button onclick="window.location.href='{% url 'pybb_edit_post' post.id %}';"> - <img src="{{ MEDIA_URL }}forum/img/edit.png" alt ="" class="middle" /> - <span class="middle">{% trans "Edit" %}</span> - </button> - {% if moderator or post|pybb_equal_to:last_post %} - <button onclick="window.location.href='{% url 'pybb_delete_post' post.id %}';"> - <img src="{{ MEDIA_URL }}forum/img/delete.png" alt ="" class="middle" /> - <span class="middle">{% trans "Delete" %}</span> - </button> - {% endif %} - {% endif %} - </td> - </tr> - </tbody> - </table> - <br /><hr /><br /> - {% endwith %} - {% endifnotequal %} -{% endif %} - - <table class="forum"> - <tbody> - {% for post in object_list %} - {% comment %} - TODO (Franku): use - {% include 'pybb/inlines/post.html' %} - {% endcomment %} - <tr class="{% cycle 'odd' 'even' %}"> - <td class="author"> - {{ post.user|user_link }}<br /> - {% if post.user.wlprofile.avatar %} - <a href="{% url 'profile_view' post.user %}"> - <img src="{{ post.user.wlprofile.avatar.url }}" alt="Avatar" /> - </a> - {% endif %} - <div class="authorStats"> - <strong>Joined:</strong> {{ post.user.date_joined|custom_date:user|title }}<br /> - <strong>Posts:</strong> {{ post.user.wlprofile.post_count }}<br /> - <img src="{{ MEDIA_URL }}img/{{ post.user.wlprofile.user_status.image }}" alt="Ranking" /><br /> - <strong>{{ post.user.wlprofile.user_status.text }}</strong><br /> - {% if post.user.wlprofile.location %} - <strong>Location:</strong> {{ post.user.wlprofile.location }}<br /> - {% endif %} - </div> - </td> - <td class="post"> - <a id="post-{{ post.id }}" href="{{post.get_absolute_url}}" title="{% trans "Permalink" %}" class="posRight small permalink"> </a> - <span class="small">Posted at: {{ post.created|custom_date:user}}</span> - <hr /> - <div class="post"> - {{ post.body_html|safe }} - </div> - - {% if post.attachment_cache %} - {% for attach in post.attachment_cache %} - {% trans "Attachment" %}: <a href="{{ attach.get_absolute_url }}">{{ attach.name }}</a> ({{ attach.size_display }}) - {% endfor %} - {% endif %} - - {% if post.updated %} - <span class="small">{% trans "Edited" %}: {{ post.updated|custom_date:user|title}}</span> - {% endif %} - <hr /> - {% if user.is_authenticated %} - {% ifequal user.wlprofile.show_signatures 1 %} - {% if post.user.wlprofile.signature %} - {{ post.user.wlprofile.signature|urlize|linebreaks }} - {% endif %} - {% endifequal %} - {% else %} - {% if post.user.wlprofile.signature %} - {{ post.user.wlprofile.signature|urlize|linebreaks }} - {% endif %} - {% endif %} - - <a class="button posRight" href="#top"> - <img src="{{ MEDIA_URL }}forum/img/top.png" alt ="" class="middle" /> - <span class="middle">{% trans "Top" %}</span> - </a> - - <a class="button" href="{% url 'pybb_add_post' topic.id %}?quote_id={{ post.id }}"> - <img src="{{ MEDIA_URL }}forum/img/quote.png" alt ="" class="middle" /> - <span class="middle">{% trans "Quote" %}</span> - </a> - {% if moderator or post|pybb_posted_by:user %} - <a class="button" href="{% url 'pybb_edit_post' post.id %}"> - <img src="{{ MEDIA_URL }}forum/img/edit.png" alt ="" class="middle" /> - <span class="middle">{% trans "Edit" %}</span> - </a> - {% if moderator or post|pybb_equal_to:last_post %} - <a class="button" href="{% url 'pybb_delete_post' post.id %}"> - <img src="{{ MEDIA_URL }}forum/img/delete.png" alt ="" class="middle" /> - <span class="middle">{% trans "Delete" %}</span> - </a> - {% endif %} - {% endif %} - </td> - </tr> - {% if not forloop.last %} - {# no spacer at end of table #} - <tr class="spacer"> - <td></td> - <td></td> - </tr> - {% endif %} - {% endfor %} - </tbody> - </table> - - <div class="posRight"> - {% if moderator %} - {% if topic.sticky %} - <a class="button" href="{% url 'pybb_unstick_topic' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/unstick.png" alt ="" class="middle" /> - <span class="middle">{% trans "Unstick Topic" %}</span> - </a> - {% else %} - <a class="button" href="{% url 'pybb_stick_topic' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/sticky.png" alt ="" class="middle" /> - <span class="middle">{% trans "Stick Topic" %}</span> - </a> - {% endif %} - {% if topic.closed %} - <a class="button" href="{% url 'pybb_open_topic' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/open.png" alt ="" class="middle" /> - <span class="middle">{% trans "Open Topic" %}</span> - </a> - {% else %} - <a class="button" href="{% url 'pybb_close_topic' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/closed.png" alt ="" class="middle" /> - <span class="middle">{% trans "Close Topic" %}</span> - </a> - {% endif %} - {% endif %} - {% if user.is_authenticated %} - {% if subscribed %} - <a class="button" href="{% url 'pybb_delete_subscription' topic.id %}?from_topic"> - <img src="{{ MEDIA_URL }}forum/img/unsubscribe.png" alt ="" class="middle" /> - <span class="middle">{% trans "Unsubscribe" %}</span> - </a> - {% else %} - <a class="button" href="{% url 'pybb_add_subscription' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/subscribe.png" alt ="" class="middle" /> - <span class="middle">{% trans "Subscribe" %}</span> - </a> - {% endif %} - <a class="button" href="{% url 'pybb_add_post' topic.id %}"> - <img src="{{ MEDIA_URL }}forum/img/send.png" alt ="" class="middle" /> - <span class="middle">{% trans "New Reply" %}</span> - </a> - {% endif %} - </div> - {% paginate %} -</div> - -{% if user.is_authenticated %} - {% if not topic.closed %} - {% include "pybb/inlines/add_post_form.html" %} - {% endif %} -{% endif %} - + <a href="{% url 'pybb_index' %}">Forums</a> » + {% pybb_link topic.forum.category %} » + <a href="{{ topic.forum.get_absolute_url }}">{{ topic.forum.name }}</a> » + {{ topic }} + </div> + {% if topic.is_hidden %} + <p>This topic is hidden. Either it waits for a review, or it was hid by a moderator intentionally.</p> + {% if posts.0.is_spam and moderator %} + <p>This topics first post is possible spam. Toggle visibilty to show the post. If this is spam, consider to delete the user:</p> + <p>To delete the user, go to:<a href="/admin/auth/user/{{posts.0.user.pk}}/change/"> Admin user-page for the posts author</a></p> + {% endif %} + <div class="posRight"> + {% if moderator %} + <a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/topic_show.png" alt ="" class="middle" /> + <span class="middle">{% trans "Toggle Visibility" %}</span> + </a> + {% endif %} + {% else %} + <div class="posRight"> + {% if moderator %} + <a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/topic_hide.png" alt ="" class="middle" /> + <span class="middle">{% trans "Toggle Visibility" %}</span> + </a> + {% if topic.sticky %} + <a class="button" href="{% url 'pybb_unstick_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/unstick.png" alt ="" class="middle" /> + <span class="middle">{% trans "Unstick Topic" %}</span> + </a> + {% else %} + <a class="button" href="{% url 'pybb_stick_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/sticky.png" alt ="" class="middle" /> + <span class="middle">{% trans "Stick Topic" %}</span> + </a> + {% endif %} + {% if topic.closed %} + <a class="button" href="{% url 'pybb_open_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/open.png" alt ="" class="middle" /> + <span class="middle">{% trans "Open Topic" %}</span> + </a> + {% else %} + <a class="button" href="{% url 'pybb_close_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/closed.png" alt ="" class="middle" /> + <span class="middle">{% trans "Close Topic" %}</span> + </a> + {% endif %} + {% endif %} + {% if user.is_authenticated %} + {% if subscribed %} + <a class="button" href="{% url 'pybb_delete_subscription' topic.id %}?from_topic"> + <img src="{{ MEDIA_URL }}forum/img/unsubscribe.png" alt ="" class="middle" /> + <span class="middle">{% trans "Unsubscribe" %}</span> + </a> + {% else %} + <a class="button" href="{% url 'pybb_add_subscription' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/subscribe.png" alt ="" class="middle" /> + <span class="middle">{% trans "Subscribe" %}</span> + </a> + {% endif %} + <a class="button" href="{% url 'pybb_add_post' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/send.png" alt ="" class="middle" /> + <span class="middle">{% trans "New Reply" %}</span> + </a> + {% endif %} + </div> + {% autopaginate posts page_size as object_list %} + {% paginate using "pagination/pagination_mod.html" %} + + {% if first_post %} + {% ifnotequal first_post posts.0 %} + {% with first_post as post %} + {% trans "First Post" %}: + <table class="forum"> + <tbody> + <tr class="odd"> + <td class="author"> + {{ post.user|user_link }}<br /> + {% if post.user.wlprofile_extras.avatar %} + <a href="{% url 'profile_view' post.user %}"> + <img src="{{ post.user.wlprofile.avatar.url }}" alt="Avatar" /> + </a> + {% endif %} + <div class="authorStats"> + <strong>Joined:</strong> {{ post.user.date_joined|custom_date:user|title }}<br /> + <strong>Posts:</strong> {{ post.user.wlprofile.post_count }}<br /> + <img src="{{ MEDIA_URL }}img/{{ post.user.wlprofile.user_status.image }}" alt="Ranking" /><br /> + <strong>{{ post.user.wlprofile.user_status.text }}</strong><br /> + {% if post.user.wlprofile.location %} + <strong>Location:</strong> {{ post.user.wlprofile.location }}<br /> + {% endif %} + </div> + </td> + <td class="post"> + <a id="post-{{ post.id }}" href="{{post.get_absolute_url}}" title="{% trans "Permalink" %}" class="posRight small permalink"> </a> + <span class="small">Posted at: {{ post.created|custom_date:user}}</span> + <hr /> + <div class="post"> + {{ post.body_html|safe }} + </div> + + {% if post.attachment_cache %} + {% for attach in post.attachment_cache %} + {% trans "Attachment" %}: <a href="{{ attach.get_absolute_url }}">{{ attach.name }}</a> ({{ attach.size_display }}) + {% endfor %} + {% endif %} + + {% if post.updated %} + <span class="small">{% trans "Edited" %}: {{ post.updated|custom_date:user|title}}</span> + {% endif %} + <hr /> + {% if user.is_authenticated %} + {% ifequal user.wlprofile.show_signatures 1 %} + {% if post.user.wlprofile.signature %} + {{ post.user.wlprofile.signature|urlize|linebreaks }} + {% endif %} + {% endifequal %} + {% else %} + {% if post.user.wlprofile.signature %} + {{ post.user.wlprofile.signature|urlize|linebreaks }} + {% endif %} + {% endif %} + + <button onclick="window.location.href='#top';" class="posRight"> + <img src="{{ MEDIA_URL }}forum/img/top.png" alt ="" class="middle" /> + <span class="middle">{% trans "Top" %}</span> + </button> + + <button onclick="window.location.href='{% url 'pybb_add_post' topic.id %}?quote_id={{ post.id }}';"> + <img src="{{ MEDIA_URL }}forum/img/quote.png" alt ="" class="middle" /> + <span class="middle">{% trans "Quote" %}</span> + </button> + {% if moderator or post|pybb_posted_by:user %} + <button onclick="window.location.href='{% url 'pybb_edit_post' post.id %}';"> + <img src="{{ MEDIA_URL }}forum/img/edit.png" alt ="" class="middle" /> + <span class="middle">{% trans "Edit" %}</span> + </button> + {% if moderator or post|pybb_equal_to:last_post %} + <button onclick="window.location.href='{% url 'pybb_delete_post' post.id %}';"> + <img src="{{ MEDIA_URL }}forum/img/delete.png" alt ="" class="middle" /> + <span class="middle">{% trans "Delete" %}</span> + </button> + {% endif %} + {% endif %} + </td> + </tr> + </tbody> + </table> + <br /><hr /><br /> + {% endwith %} + {% endifnotequal %} + {% endif %} + + <table class="forum"> + <tbody> + {% for post in object_list %} + {% comment %} + TODO (Franku): use + {% include 'pybb/inlines/post.html' %} + {% endcomment %} + <tr class="{% cycle 'odd' 'even' %}" {% if post.is_spam %} style="background-color: gray" {% endif %}> + <td class="author"> + {{ post.user|user_link }}<br /> + {% if post.user.wlprofile.avatar %} + <a href="{% url 'profile_view' post.user %}"> + <img src="{{ post.user.wlprofile.avatar.url }}" alt="Avatar" /> + </a> + {% endif %} + <div class="authorStats"> + <strong>Joined:</strong> {{ post.user.date_joined|custom_date:user|title }}<br /> + <strong>Posts:</strong> {{ post.user.wlprofile.post_count }}<br /> + <img src="{{ MEDIA_URL }}img/{{ post.user.wlprofile.user_status.image }}" alt="Ranking" /><br /> + <strong>{{ post.user.wlprofile.user_status.text }}</strong><br /> + {% if post.user.wlprofile.location %} + <strong>Location:</strong> {{ post.user.wlprofile.location }}<br /> + {% endif %} + </div> + </td> + <td class="post"> + <a id="post-{{ post.id }}" href="{{post.get_absolute_url}}" title="{% trans "Permalink" %}" class="posRight small permalink"> </a> + <span class="small">Posted at: {{ post.created|custom_date:user}}</span> + <hr /> + <div class="post"> + {{ post.body_html|safe }} + </div> + + {% if post.attachment_cache %} + {% for attach in post.attachment_cache %} + {% trans "Attachment" %}: <a href="{{ attach.get_absolute_url }}">{{ attach.name }}</a> ({{ attach.size_display }}) + {% endfor %} + {% endif %} + + {% if post.updated %} + <span class="small">{% trans "Edited" %}: {{ post.updated|custom_date:user|title}}</span> + {% endif %} + <hr /> + {% if user.is_authenticated %} + {% ifequal user.wlprofile.show_signatures 1 %} + {% if post.user.wlprofile.signature %} + {{ post.user.wlprofile.signature|urlize|linebreaks }} + {% endif %} + {% endifequal %} + {% else %} + {% if post.user.wlprofile.signature %} + {{ post.user.wlprofile.signature|urlize|linebreaks }} + {% endif %} + {% endif %} + + <a class="button posRight" href="#top"> + <img src="{{ MEDIA_URL }}forum/img/top.png" alt ="" class="middle" /> + <span class="middle">{% trans "Top" %}</span> + </a> + + <a class="button" href="{% url 'pybb_add_post' topic.id %}?quote_id={{ post.id }}"> + <img src="{{ MEDIA_URL }}forum/img/quote.png" alt ="" class="middle" /> + <span class="middle">{% trans "Quote" %}</span> + </a> + {% if moderator or post|pybb_posted_by:user %} + <a class="button" href="{% url 'pybb_edit_post' post.id %}"> + <img src="{{ MEDIA_URL }}forum/img/edit.png" alt ="" class="middle" /> + <span class="middle">{% trans "Edit" %}</span> + </a> + {% if moderator or post|pybb_equal_to:last_post %} + <a class="button" href="{% url 'pybb_delete_post' post.id %}"> + <img src="{{ MEDIA_URL }}forum/img/delete.png" alt ="" class="middle" /> + <span class="middle">{% trans "Delete" %}</span> + </a> + {% endif %} + {% endif %} + </td> + </tr> + {% if not forloop.last %} + {# no spacer at end of table #} + <tr class="spacer"> + <td></td> + <td></td> + </tr> + {% endif %} + {% endfor %} + </tbody> + </table> + + <div class="posRight"> + {% if moderator %} + <a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/topic_hide.png" alt ="" class="middle" /> + <span class="middle">{% trans "Toggle Visibility" %}</span> + </a> + {% if topic.sticky %} + <a class="button" href="{% url 'pybb_unstick_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/unstick.png" alt ="" class="middle" /> + <span class="middle">{% trans "Unstick Topic" %}</span> + </a> + {% else %} + <a class="button" href="{% url 'pybb_stick_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/sticky.png" alt ="" class="middle" /> + <span class="middle">{% trans "Stick Topic" %}</span> + </a> + {% endif %} + {% if topic.closed %} + <a class="button" href="{% url 'pybb_open_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/open.png" alt ="" class="middle" /> + <span class="middle">{% trans "Open Topic" %}</span> + </a> + {% else %} + <a class="button" href="{% url 'pybb_close_topic' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/closed.png" alt ="" class="middle" /> + <span class="middle">{% trans "Close Topic" %}</span> + </a> + {% endif %} + {% endif %} + {% if user.is_authenticated %} + {% if subscribed %} + <a class="button" href="{% url 'pybb_delete_subscription' topic.id %}?from_topic"> + <img src="{{ MEDIA_URL }}forum/img/unsubscribe.png" alt ="" class="middle" /> + <span class="middle">{% trans "Unsubscribe" %}</span> + </a> + {% else %} + <a class="button" href="{% url 'pybb_add_subscription' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/subscribe.png" alt ="" class="middle" /> + <span class="middle">{% trans "Subscribe" %}</span> + </a> + {% endif %} + <a class="button" href="{% url 'pybb_add_post' topic.id %}"> + <img src="{{ MEDIA_URL }}forum/img/send.png" alt ="" class="middle" /> + <span class="middle">{% trans "New Reply" %}</span> + </a> + {% endif %} + </div> + {% paginate %} + </div> + + {% if user.is_authenticated %} + {% if not topic.closed %} + {% include "pybb/inlines/add_post_form.html" %} + {% endif %} + {% endif %} + {% endif %} {% endblock %}
_______________________________________________ Mailing list: https://launchpad.net/~widelands-dev Post to : widelands-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~widelands-dev More help : https://help.launchpad.net/ListHelp