widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #15347
[Merge] lp:~widelands-dev/widelands-website/hidden_topics into lp:widelands-website
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 %}
Follow ups