Merge lp:~widelands-dev/widelands-website/hidden_topics into lp:widelands-website
- hidden_topics
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 506 |
Proposed branch: | lp:~widelands-dev/widelands-website/hidden_topics |
Merge into: | lp:widelands-website |
Diff against target: |
922 lines (+403/-324) 8 files modified
pybb/feeds.py (+2/-2) pybb/models.py (+54/-8) pybb/templatetags/pybb_extras.py (+6/-3) pybb/urls.py (+2/-0) pybb/views.py (+31/-30) templates/pybb/forum.html (+4/-0) templates/pybb/inlines/display_category.html (+6/-4) templates/pybb/topic.html (+298/-277) |
To merge this branch: | bzr merge lp:~widelands-dev/widelands-website/hidden_topics |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
GunChleoc | Approve | ||
Review via email: mp+358944@code.launchpad.net |
Commit message
Implement possibility to hide whole topics
Description of the change
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.
kaputtnik (franku) wrote : | # |
This merged and deployed now.
Preview Diff
1 | === added file 'media/forum/img/topic_hide.png' |
2 | Binary files media/forum/img/topic_hide.png 1970-01-01 00:00:00 +0000 and media/forum/img/topic_hide.png 2018-11-18 10:28:19 +0000 differ |
3 | === added file 'media/forum/img/topic_show.png' |
4 | Binary files media/forum/img/topic_show.png 1970-01-01 00:00:00 +0000 and media/forum/img/topic_show.png 2018-11-18 10:28:19 +0000 differ |
5 | === modified file 'pybb/feeds.py' |
6 | --- pybb/feeds.py 2018-09-12 07:45:35 +0000 |
7 | +++ pybb/feeds.py 2018-11-18 10:28:19 +0000 |
8 | @@ -56,10 +56,10 @@ |
9 | title_template = 'pybb/feeds/posts_title.html' |
10 | description_template = 'pybb/feeds/posts_description.html' |
11 | |
12 | - all_objects = Post.objects.filter(hidden=False) |
13 | + all_objects = Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(hidden=False) |
14 | |
15 | def items_for_object(self, obj): |
16 | - return Post.objects.filter(hidden=False, topic__forum=obj).order_by('-created')[:15] |
17 | + return Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(hidden=False, topic__forum=obj).order_by('-created')[:15] |
18 | |
19 | # Validated through http://validator.w3.org/feed/ |
20 | |
21 | |
22 | === modified file 'pybb/models.py' |
23 | --- pybb/models.py 2018-10-03 09:01:09 +0000 |
24 | +++ pybb/models.py 2018-11-18 10:28:19 +0000 |
25 | @@ -17,6 +17,8 @@ |
26 | from django.conf import settings |
27 | from notification.models import send |
28 | from django.contrib.auth.models import User |
29 | +from check_input.models import SuspiciousInput |
30 | + |
31 | |
32 | try: |
33 | from notification import models as notification |
34 | @@ -91,8 +93,16 @@ |
35 | |
36 | @property |
37 | def last_post(self): |
38 | - posts = self.posts.exclude(hidden=True).order_by( |
39 | + # This has better performance than using the posts manager hidden_topics |
40 | + # We search only for the last 10 topics |
41 | + topics = self.topics.order_by('-updated')[:10] |
42 | + for topic in topics: |
43 | + if topic.is_hidden: |
44 | + continue |
45 | + posts = topic.posts.exclude(hidden=True).order_by( |
46 | '-created').select_related() |
47 | + break |
48 | + |
49 | try: |
50 | return posts[0] |
51 | except IndexError: |
52 | @@ -122,21 +132,22 @@ |
53 | |
54 | @property |
55 | def head(self): |
56 | - return self.posts.all().order_by('created').select_related()[0] |
57 | + try: |
58 | + return self.posts.all().order_by('created').select_related()[0] |
59 | + except: |
60 | + return None |
61 | |
62 | @property |
63 | def last_post(self): |
64 | return self.posts.exclude(hidden=True).order_by('-created').select_related()[0] |
65 | |
66 | - # If the first post of this topic is hidden, the topic is hidden |
67 | @property |
68 | def is_hidden(self): |
69 | + # If the first post of this topic is hidden, the topic is hidden |
70 | try: |
71 | - p = self.posts.order_by('created').filter( |
72 | - hidden=False).select_related()[0] |
73 | - except IndexError: |
74 | - return True |
75 | - return False |
76 | + return self.posts.first().hidden |
77 | + except: |
78 | + return False |
79 | |
80 | @property |
81 | def post_count(self): |
82 | @@ -191,6 +202,30 @@ |
83 | self.body_html = urlize(self.body_html) |
84 | |
85 | |
86 | +class HiddenTopicsManager(models.Manager): |
87 | + """Find all hidden topics by posts. |
88 | + |
89 | + A whole topic is hidden, if the first post is hidden. |
90 | + This manager returns the hidden topics and can be used to filter them out |
91 | + like so: |
92 | + |
93 | + Post.objects.exclude(topic__in=Post.hidden_topics.all()).filter(...) |
94 | + |
95 | + Use this with caution, because it affects performance, see: |
96 | + https://docs.djangoproject.com/en/dev/ref/models/querysets/#in |
97 | + """ |
98 | + |
99 | + def get_queryset(self, *args, **kwargs): |
100 | + qs = super(HiddenTopicsManager, |
101 | + self).get_queryset().filter(hidden=True) |
102 | + |
103 | + hidden_topics = [] |
104 | + for post in qs: |
105 | + if post.topic.is_hidden: |
106 | + hidden_topics.append(post.topic) |
107 | + return hidden_topics |
108 | + |
109 | + |
110 | class Post(RenderableItem): |
111 | topic = models.ForeignKey( |
112 | Topic, related_name='posts', verbose_name=_('Topic')) |
113 | @@ -205,6 +240,9 @@ |
114 | body_text = models.TextField(_('Text version')) |
115 | hidden = models.BooleanField(_('Hidden'), blank=True, default=False) |
116 | |
117 | + objects = models.Manager() # Normal manager |
118 | + hidden_topics = HiddenTopicsManager() # Custom manager |
119 | + |
120 | class Meta: |
121 | ordering = ['created'] |
122 | verbose_name = _('Post') |
123 | @@ -260,6 +298,14 @@ |
124 | if self_id == head_post_id: |
125 | self.topic.delete() |
126 | |
127 | + def is_spam(self): |
128 | + try: |
129 | + SuspiciousInput.objects.get(object_id = self.pk) |
130 | + return True |
131 | + except: |
132 | + pass |
133 | + return False |
134 | + |
135 | |
136 | class Read(models.Model): |
137 | """For each topic that user has entered the time is logged to this |
138 | |
139 | === modified file 'pybb/templatetags/pybb_extras.py' |
140 | --- pybb/templatetags/pybb_extras.py 2018-09-11 20:16:31 +0000 |
141 | +++ pybb/templatetags/pybb_extras.py 2018-11-18 10:28:19 +0000 |
142 | @@ -82,14 +82,17 @@ |
143 | |
144 | @register.inclusion_tag('pybb/last_posts.html', takes_context=True) |
145 | def pybb_last_posts(context, number=8): |
146 | + |
147 | last_posts = Post.objects.filter(hidden=False).order_by( |
148 | '-created').select_related()[:45] |
149 | + |
150 | check = [] |
151 | answer = [] |
152 | for post in last_posts: |
153 | - if (post.topic_id not in check) and len(check) < number: |
154 | - check = check + [post.topic_id] |
155 | - answer = answer + [post] |
156 | + if not post.topic.is_hidden: |
157 | + if (post.topic_id not in check) and len(check) < number: |
158 | + check = check + [post.topic_id] |
159 | + answer = answer + [post] |
160 | return { |
161 | 'posts': answer, |
162 | } |
163 | |
164 | === modified file 'pybb/urls.py' |
165 | --- pybb/urls.py 2018-04-08 15:20:01 +0000 |
166 | +++ pybb/urls.py 2018-11-18 10:28:19 +0000 |
167 | @@ -30,6 +30,8 @@ |
168 | views.close_topic, name='pybb_close_topic'), |
169 | url('^topic/(?P<topic_id>\d+)/open/$', |
170 | views.open_topic, name='pybb_open_topic'), |
171 | + url('^topic/(?P<topic_id>\d+)/unhide/$', |
172 | + views.toggle_hidden_topic, name='pybb_toggle_hid_topic'), |
173 | |
174 | # Post |
175 | url('^topic/(?P<topic_id>\d+)/post/add/$', views.add_post, |
176 | |
177 | === modified file 'pybb/views.py' |
178 | --- pybb/views.py 2018-10-03 09:01:09 +0000 |
179 | +++ pybb/views.py 2018-11-18 10:28:19 +0000 |
180 | @@ -10,7 +10,7 @@ |
181 | from django.urls import reverse |
182 | from django.db import connection |
183 | from django.utils import translation |
184 | -from django.shortcuts import render |
185 | +from django.shortcuts import render, redirect |
186 | |
187 | |
188 | from pybb.util import render_to, paged, build_form, quote_text, ajax, urlize |
189 | @@ -29,52 +29,32 @@ |
190 | |
191 | |
192 | def index_ctx(request): |
193 | - quick = {'posts': Post.objects.count(), |
194 | - 'topics': Topic.objects.count(), |
195 | - 'users': User.objects.count(), |
196 | - 'last_topics': Topic.objects.all().select_related()[:pybb_settings.QUICK_TOPICS_NUMBER], |
197 | - 'last_posts': Post.objects.order_by('-created').select_related()[:pybb_settings.QUICK_POSTS_NUMBER], |
198 | - } |
199 | - |
200 | cats = Category.objects.all().select_related() |
201 | |
202 | - return {'cats': cats, |
203 | - 'quick': quick, |
204 | - } |
205 | + return {'cats': cats } |
206 | index = render_to('pybb/index.html')(index_ctx) |
207 | |
208 | |
209 | def show_category_ctx(request, category_id): |
210 | category = get_object_or_404(Category, pk=category_id) |
211 | - quick = {'posts': category.posts.count(), |
212 | - 'topics': category.topics.count(), |
213 | - 'last_topics': category.topics.select_related()[:pybb_settings.QUICK_TOPICS_NUMBER], |
214 | - 'last_posts': category.posts.order_by('-created').select_related() |
215 | - [:pybb_settings.QUICK_POSTS_NUMBER], |
216 | - } |
217 | - return {'category': category, |
218 | - 'quick': quick, |
219 | - } |
220 | + |
221 | + return {'category': category } |
222 | show_category = render_to('pybb/category.html')(show_category_ctx) |
223 | |
224 | |
225 | def show_forum_ctx(request, forum_id): |
226 | forum = get_object_or_404(Forum, pk=forum_id) |
227 | |
228 | - quick = {'posts': forum.post_count, |
229 | - 'topics': forum.topics.count(), |
230 | - 'last_topics': forum.topics.all().select_related()[:pybb_settings.QUICK_TOPICS_NUMBER], |
231 | - 'last_posts': forum.posts.order_by('-created').select_related() |
232 | - [:pybb_settings.QUICK_POSTS_NUMBER], |
233 | - } |
234 | + moderator = (request.user.is_superuser or |
235 | + request.user in forum.moderators.all()) |
236 | |
237 | topics = forum.topics.order_by( |
238 | - '-sticky', '-updated').exclude(posts__hidden=True).select_related() |
239 | + '-sticky', '-updated').select_related() |
240 | |
241 | return {'forum': forum, |
242 | 'topics': topics, |
243 | - 'quick': quick, |
244 | 'page_size': pybb_settings.FORUM_PAGE_SIZE, |
245 | + 'moderator': moderator, |
246 | } |
247 | show_forum = render_to('pybb/forum.html')(show_forum_ctx) |
248 | |
249 | @@ -106,8 +86,16 @@ |
250 | subscribed = (request.user.is_authenticated and |
251 | request.user in topic.subscribers.all()) |
252 | |
253 | - posts = topic.posts.exclude(hidden=True).select_related() |
254 | - |
255 | + |
256 | + is_spam = False |
257 | + if topic.is_hidden: |
258 | + is_spam = topic.posts.first().is_spam() |
259 | + |
260 | + if moderator: |
261 | + posts = topic.posts.select_related() |
262 | + else: |
263 | + posts = topic.posts.exclude(hidden=True).select_related() |
264 | + |
265 | # TODO: fetch profiles |
266 | # profiles = Profile.objects.filter(user__pk__in= |
267 | # set(x.user.id for x in page.object_list)) |
268 | @@ -127,6 +115,7 @@ |
269 | 'posts': posts, |
270 | 'page_size': pybb_settings.TOPIC_PAGE_SIZE, |
271 | 'form_url': reverse('pybb_add_post', args=[topic.id]), |
272 | + 'is_spam': is_spam, |
273 | } |
274 | show_topic = render_to('pybb/topic.html')(show_topic_ctx) |
275 | |
276 | @@ -393,3 +382,15 @@ |
277 | |
278 | def pybb_moderate_info(request): |
279 | return render(request, 'pybb/pybb_moderate_info.html') |
280 | + |
281 | + |
282 | +def toggle_hidden_topic(request, topic_id): |
283 | + topic = get_object_or_404(Topic, pk=topic_id) |
284 | + first_post = topic.posts.all()[0] |
285 | + if first_post.hidden: |
286 | + first_post.hidden = False |
287 | + else: |
288 | + first_post.hidden = True |
289 | + first_post.save() |
290 | + |
291 | + return redirect(topic) |
292 | \ No newline at end of file |
293 | |
294 | === modified file 'templates/pybb/forum.html' |
295 | --- templates/pybb/forum.html 2018-10-15 16:11:43 +0000 |
296 | +++ templates/pybb/forum.html 2018-11-18 10:28:19 +0000 |
297 | @@ -51,6 +51,7 @@ |
298 | <tbody> |
299 | {% for topic in object_list %} |
300 | <tr class="{% cycle 'odd' 'even' %}"> |
301 | + {% if not topic.is_hidden %} |
302 | <td class="forumIcon center"> |
303 | {% if topic|pybb_has_unreads:user %} |
304 | <img src="{{ MEDIA_URL }}forum/img/doc_big_work_star.png" style="margin: 0px;" alt="" class="middle" /> |
305 | @@ -74,6 +75,9 @@ |
306 | <span class="small">on {{ topic.last_post.created|custom_date:user }}</span> |
307 | {% endif %} |
308 | </td> |
309 | + {% elif moderator %} |
310 | + <td colspan="4" class="center errormessage">Hidden Topic: <a href="{{ topic.get_absolute_url }}">{{ topic.name }}</a></td> |
311 | + {% endif %} |
312 | </tr> |
313 | {% endfor %} |
314 | </tbody> |
315 | |
316 | === modified file 'templates/pybb/inlines/display_category.html' |
317 | --- templates/pybb/inlines/display_category.html 2016-10-29 20:47:11 +0000 |
318 | +++ templates/pybb/inlines/display_category.html 2018-11-18 10:28:19 +0000 |
319 | @@ -30,13 +30,15 @@ |
320 | Posts: {{ forum.posts.count }} |
321 | </td> |
322 | <td class="lastPost"> |
323 | - {%if forum.last_post %} |
324 | - <a href="{{forum.last_post.get_absolute_url}}">{{ forum.last_post.topic.name }}</a><br /> |
325 | - <span class="small">by {{ forum.last_post.user|user_link }}<br /> |
326 | - on {{ forum.last_post.created|custom_date:user}}</span> |
327 | + {% with last_post=forum.last_post %} |
328 | + {% if last_post %} |
329 | + <a href="{{last_post.get_absolute_url}}">{{ last_post.topic.name }}</a><br /> |
330 | + <span class="small">by {{ last_post.user|user_link }}<br /> |
331 | + on {{ last_post.created|custom_date:user}}</span> |
332 | {% else %} |
333 | |
334 | {% endif %} |
335 | + {% endwith %} |
336 | </td> |
337 | </tr> |
338 | {% endfor %} |
339 | |
340 | === modified file 'templates/pybb/topic.html' |
341 | --- templates/pybb/topic.html 2018-10-14 13:24:15 +0000 |
342 | +++ templates/pybb/topic.html 2018-11-18 10:28:19 +0000 |
343 | @@ -24,281 +24,302 @@ |
344 | {% block content_main %} |
345 | <div class="blogEntry"> |
346 | <div class="breadCrumb"> |
347 | - <a href="{% url 'pybb_index' %}">Forums</a> » |
348 | - {% pybb_link topic.forum.category %} » |
349 | - <a href="{{ topic.forum.get_absolute_url }}">{{ topic.forum.name }}</a> » |
350 | - {{ topic }} |
351 | - </div> |
352 | - |
353 | - <div class="posRight"> |
354 | - {% if moderator %} |
355 | - {% if topic.sticky %} |
356 | - <a class="button" href="{% url 'pybb_unstick_topic' topic.id %}"> |
357 | - <img src="{{ MEDIA_URL }}forum/img/unstick.png" alt ="" class="middle" /> |
358 | - <span class="middle">{% trans "Unstick Topic" %}</span> |
359 | - </a> |
360 | - {% else %} |
361 | - <a class="button" href="{% url 'pybb_stick_topic' topic.id %}"> |
362 | - <img src="{{ MEDIA_URL }}forum/img/sticky.png" alt ="" class="middle" /> |
363 | - <span class="middle">{% trans "Stick Topic" %}</span> |
364 | - </a> |
365 | - {% endif %} |
366 | - {% if topic.closed %} |
367 | - <a class="button" href="{% url 'pybb_open_topic' topic.id %}"> |
368 | - <img src="{{ MEDIA_URL }}forum/img/open.png" alt ="" class="middle" /> |
369 | - <span class="middle">{% trans "Open Topic" %}</span> |
370 | - </a> |
371 | - {% else %} |
372 | - <a class="button" href="{% url 'pybb_close_topic' topic.id %}"> |
373 | - <img src="{{ MEDIA_URL }}forum/img/closed.png" alt ="" class="middle" /> |
374 | - <span class="middle">{% trans "Close Topic" %}</span> |
375 | - </a> |
376 | - {% endif %} |
377 | - {% endif %} |
378 | - {% if user.is_authenticated %} |
379 | - {% if subscribed %} |
380 | - <a class="button" href="{% url 'pybb_delete_subscription' topic.id %}?from_topic"> |
381 | - <img src="{{ MEDIA_URL }}forum/img/unsubscribe.png" alt ="" class="middle" /> |
382 | - <span class="middle">{% trans "Unsubscribe" %}</span> |
383 | - </a> |
384 | - {% else %} |
385 | - <a class="button" href="{% url 'pybb_add_subscription' topic.id %}"> |
386 | - <img src="{{ MEDIA_URL }}forum/img/subscribe.png" alt ="" class="middle" /> |
387 | - <span class="middle">{% trans "Subscribe" %}</span> |
388 | - </a> |
389 | - {% endif %} |
390 | - <a class="button" href="{% url 'pybb_add_post' topic.id %}"> |
391 | - <img src="{{ MEDIA_URL }}forum/img/send.png" alt ="" class="middle" /> |
392 | - <span class="middle">{% trans "New Reply" %}</span> |
393 | - </a> |
394 | - {% endif %} |
395 | - </div> |
396 | - {% autopaginate posts page_size as object_list %} |
397 | - {% paginate using "pagination/pagination_mod.html" %} |
398 | - |
399 | -{% if first_post %} |
400 | - {% ifnotequal first_post posts.0 %} |
401 | - {% with first_post as post %} |
402 | - {% trans "First Post" %}: |
403 | - <table class="forum"> |
404 | - <tbody> |
405 | - <tr class="odd"> |
406 | - <td class="author"> |
407 | - {{ post.user|user_link }}<br /> |
408 | - {% if post.user.wlprofile_extras.avatar %} |
409 | - <a href="{% url 'profile_view' post.user %}"> |
410 | - <img src="{{ post.user.wlprofile.avatar.url }}" alt="Avatar" /> |
411 | - </a> |
412 | - {% endif %} |
413 | - <div class="authorStats"> |
414 | - <strong>Joined:</strong> {{ post.user.date_joined|custom_date:user|title }}<br /> |
415 | - <strong>Posts:</strong> {{ post.user.wlprofile.post_count }}<br /> |
416 | - <img src="{{ MEDIA_URL }}img/{{ post.user.wlprofile.user_status.image }}" alt="Ranking" /><br /> |
417 | - <strong>{{ post.user.wlprofile.user_status.text }}</strong><br /> |
418 | - {% if post.user.wlprofile.location %} |
419 | - <strong>Location:</strong> {{ post.user.wlprofile.location }}<br /> |
420 | - {% endif %} |
421 | - </div> |
422 | - </td> |
423 | - <td class="post"> |
424 | - <a id="post-{{ post.id }}" href="{{post.get_absolute_url}}" title="{% trans "Permalink" %}" class="posRight small permalink"> </a> |
425 | - <span class="small">Posted at: {{ post.created|custom_date:user}}</span> |
426 | - <hr /> |
427 | - <div class="post"> |
428 | - {{ post.body_html|safe }} |
429 | - </div> |
430 | - |
431 | - {% if post.attachment_cache %} |
432 | - {% for attach in post.attachment_cache %} |
433 | - {% trans "Attachment" %}: <a href="{{ attach.get_absolute_url }}">{{ attach.name }}</a> ({{ attach.size_display }}) |
434 | - {% endfor %} |
435 | - {% endif %} |
436 | - |
437 | - {% if post.updated %} |
438 | - <span class="small">{% trans "Edited" %}: {{ post.updated|custom_date:user|title}}</span> |
439 | - {% endif %} |
440 | - <hr /> |
441 | - {% if user.is_authenticated %} |
442 | - {% ifequal user.wlprofile.show_signatures 1 %} |
443 | - {% if post.user.wlprofile.signature %} |
444 | - {{ post.user.wlprofile.signature|urlize|linebreaks }} |
445 | - {% endif %} |
446 | - {% endifequal %} |
447 | - {% else %} |
448 | - {% if post.user.wlprofile.signature %} |
449 | - {{ post.user.wlprofile.signature|urlize|linebreaks }} |
450 | - {% endif %} |
451 | - {% endif %} |
452 | - |
453 | - <button onclick="window.location.href='#top';" class="posRight"> |
454 | - <img src="{{ MEDIA_URL }}forum/img/top.png" alt ="" class="middle" /> |
455 | - <span class="middle">{% trans "Top" %}</span> |
456 | - </button> |
457 | - |
458 | - <button onclick="window.location.href='{% url 'pybb_add_post' topic.id %}?quote_id={{ post.id }}';"> |
459 | - <img src="{{ MEDIA_URL }}forum/img/quote.png" alt ="" class="middle" /> |
460 | - <span class="middle">{% trans "Quote" %}</span> |
461 | - </button> |
462 | - {% if moderator or post|pybb_posted_by:user %} |
463 | - <button onclick="window.location.href='{% url 'pybb_edit_post' post.id %}';"> |
464 | - <img src="{{ MEDIA_URL }}forum/img/edit.png" alt ="" class="middle" /> |
465 | - <span class="middle">{% trans "Edit" %}</span> |
466 | - </button> |
467 | - {% if moderator or post|pybb_equal_to:last_post %} |
468 | - <button onclick="window.location.href='{% url 'pybb_delete_post' post.id %}';"> |
469 | - <img src="{{ MEDIA_URL }}forum/img/delete.png" alt ="" class="middle" /> |
470 | - <span class="middle">{% trans "Delete" %}</span> |
471 | - </button> |
472 | - {% endif %} |
473 | - {% endif %} |
474 | - </td> |
475 | - </tr> |
476 | - </tbody> |
477 | - </table> |
478 | - <br /><hr /><br /> |
479 | - {% endwith %} |
480 | - {% endifnotequal %} |
481 | -{% endif %} |
482 | - |
483 | - <table class="forum"> |
484 | - <tbody> |
485 | - {% for post in object_list %} |
486 | - {% comment %} |
487 | - TODO (Franku): use |
488 | - {% include 'pybb/inlines/post.html' %} |
489 | - {% endcomment %} |
490 | - <tr class="{% cycle 'odd' 'even' %}"> |
491 | - <td class="author"> |
492 | - {{ post.user|user_link }}<br /> |
493 | - {% if post.user.wlprofile.avatar %} |
494 | - <a href="{% url 'profile_view' post.user %}"> |
495 | - <img src="{{ post.user.wlprofile.avatar.url }}" alt="Avatar" /> |
496 | - </a> |
497 | - {% endif %} |
498 | - <div class="authorStats"> |
499 | - <strong>Joined:</strong> {{ post.user.date_joined|custom_date:user|title }}<br /> |
500 | - <strong>Posts:</strong> {{ post.user.wlprofile.post_count }}<br /> |
501 | - <img src="{{ MEDIA_URL }}img/{{ post.user.wlprofile.user_status.image }}" alt="Ranking" /><br /> |
502 | - <strong>{{ post.user.wlprofile.user_status.text }}</strong><br /> |
503 | - {% if post.user.wlprofile.location %} |
504 | - <strong>Location:</strong> {{ post.user.wlprofile.location }}<br /> |
505 | - {% endif %} |
506 | - </div> |
507 | - </td> |
508 | - <td class="post"> |
509 | - <a id="post-{{ post.id }}" href="{{post.get_absolute_url}}" title="{% trans "Permalink" %}" class="posRight small permalink"> </a> |
510 | - <span class="small">Posted at: {{ post.created|custom_date:user}}</span> |
511 | - <hr /> |
512 | - <div class="post"> |
513 | - {{ post.body_html|safe }} |
514 | - </div> |
515 | - |
516 | - {% if post.attachment_cache %} |
517 | - {% for attach in post.attachment_cache %} |
518 | - {% trans "Attachment" %}: <a href="{{ attach.get_absolute_url }}">{{ attach.name }}</a> ({{ attach.size_display }}) |
519 | - {% endfor %} |
520 | - {% endif %} |
521 | - |
522 | - {% if post.updated %} |
523 | - <span class="small">{% trans "Edited" %}: {{ post.updated|custom_date:user|title}}</span> |
524 | - {% endif %} |
525 | - <hr /> |
526 | - {% if user.is_authenticated %} |
527 | - {% ifequal user.wlprofile.show_signatures 1 %} |
528 | - {% if post.user.wlprofile.signature %} |
529 | - {{ post.user.wlprofile.signature|urlize|linebreaks }} |
530 | - {% endif %} |
531 | - {% endifequal %} |
532 | - {% else %} |
533 | - {% if post.user.wlprofile.signature %} |
534 | - {{ post.user.wlprofile.signature|urlize|linebreaks }} |
535 | - {% endif %} |
536 | - {% endif %} |
537 | - |
538 | - <a class="button posRight" href="#top"> |
539 | - <img src="{{ MEDIA_URL }}forum/img/top.png" alt ="" class="middle" /> |
540 | - <span class="middle">{% trans "Top" %}</span> |
541 | - </a> |
542 | - |
543 | - <a class="button" href="{% url 'pybb_add_post' topic.id %}?quote_id={{ post.id }}"> |
544 | - <img src="{{ MEDIA_URL }}forum/img/quote.png" alt ="" class="middle" /> |
545 | - <span class="middle">{% trans "Quote" %}</span> |
546 | - </a> |
547 | - {% if moderator or post|pybb_posted_by:user %} |
548 | - <a class="button" href="{% url 'pybb_edit_post' post.id %}"> |
549 | - <img src="{{ MEDIA_URL }}forum/img/edit.png" alt ="" class="middle" /> |
550 | - <span class="middle">{% trans "Edit" %}</span> |
551 | - </a> |
552 | - {% if moderator or post|pybb_equal_to:last_post %} |
553 | - <a class="button" href="{% url 'pybb_delete_post' post.id %}"> |
554 | - <img src="{{ MEDIA_URL }}forum/img/delete.png" alt ="" class="middle" /> |
555 | - <span class="middle">{% trans "Delete" %}</span> |
556 | - </a> |
557 | - {% endif %} |
558 | - {% endif %} |
559 | - </td> |
560 | - </tr> |
561 | - {% if not forloop.last %} |
562 | - {# no spacer at end of table #} |
563 | - <tr class="spacer"> |
564 | - <td></td> |
565 | - <td></td> |
566 | - </tr> |
567 | - {% endif %} |
568 | - {% endfor %} |
569 | - </tbody> |
570 | - </table> |
571 | - |
572 | - <div class="posRight"> |
573 | - {% if moderator %} |
574 | - {% if topic.sticky %} |
575 | - <a class="button" href="{% url 'pybb_unstick_topic' topic.id %}"> |
576 | - <img src="{{ MEDIA_URL }}forum/img/unstick.png" alt ="" class="middle" /> |
577 | - <span class="middle">{% trans "Unstick Topic" %}</span> |
578 | - </a> |
579 | - {% else %} |
580 | - <a class="button" href="{% url 'pybb_stick_topic' topic.id %}"> |
581 | - <img src="{{ MEDIA_URL }}forum/img/sticky.png" alt ="" class="middle" /> |
582 | - <span class="middle">{% trans "Stick Topic" %}</span> |
583 | - </a> |
584 | - {% endif %} |
585 | - {% if topic.closed %} |
586 | - <a class="button" href="{% url 'pybb_open_topic' topic.id %}"> |
587 | - <img src="{{ MEDIA_URL }}forum/img/open.png" alt ="" class="middle" /> |
588 | - <span class="middle">{% trans "Open Topic" %}</span> |
589 | - </a> |
590 | - {% else %} |
591 | - <a class="button" href="{% url 'pybb_close_topic' topic.id %}"> |
592 | - <img src="{{ MEDIA_URL }}forum/img/closed.png" alt ="" class="middle" /> |
593 | - <span class="middle">{% trans "Close Topic" %}</span> |
594 | - </a> |
595 | - {% endif %} |
596 | - {% endif %} |
597 | - {% if user.is_authenticated %} |
598 | - {% if subscribed %} |
599 | - <a class="button" href="{% url 'pybb_delete_subscription' topic.id %}?from_topic"> |
600 | - <img src="{{ MEDIA_URL }}forum/img/unsubscribe.png" alt ="" class="middle" /> |
601 | - <span class="middle">{% trans "Unsubscribe" %}</span> |
602 | - </a> |
603 | - {% else %} |
604 | - <a class="button" href="{% url 'pybb_add_subscription' topic.id %}"> |
605 | - <img src="{{ MEDIA_URL }}forum/img/subscribe.png" alt ="" class="middle" /> |
606 | - <span class="middle">{% trans "Subscribe" %}</span> |
607 | - </a> |
608 | - {% endif %} |
609 | - <a class="button" href="{% url 'pybb_add_post' topic.id %}"> |
610 | - <img src="{{ MEDIA_URL }}forum/img/send.png" alt ="" class="middle" /> |
611 | - <span class="middle">{% trans "New Reply" %}</span> |
612 | - </a> |
613 | - {% endif %} |
614 | - </div> |
615 | - {% paginate %} |
616 | -</div> |
617 | - |
618 | -{% if user.is_authenticated %} |
619 | - {% if not topic.closed %} |
620 | - {% include "pybb/inlines/add_post_form.html" %} |
621 | - {% endif %} |
622 | -{% endif %} |
623 | - |
624 | + <a href="{% url 'pybb_index' %}">Forums</a> » |
625 | + {% pybb_link topic.forum.category %} » |
626 | + <a href="{{ topic.forum.get_absolute_url }}">{{ topic.forum.name }}</a> » |
627 | + {{ topic }} |
628 | + </div> |
629 | + {% if topic.is_hidden %} |
630 | + <p>This topic is hidden. It is either waiting for a review or was hidden by a moderator.</p> |
631 | + {% if posts.0.is_spam and moderator %} |
632 | + <p>This topic's first post is possible spam. Toggle the visibility to show the post. If it is indeed spam, consider deleting the user:</p> |
633 | + <p>To delete the user, go to the <a href="/admin/auth/user/{{posts.0.user.pk}}/change/">admin user-page for the post's author</a></p> |
634 | + {% endif %} |
635 | + <div class="posRight"> |
636 | + {% if moderator %} |
637 | + <a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}"> |
638 | + <img src="{{ MEDIA_URL }}forum/img/topic_show.png" alt ="" class="middle" /> |
639 | + <span class="middle">{% trans "Toggle Visibility" %}</span> |
640 | + </a> |
641 | + {% endif %} |
642 | + {% else %} |
643 | + <div class="posRight"> |
644 | + {% if moderator %} |
645 | + <a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}"> |
646 | + <img src="{{ MEDIA_URL }}forum/img/topic_hide.png" alt ="" class="middle" /> |
647 | + <span class="middle">{% trans "Toggle Visibility" %}</span> |
648 | + </a> |
649 | + {% if topic.sticky %} |
650 | + <a class="button" href="{% url 'pybb_unstick_topic' topic.id %}"> |
651 | + <img src="{{ MEDIA_URL }}forum/img/unstick.png" alt ="" class="middle" /> |
652 | + <span class="middle">{% trans "Unstick Topic" %}</span> |
653 | + </a> |
654 | + {% else %} |
655 | + <a class="button" href="{% url 'pybb_stick_topic' topic.id %}"> |
656 | + <img src="{{ MEDIA_URL }}forum/img/sticky.png" alt ="" class="middle" /> |
657 | + <span class="middle">{% trans "Stick Topic" %}</span> |
658 | + </a> |
659 | + {% endif %} |
660 | + {% if topic.closed %} |
661 | + <a class="button" href="{% url 'pybb_open_topic' topic.id %}"> |
662 | + <img src="{{ MEDIA_URL }}forum/img/open.png" alt ="" class="middle" /> |
663 | + <span class="middle">{% trans "Open Topic" %}</span> |
664 | + </a> |
665 | + {% else %} |
666 | + <a class="button" href="{% url 'pybb_close_topic' topic.id %}"> |
667 | + <img src="{{ MEDIA_URL }}forum/img/closed.png" alt ="" class="middle" /> |
668 | + <span class="middle">{% trans "Close Topic" %}</span> |
669 | + </a> |
670 | + {% endif %} |
671 | + {% endif %} |
672 | + {% if user.is_authenticated %} |
673 | + {% if subscribed %} |
674 | + <a class="button" href="{% url 'pybb_delete_subscription' topic.id %}?from_topic"> |
675 | + <img src="{{ MEDIA_URL }}forum/img/unsubscribe.png" alt ="" class="middle" /> |
676 | + <span class="middle">{% trans "Unsubscribe" %}</span> |
677 | + </a> |
678 | + {% else %} |
679 | + <a class="button" href="{% url 'pybb_add_subscription' topic.id %}"> |
680 | + <img src="{{ MEDIA_URL }}forum/img/subscribe.png" alt ="" class="middle" /> |
681 | + <span class="middle">{% trans "Subscribe" %}</span> |
682 | + </a> |
683 | + {% endif %} |
684 | + <a class="button" href="{% url 'pybb_add_post' topic.id %}"> |
685 | + <img src="{{ MEDIA_URL }}forum/img/send.png" alt ="" class="middle" /> |
686 | + <span class="middle">{% trans "New Reply" %}</span> |
687 | + </a> |
688 | + {% endif %} |
689 | + </div> |
690 | + {% autopaginate posts page_size as object_list %} |
691 | + {% paginate using "pagination/pagination_mod.html" %} |
692 | + |
693 | + {% if first_post %} |
694 | + {% ifnotequal first_post posts.0 %} |
695 | + {% with first_post as post %} |
696 | + {% trans "First Post" %}: |
697 | + <table class="forum"> |
698 | + <tbody> |
699 | + <tr class="odd"> |
700 | + <td class="author"> |
701 | + {{ post.user|user_link }}<br /> |
702 | + {% if post.user.wlprofile_extras.avatar %} |
703 | + <a href="{% url 'profile_view' post.user %}"> |
704 | + <img src="{{ post.user.wlprofile.avatar.url }}" alt="Avatar" /> |
705 | + </a> |
706 | + {% endif %} |
707 | + <div class="authorStats"> |
708 | + <strong>Joined:</strong> {{ post.user.date_joined|custom_date:user|title }}<br /> |
709 | + <strong>Posts:</strong> {{ post.user.wlprofile.post_count }}<br /> |
710 | + <img src="{{ MEDIA_URL }}img/{{ post.user.wlprofile.user_status.image }}" alt="Ranking" /><br /> |
711 | + <strong>{{ post.user.wlprofile.user_status.text }}</strong><br /> |
712 | + {% if post.user.wlprofile.location %} |
713 | + <strong>Location:</strong> {{ post.user.wlprofile.location }}<br /> |
714 | + {% endif %} |
715 | + </div> |
716 | + </td> |
717 | + <td class="post"> |
718 | + <a id="post-{{ post.id }}" href="{{post.get_absolute_url}}" title="{% trans "Permalink" %}" class="posRight small permalink"> </a> |
719 | + <span class="small">Posted at: {{ post.created|custom_date:user}}</span> |
720 | + <hr /> |
721 | + <div class="post"> |
722 | + {{ post.body_html|safe }} |
723 | + </div> |
724 | + |
725 | + {% if post.attachment_cache %} |
726 | + {% for attach in post.attachment_cache %} |
727 | + {% trans "Attachment" %}: <a href="{{ attach.get_absolute_url }}">{{ attach.name }}</a> ({{ attach.size_display }}) |
728 | + {% endfor %} |
729 | + {% endif %} |
730 | + |
731 | + {% if post.updated %} |
732 | + <span class="small">{% trans "Edited" %}: {{ post.updated|custom_date:user|title}}</span> |
733 | + {% endif %} |
734 | + <hr /> |
735 | + {% if user.is_authenticated %} |
736 | + {% ifequal user.wlprofile.show_signatures 1 %} |
737 | + {% if post.user.wlprofile.signature %} |
738 | + {{ post.user.wlprofile.signature|urlize|linebreaks }} |
739 | + {% endif %} |
740 | + {% endifequal %} |
741 | + {% else %} |
742 | + {% if post.user.wlprofile.signature %} |
743 | + {{ post.user.wlprofile.signature|urlize|linebreaks }} |
744 | + {% endif %} |
745 | + {% endif %} |
746 | + |
747 | + <button onclick="window.location.href='#top';" class="posRight"> |
748 | + <img src="{{ MEDIA_URL }}forum/img/top.png" alt ="" class="middle" /> |
749 | + <span class="middle">{% trans "Top" %}</span> |
750 | + </button> |
751 | + |
752 | + <button onclick="window.location.href='{% url 'pybb_add_post' topic.id %}?quote_id={{ post.id }}';"> |
753 | + <img src="{{ MEDIA_URL }}forum/img/quote.png" alt ="" class="middle" /> |
754 | + <span class="middle">{% trans "Quote" %}</span> |
755 | + </button> |
756 | + {% if moderator or post|pybb_posted_by:user %} |
757 | + <button onclick="window.location.href='{% url 'pybb_edit_post' post.id %}';"> |
758 | + <img src="{{ MEDIA_URL }}forum/img/edit.png" alt ="" class="middle" /> |
759 | + <span class="middle">{% trans "Edit" %}</span> |
760 | + </button> |
761 | + {% if moderator or post|pybb_equal_to:last_post %} |
762 | + <button onclick="window.location.href='{% url 'pybb_delete_post' post.id %}';"> |
763 | + <img src="{{ MEDIA_URL }}forum/img/delete.png" alt ="" class="middle" /> |
764 | + <span class="middle">{% trans "Delete" %}</span> |
765 | + </button> |
766 | + {% endif %} |
767 | + {% endif %} |
768 | + </td> |
769 | + </tr> |
770 | + </tbody> |
771 | + </table> |
772 | + <br /><hr /><br /> |
773 | + {% endwith %} |
774 | + {% endifnotequal %} |
775 | + {% endif %} |
776 | + |
777 | + <table class="forum"> |
778 | + <tbody> |
779 | + {% for post in object_list %} |
780 | + {% comment %} |
781 | + TODO (Franku): use |
782 | + {% include 'pybb/inlines/post.html' %} |
783 | + {% endcomment %} |
784 | + <tr class="{% cycle 'odd' 'even' %}" {% if post.is_spam %} style="background-color: gray" {% endif %}> |
785 | + <td class="author"> |
786 | + {{ post.user|user_link }}<br /> |
787 | + {% if post.user.wlprofile.avatar %} |
788 | + <a href="{% url 'profile_view' post.user %}"> |
789 | + <img src="{{ post.user.wlprofile.avatar.url }}" alt="Avatar" /> |
790 | + </a> |
791 | + {% endif %} |
792 | + <div class="authorStats"> |
793 | + <strong>Joined:</strong> {{ post.user.date_joined|custom_date:user|title }}<br /> |
794 | + <strong>Posts:</strong> {{ post.user.wlprofile.post_count }}<br /> |
795 | + <img src="{{ MEDIA_URL }}img/{{ post.user.wlprofile.user_status.image }}" alt="Ranking" /><br /> |
796 | + <strong>{{ post.user.wlprofile.user_status.text }}</strong><br /> |
797 | + {% if post.user.wlprofile.location %} |
798 | + <strong>Location:</strong> {{ post.user.wlprofile.location }}<br /> |
799 | + {% endif %} |
800 | + </div> |
801 | + </td> |
802 | + <td class="post"> |
803 | + <a id="post-{{ post.id }}" href="{{post.get_absolute_url}}" title="{% trans "Permalink" %}" class="posRight small permalink"> </a> |
804 | + <span class="small">Posted at: {{ post.created|custom_date:user}}</span> |
805 | + <hr /> |
806 | + <div class="post"> |
807 | + {{ post.body_html|safe }} |
808 | + </div> |
809 | + |
810 | + {% if post.attachment_cache %} |
811 | + {% for attach in post.attachment_cache %} |
812 | + {% trans "Attachment" %}: <a href="{{ attach.get_absolute_url }}">{{ attach.name }}</a> ({{ attach.size_display }}) |
813 | + {% endfor %} |
814 | + {% endif %} |
815 | + |
816 | + {% if post.updated %} |
817 | + <span class="small">{% trans "Edited" %}: {{ post.updated|custom_date:user|title}}</span> |
818 | + {% endif %} |
819 | + <hr /> |
820 | + {% if user.is_authenticated %} |
821 | + {% ifequal user.wlprofile.show_signatures 1 %} |
822 | + {% if post.user.wlprofile.signature %} |
823 | + {{ post.user.wlprofile.signature|urlize|linebreaks }} |
824 | + {% endif %} |
825 | + {% endifequal %} |
826 | + {% else %} |
827 | + {% if post.user.wlprofile.signature %} |
828 | + {{ post.user.wlprofile.signature|urlize|linebreaks }} |
829 | + {% endif %} |
830 | + {% endif %} |
831 | + |
832 | + <a class="button posRight" href="#top"> |
833 | + <img src="{{ MEDIA_URL }}forum/img/top.png" alt ="" class="middle" /> |
834 | + <span class="middle">{% trans "Top" %}</span> |
835 | + </a> |
836 | + |
837 | + <a class="button" href="{% url 'pybb_add_post' topic.id %}?quote_id={{ post.id }}"> |
838 | + <img src="{{ MEDIA_URL }}forum/img/quote.png" alt ="" class="middle" /> |
839 | + <span class="middle">{% trans "Quote" %}</span> |
840 | + </a> |
841 | + {% if moderator or post|pybb_posted_by:user %} |
842 | + <a class="button" href="{% url 'pybb_edit_post' post.id %}"> |
843 | + <img src="{{ MEDIA_URL }}forum/img/edit.png" alt ="" class="middle" /> |
844 | + <span class="middle">{% trans "Edit" %}</span> |
845 | + </a> |
846 | + {% if moderator or post|pybb_equal_to:last_post %} |
847 | + <a class="button" href="{% url 'pybb_delete_post' post.id %}"> |
848 | + <img src="{{ MEDIA_URL }}forum/img/delete.png" alt ="" class="middle" /> |
849 | + <span class="middle">{% trans "Delete" %}</span> |
850 | + </a> |
851 | + {% endif %} |
852 | + {% endif %} |
853 | + </td> |
854 | + </tr> |
855 | + {% if not forloop.last %} |
856 | + {# no spacer at end of table #} |
857 | + <tr class="spacer"> |
858 | + <td></td> |
859 | + <td></td> |
860 | + </tr> |
861 | + {% endif %} |
862 | + {% endfor %} |
863 | + </tbody> |
864 | + </table> |
865 | + |
866 | + <div class="posRight"> |
867 | + {% if moderator %} |
868 | + <a class="button" href="{% url 'pybb_toggle_hid_topic' topic.id %}"> |
869 | + <img src="{{ MEDIA_URL }}forum/img/topic_hide.png" alt ="" class="middle" /> |
870 | + <span class="middle">{% trans "Toggle Visibility" %}</span> |
871 | + </a> |
872 | + {% if topic.sticky %} |
873 | + <a class="button" href="{% url 'pybb_unstick_topic' topic.id %}"> |
874 | + <img src="{{ MEDIA_URL }}forum/img/unstick.png" alt ="" class="middle" /> |
875 | + <span class="middle">{% trans "Unstick Topic" %}</span> |
876 | + </a> |
877 | + {% else %} |
878 | + <a class="button" href="{% url 'pybb_stick_topic' topic.id %}"> |
879 | + <img src="{{ MEDIA_URL }}forum/img/sticky.png" alt ="" class="middle" /> |
880 | + <span class="middle">{% trans "Stick Topic" %}</span> |
881 | + </a> |
882 | + {% endif %} |
883 | + {% if topic.closed %} |
884 | + <a class="button" href="{% url 'pybb_open_topic' topic.id %}"> |
885 | + <img src="{{ MEDIA_URL }}forum/img/open.png" alt ="" class="middle" /> |
886 | + <span class="middle">{% trans "Open Topic" %}</span> |
887 | + </a> |
888 | + {% else %} |
889 | + <a class="button" href="{% url 'pybb_close_topic' topic.id %}"> |
890 | + <img src="{{ MEDIA_URL }}forum/img/closed.png" alt ="" class="middle" /> |
891 | + <span class="middle">{% trans "Close Topic" %}</span> |
892 | + </a> |
893 | + {% endif %} |
894 | + {% endif %} |
895 | + {% if user.is_authenticated %} |
896 | + {% if subscribed %} |
897 | + <a class="button" href="{% url 'pybb_delete_subscription' topic.id %}?from_topic"> |
898 | + <img src="{{ MEDIA_URL }}forum/img/unsubscribe.png" alt ="" class="middle" /> |
899 | + <span class="middle">{% trans "Unsubscribe" %}</span> |
900 | + </a> |
901 | + {% else %} |
902 | + <a class="button" href="{% url 'pybb_add_subscription' topic.id %}"> |
903 | + <img src="{{ MEDIA_URL }}forum/img/subscribe.png" alt ="" class="middle" /> |
904 | + <span class="middle">{% trans "Subscribe" %}</span> |
905 | + </a> |
906 | + {% endif %} |
907 | + <a class="button" href="{% url 'pybb_add_post' topic.id %}"> |
908 | + <img src="{{ MEDIA_URL }}forum/img/send.png" alt ="" class="middle" /> |
909 | + <span class="middle">{% trans "New Reply" %}</span> |
910 | + </a> |
911 | + {% endif %} |
912 | + </div> |
913 | + {% paginate %} |
914 | + </div> |
915 | + |
916 | + {% if user.is_authenticated %} |
917 | + {% if not topic.closed %} |
918 | + {% include "pybb/inlines/add_post_form.html" %} |
919 | + {% endif %} |
920 | + {% endif %} |
921 | + {% endif %} |
922 | {% endblock %} |
Just some few nits for the English language. Thanks for taking care of this so fast!