##// END OF EJS Templates
Truncate line breaks
neko259 -
r1786:bce744de default
parent child Browse files
Show More
@@ -1,112 +1,112 b''
1 {% load i18n %}
1 {% load i18n %}
2 {% load board %}
2 {% load board %}
3
3
4 {% get_current_language as LANGUAGE_CODE %}
4 {% get_current_language as LANGUAGE_CODE %}
5
5
6 <div class="{{ css_class }}" id="{{ post.id }}" data-uid="{{ post.uid }}" {% if tree_depth %}style="margin-left: {{ tree_depth }}em;"{% endif %}>
6 <div class="{{ css_class }}" id="{{ post.id }}" data-uid="{{ post.uid }}" {% if tree_depth %}style="margin-left: {{ tree_depth }}em;"{% endif %}>
7 <div class="post-info">
7 <div class="post-info">
8 <a class="post_id" href="{{ post.get_absolute_url }}">#{{ post.id }}</a>
8 <a class="post_id" href="{{ post.get_absolute_url }}">#{{ post.id }}</a>
9 <span class="title">{{ post.title }}</span>
9 <span class="title">{{ post.title }}</span>
10 {% if perms.boards.change_post and post.has_ip %}
10 {% if perms.boards.change_post and post.has_ip %}
11 <a href="{% url 'feed' %}?ip={{ post.poster_ip }}">*</a>
11 <a href="{% url 'feed' %}?ip={{ post.poster_ip }}">*</a>
12 <span class="pub_time" style="border-bottom: solid 2px #{{ post.get_ip_color }};" title="{{ post.poster_ip }}">
12 <span class="pub_time" style="border-bottom: solid 2px #{{ post.get_ip_color }};" title="{{ post.poster_ip }}">
13 {% else %}
13 {% else %}
14 <span class="pub_time">
14 <span class="pub_time">
15 {% endif %}
15 {% endif %}
16 <time datetime="{{ post.pub_time|date:'c' }}">{{ post.pub_time }}</time></span>
16 <time datetime="{{ post.pub_time|date:'c' }}">{{ post.pub_time }}</time></span>
17 {% if post.tripcode %}
17 {% if post.tripcode %}
18 /
18 /
19 {% with tripcode=post.get_tripcode %}
19 {% with tripcode=post.get_tripcode %}
20 <a href="{% url 'feed' %}?tripcode={{ tripcode.get_full_text }}"
20 <a href="{% url 'feed' %}?tripcode={{ tripcode.get_full_text }}"
21 class="tripcode" title="{{ tripcode.get_full_text }}"
21 class="tripcode" title="{{ tripcode.get_full_text }}"
22 style="border: solid 2px #{{ tripcode.get_color }}; border-left: solid 1ex #{{ tripcode.get_color }};">{{ tripcode.get_short_text }}</a>
22 style="border: solid 2px #{{ tripcode.get_color }}; border-left: solid 1ex #{{ tripcode.get_color }};">{{ tripcode.get_short_text }}</a>
23 {% endwith %}
23 {% endwith %}
24 {% endif %}
24 {% endif %}
25 {% comment %}
25 {% comment %}
26 Thread death time needs to be shown only if the thread is alredy archived
26 Thread death time needs to be shown only if the thread is alredy archived
27 and this is an opening post (thread death time) or a post for popup
27 and this is an opening post (thread death time) or a post for popup
28 (we don't see OP here so we show the death time in the post itself).
28 (we don't see OP here so we show the death time in the post itself).
29 {% endcomment %}
29 {% endcomment %}
30 {% if is_opening and thread.is_archived %}
30 {% if is_opening and thread.is_archived %}
31 β€” <time datetime="{{ thread.bump_time|date:'c' }}">{{ thread.bump_time }}</time>
31 β€” <time datetime="{{ thread.bump_time|date:'c' }}">{{ thread.bump_time }}</time>
32 {% endif %}
32 {% endif %}
33 {% if is_opening %}
33 {% if is_opening %}
34 {% if need_open_link %}
34 {% if need_open_link %}
35 {% if thread.is_archived %}
35 {% if thread.is_archived %}
36 <a class="link" href="{% url 'thread' post.id %}">{% trans "Open" %}</a>
36 <a class="link" href="{% url 'thread' post.id %}">{% trans "Open" %}</a>
37 {% else %}
37 {% else %}
38 <a class="link" href="{% url 'thread' post.id %}#form">{% trans "Reply" %}</a>
38 <a class="link" href="{% url 'thread' post.id %}#form">{% trans "Reply" %}</a>
39 {% endif %}
39 {% endif %}
40 {% endif %}
40 {% endif %}
41 {% else %}
41 {% else %}
42 {% if need_op_data %}
42 {% if need_op_data %}
43 {% with thread.get_opening_post as op %}
43 {% with thread.get_opening_post as op %}
44 {% trans " in " %}{{ op.get_link_view|safe }} <span class="title">{{ op.get_title_or_text }}</span>
44 {% trans " in " %}{{ op.get_link_view|safe }} <span class="title">{{ op.get_title_or_text }}</span>
45 {% endwith %}
45 {% endwith %}
46 {% endif %}
46 {% endif %}
47 {% endif %}
47 {% endif %}
48 {% if reply_link and not thread.is_archived %}
48 {% if reply_link and not thread.is_archived %}
49 <a href="#form" onclick="addQuickReply('{{ post.id }}'); return false;">{% trans 'Reply' %}</a>
49 <a href="#form" onclick="addQuickReply('{{ post.id }}'); return false;">{% trans 'Reply' %}</a>
50 {% endif %}
50 {% endif %}
51
51
52 {% if perms.boards.change_post or perms.boards.delete_post or perms.boards.change_thread or perms_boards.delete_thread %}
52 {% if perms.boards.change_post or perms.boards.delete_post or perms.boards.change_thread or perms_boards.delete_thread %}
53 <span class="moderator_info">
53 <span class="moderator_info">
54 {% if perms.boards.change_post or perms.boards.delete_post %}
54 {% if perms.boards.change_post or perms.boards.delete_post %}
55 | <a href="{% url 'admin:boards_post_change' post.id %}">{% trans 'Edit' %}</a>
55 | <a href="{% url 'admin:boards_post_change' post.id %}">{% trans 'Edit' %}</a>
56 {% endif %}
56 {% endif %}
57 {% if perms.boards.change_thread or perms_boards.delete_thread %}
57 {% if perms.boards.change_thread or perms_boards.delete_thread %}
58 {% if is_opening %}
58 {% if is_opening %}
59 | <a href="{% url 'admin:boards_thread_change' thread.id %}">{% trans 'Edit thread' %}</a>
59 | <a href="{% url 'admin:boards_thread_change' thread.id %}">{% trans 'Edit thread' %}</a>
60 | <a href="{% url 'admin:boards_thread_delete' thread.id %}">{% trans 'Delete thread' %}</a>
60 | <a href="{% url 'admin:boards_thread_delete' thread.id %}">{% trans 'Delete thread' %}</a>
61 {% else %}
61 {% else %}
62 | <a href="{% url 'admin:boards_post_delete' post.id %}">{% trans 'Delete post' %}</a>
62 | <a href="{% url 'admin:boards_post_delete' post.id %}">{% trans 'Delete post' %}</a>
63 {% endif %}
63 {% endif %}
64 {% endif %}
64 {% endif %}
65 {% if post.global_id_id %}
65 {% if post.global_id_id %}
66 | <a href="{% url 'post_sync_data' post.id %}">RAW</a>
66 | <a href="{% url 'post_sync_data' post.id %}">RAW</a>
67 {% endif %}
67 {% endif %}
68 </span>
68 </span>
69 {% endif %}
69 {% endif %}
70 </div>
70 </div>
71 {% comment %}
71 {% comment %}
72 Post images. Currently only 1 image can be posted and shown, but post model
72 Post images. Currently only 1 image can be posted and shown, but post model
73 supports multiple.
73 supports multiple.
74 {% endcomment %}
74 {% endcomment %}
75 {% for image in post.images.all %}
75 {% for image in post.images.all %}
76 {{ image.get_view|safe }}
76 {{ image.get_view|safe }}
77 {% endfor %}
77 {% endfor %}
78 {% for file in post.attachments.all %}
78 {% for file in post.attachments.all %}
79 {{ file.get_view|safe }}
79 {{ file.get_view|safe }}
80 {% endfor %}
80 {% endfor %}
81 {% comment %}
81 {% comment %}
82 Post message (text)
82 Post message (text)
83 {% endcomment %}
83 {% endcomment %}
84 <div class="message">
84 <div class="message">
85 {% if truncated %}
85 {% if truncated %}
86 {{ post.get_text|truncatewords_html:50|safe }}
86 {{ post.get_text|truncatewords_html:50|truncatenewlines_html:3|safe }}
87 {% else %}
87 {% else %}
88 {{ post.get_text|safe }}
88 {{ post.get_text|safe }}
89 {% endif %}
89 {% endif %}
90 </div>
90 </div>
91 {% if post.is_referenced and not mode_tree %}
91 {% if post.is_referenced and not mode_tree %}
92 <div class="refmap">
92 <div class="refmap">
93 {% trans "Replies" %}: {{ post.refmap|safe }}
93 {% trans "Replies" %}: {{ post.refmap|safe }}
94 </div>
94 </div>
95 {% endif %}
95 {% endif %}
96 {% comment %}
96 {% comment %}
97 Thread metadata: counters, tags etc
97 Thread metadata: counters, tags etc
98 {% endcomment %}
98 {% endcomment %}
99 {% if is_opening %}
99 {% if is_opening %}
100 <div class="metadata">
100 <div class="metadata">
101 {% if need_open_link %}
101 {% if need_open_link %}
102 β™₯ {{ thread.get_reply_count }}
102 β™₯ {{ thread.get_reply_count }}
103 ❄ {{ thread.get_images_count }}
103 ❄ {{ thread.get_images_count }}
104 <a href="{% url 'thread_gallery' post.id %}">G</a>
104 <a href="{% url 'thread_gallery' post.id %}">G</a>
105 <a href="{% url 'thread_tree' post.id %}">T</a>
105 <a href="{% url 'thread_tree' post.id %}">T</a>
106 {% endif %}
106 {% endif %}
107 <span class="tags">
107 <span class="tags">
108 {{ thread.get_tag_url_list|safe }}
108 {{ thread.get_tag_url_list|safe }}
109 </span>
109 </span>
110 </div>
110 </div>
111 {% endif %}
111 {% endif %}
112 </div>
112 </div>
@@ -1,51 +1,116 b''
1 import re
1 import re
2
2 from django.shortcuts import get_object_or_404
3 from django.shortcuts import get_object_or_404
3 from django import template
4 from django import template
5 from django.utils.text import re_tag
6
7 from boards.mdx_neboard import LINE_BREAK_HTML
4
8
5
9
6 IMG_ACTION_URL = '[<a href="{}">{}</a>]'
10 IMG_ACTION_URL = '[<a href="{}">{}</a>]'
11 REGEX_NEWLINE = re.compile(LINE_BREAK_HTML)
12 TRUNCATOR = '...'
13 HTML4_SINGLETS =(
14 'br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input'
15 )
7
16
8
17
9 register = template.Library()
18 register = template.Library()
10
19
11 actions = [
20 actions = [
12 {
21 {
13 'name': 'google',
22 'name': 'google',
14 'link': 'http://google.com/searchbyimage?image_url=%s',
23 'link': 'http://google.com/searchbyimage?image_url=%s',
15 },
24 },
16 {
25 {
17 'name': 'iqdb',
26 'name': 'iqdb',
18 'link': 'http://iqdb.org/?url=%s',
27 'link': 'http://iqdb.org/?url=%s',
19 },
28 },
20 ]
29 ]
21
30
22
31
23 @register.simple_tag(name='post_url')
32 @register.simple_tag(name='post_url')
24 def post_url(*args, **kwargs):
33 def post_url(*args, **kwargs):
25 post_id = args[0]
34 post_id = args[0]
26
35
27 post = get_object_or_404('Post', id=post_id)
36 post = get_object_or_404('Post', id=post_id)
28
37
29 return post.get_absolute_url()
38 return post.get_absolute_url()
30
39
31
40
32 @register.simple_tag(name='image_actions')
41 @register.simple_tag(name='image_actions')
33 def image_actions(*args, **kwargs):
42 def image_actions(*args, **kwargs):
34 image_link = args[0]
43 image_link = args[0]
35 if len(args) > 1:
44 if len(args) > 1:
36 image_link = 'http://' + args[1] + image_link # TODO https?
45 image_link = 'http://' + args[1] + image_link # TODO https?
37
46
38 return ', '.join([IMG_ACTION_URL.format(
47 return ', '.join([IMG_ACTION_URL.format(
39 action['link'] % image_link, action['name']) for action in actions])
48 action['link'] % image_link, action['name']) for action in actions])
40
49
41
50
42 @register.inclusion_tag('boards/post.html', name='post_view', takes_context=True)
51 @register.inclusion_tag('boards/post.html', name='post_view', takes_context=True)
43 def post_view(context, post, *args, **kwargs):
52 def post_view(context, post, *args, **kwargs):
44 kwargs['perms'] = context['perms']
53 kwargs['perms'] = context['perms']
45 return post.get_view_params(*args, **kwargs)
54 return post.get_view_params(*args, **kwargs)
46
55
47
56
48 @register.simple_tag(name='page_url')
57 @register.simple_tag(name='page_url')
49 def page_url(paginator, page_number, *args, **kwargs):
58 def page_url(paginator, page_number, *args, **kwargs):
50 if paginator.supports_urls():
59 if paginator.supports_urls():
51 return paginator.get_page_url(page_number)
60 return paginator.get_page_url(page_number)
61
62
63 @register.filter(name='truncatenewlines_html')
64 def truncatenewlines_html(value, arg):
65 current_pos = 0
66 match_count = 0
67
68 # Collect places for truncation
69 while match_count <= arg:
70 m = REGEX_NEWLINE.search(value, current_pos)
71 if m is None:
72 break
73 else:
74 match_count += 1
75 current_pos = m.end()
76
77 # Find and close open tags
78 if match_count > arg:
79 truncate_pos = current_pos
80
81 open_tags = []
82 text = value[:truncate_pos]
83 current_pos = 0
84 while True:
85 tag = re_tag.search(text, current_pos)
86 if tag is None:
87 break
88 else:
89 closing_tag, tagname, self_closing = tag.groups()
90 tagname = tagname.lower()
91 if self_closing or tagname in HTML4_SINGLETS:
92 pass
93 elif closing_tag:
94 # Check for match in open tags list
95 try:
96 i = open_tags.index(tagname)
97 except ValueError:
98 pass
99 else:
100 # SGML: An end tag closes, back to the matching start tag,
101 # all unclosed intervening start tags with omitted end tags
102 open_tags = open_tags[i + 1:]
103 else:
104 # Add it to the start of the open tags list
105 open_tags.insert(0, tagname)
106
107 current_pos = tag.end()
108
109 for tag in open_tags:
110 text += '</%s>'.format(tag)
111 text += TRUNCATOR
112 else:
113 text = value
114
115 return text
116
General Comments 0
You need to be logged in to leave comments. Login now