public
Description: The ultra-lightweight ultra-flexible blogging engine with a fetish for birds and misspellings.
Homepage: http://chyrp.net/
Clone URL: git://github.com/vito/chyrp.git
Click here to lend your support to: chyrp and make a donation at www.pledgie.com !
Added bulk tag managing and bulk post tagging. [#125 state:resolved]
vito (author)
Fri Aug 29 22:14:49 -0700 2008
commit  4e3143b9f0a2f79b46f8610c0b76a55b25c1291f
tree    ae7ef3e7cd5e79e6fa4a6fcb18e4b8ef5837b572
parent  0e91f8164067b11245d1cc918aab3325352f9ea2
...
18
19
20
21
 
22
23
24
...
18
19
20
 
21
22
23
24
0
@@ -18,7 +18,7 @@
0
         </fieldset>
0
       </form>
0
       <br />
0
-      <h2>${ "Last 25 Pages" | translate }</h2>
0
+      <h2>{% if GET.query %}${ "Search Results" | translate }{% else %}${ "Last 25 Pages" | translate }{% endif %}</h2>
0
       <table border="0" cellspacing="0" cellpadding="0" class="wide">
0
         <thead>
0
           <tr class="head">
...
29
30
31
32
 
33
34
35
...
29
30
31
 
32
33
34
35
0
@@ -29,7 +29,7 @@
0
         </fieldset>
0
       </form>
0
       <br />
0
-      <h2>${ "Last 25 Posts" | translate }</h2>
0
+      <h2>{% if GET.query %}${ "Search Results" | translate }{% else %}${ "Last 25 Posts" | translate }{% endif %}</h2>
0
       <table border="0" cellspacing="0" cellpadding="0" class="wide">
0
         <thead>
0
           <tr class="head">
...
208
209
210
 
 
 
 
 
 
211
212
213
...
534
535
536
537
538
 
539
540
541
...
561
562
563
564
 
 
565
566
567
...
953
954
955
 
 
 
956
...
208
209
210
211
212
213
214
215
216
217
218
219
...
540
541
542
 
 
543
544
545
546
...
566
567
568
 
569
570
571
572
573
...
959
960
961
962
963
964
965
0
@@ -208,6 +208,12 @@ a:visited {
0
   font-size: .8em;
0
   color: #bcbcbc;
0
 }
0
+#content h1.sub,
0
+#content h2.sub,
0
+#content h3.sub,
0
+#content h4.sub {
0
+  color: #bcbcbc;
0
+}
0
 /* @end */
0
 
0
 /* @group Extend */
0
@@ -534,8 +540,7 @@ table thead tr th {
0
 }
0
 table thead tr th input {
0
   position: relative;
0
-  top: -2px;
0
-  right: -2px;
0
+  top: -.15em;
0
 }
0
 table thead tr th.header {
0
   cursor: pointer;
0
@@ -561,7 +566,8 @@ table tbody tr td.main {
0
   background: #f9f9f9;
0
   font-weight: bold;
0
 }
0
-table tbody tr td.center {
0
+table tbody tr td.center,
0
+table tbody tr th.center {
0
   text-align: center;
0
   vertical-align: middle;
0
 }
0
@@ -953,4 +959,7 @@ br#after_options {
0
 img.smiley {
0
   margin: 0 0 -.3em;
0
 }
0
+.inline {
0
+  display: inline;
0
+}
0
 /* @end */
...
27
28
29
 
 
 
30
31
32
...
68
69
70
71
72
73
74
75
 
 
 
76
77
78
 
 
 
 
79
80
81
...
84
85
86
87
 
88
89
90
...
92
93
94
 
 
 
 
 
95
96
97
...
27
28
29
30
31
32
33
34
35
...
71
72
73
 
74
75
76
 
77
78
79
80
81
82
83
84
85
86
87
88
89
...
92
93
94
 
95
96
97
98
...
100
101
102
103
104
105
106
107
108
109
110
0
@@ -27,6 +27,9 @@ $(function(){
0
     return false
0
   })
0
 
0
+  // Auto-expand input fields
0
+  $(".expand").expand()
0
+
0
   // Checkbox toggling.
0
   togglers()
0
 
0
@@ -68,14 +71,19 @@ function togglers() {
0
 
0
   $(document.createElement("label")).attr("for", "toggle").text("<?php echo __("Toggle All"); ?>").appendTo("#toggler")
0
   $(document.createElement("input")).attr({
0
-    "class": "checkbox",
0
     type: "checkbox",
0
     name: "toggle",
0
     id: "toggle"
0
-  }).appendTo("#toggler, .toggler").click(function(){
0
+  }).prependTo("#toggler, .toggler")
0
+
0
+  $("#toggle").click(function(){
0
     $("form#new_group, form#group_edit, table").find(":checkbox").not("#toggle").each(function(){
0
       this.checked = document.getElementById("toggle").checked
0
     })
0
+
0
+    $(this).parent().parent().find(":checkbox").not("#toggle").each(function(){
0
+      this.checked = document.getElementById("toggle").checked
0
+    })
0
   })
0
 
0
   // Some checkboxes are already checked when the page is loaded
0
@@ -84,7 +92,7 @@ function togglers() {
0
     all_checked = this.checked
0
   })
0
 
0
-  $(":checkbox").click(function(){
0
+  $(":checkbox:not(#toggle)").click(function(){
0
     var action_all_checked = true
0
 
0
     $("form#new_group, form#group_edit, table").find(":checkbox").not("#toggle").each(function(){
0
@@ -92,6 +100,11 @@ function togglers() {
0
       action_all_checked = this.checked
0
     })
0
 
0
+    $("#toggle").parent().parent().find(":checkbox").not("#toggle").each(function(){
0
+      if (!action_all_checked) return
0
+      action_all_checked = this.checked
0
+    })
0
+
0
     document.getElementById("toggle").checked = action_all_checked
0
   })
0
 
...
5
6
7
8
 
9
10
11
...
5
6
7
 
8
9
10
11
0
@@ -5,7 +5,7 @@
0
   switch($_POST['action']) {
0
     case "edit_post":
0
       if (!isset($_POST['id']))
0
-        error(__("Unspecified ID"), __("Please specify an ID of the post you would like to edit."));
0
+        error(__("No ID Specified"), __("Please specify an ID of the post you would like to edit."));
0
 
0
       $post = new Post($_POST['id'], array("filter" => false, "drafts" => true));
0
 
...
228
229
230
231
 
232
233
234
...
228
229
230
 
231
232
233
234
0
@@ -228,7 +228,7 @@ function twig_urlencode_filter($url, $raw=false)
0
   return urlencode($url);
0
 }
0
 
0
-function twig_join_filter($value, $glue='')
0
+function twig_join_filter($value, $glue='')
0
 {
0
   return implode($glue, $value);
0
 }
...
48
49
50
 
 
 
51
52
53
...
48
49
50
51
52
53
54
55
56
0
@@ -48,6 +48,9 @@
0
 
0
       global $posts;
0
 
0
+      if (empty($_GET['query']))
0
+        return Flash::warning(__("Please enter a search term."));
0
+
0
       list($where, $params) = keywords(urldecode($_GET['query']), "xml LIKE :query");
0
 
0
       $posts = new Paginator(Post::find(array("placeholders" => true,
...
238
239
240
241
 
242
243
244
...
238
239
240
 
241
242
243
244
0
@@ -238,7 +238,7 @@ msgid "Title"
0
 msgstr ""
0
 
0
 #: includes/ajax.php:8
0
-msgid "Unspecified ID"
0
+msgid "No ID Specified"
0
 msgstr ""
0
 
0
 #: admin/layout/pages/import.twig:118
...
149
150
151
 
152
153
154
...
310
311
312
 
313
314
315
...
149
150
151
152
153
154
155
...
311
312
313
314
315
316
317
0
@@ -149,6 +149,7 @@
0
       if (!Visitor::current()->group()->can("edit_comment", "delete_comment", true))
0
         show_403(__("Access Denied"), __("You do not have sufficient privileges to manage any comments.", "comments"));
0
 
0
+      fallback($_GET['query'], "");
0
       list($where, $params) = keywords(urldecode($_GET['query']), "body LIKE :query");
0
 
0
       $where[] = "status = 'spam'";
0
@@ -310,6 +311,7 @@
0
       if (!Comment::any_editable() and !Comment::any_deletable())
0
         show_403(__("Access Denied"), __("You do not have sufficient privileges to manage any comments.", "comments"));
0
 
0
+      fallback($_GET['query'], "");
0
       list($where, $params) = keywords(urldecode($_GET['query']), "body LIKE :query");
0
 
0
       $where[] = "status != 'spam'";
...
38
39
40
41
 
42
43
44
...
38
39
40
 
41
42
43
44
0
@@ -38,7 +38,7 @@
0
           </button>
0
         </div>
0
 {% endif %}
0
-        <h2>${ "Last 25 Comments" | translate("comments") }</h2>
0
+        <h2>{% if GET.query %}${ "Search Results" | translate }{% else %}${ "Last 25 Comments" | translate("comments") }{% endif %}</h2>
0
         <table border="0" cellspacing="0" cellpadding="0" class="wide">
0
           <thead>
0
             <tr class="head">
...
34
35
36
37
 
38
39
40
...
34
35
36
 
37
38
39
40
0
@@ -34,7 +34,7 @@
0
             <img src="images/icons/delete.png" alt="delete" /> ${ "delete" | translate("comments") }
0
           </button>
0
         </div>
0
-        <h2>${ "Last 25 Spam" | translate("comments") }</h2>
0
+        <h2>{% if GET.query %}${ "Search Results" | translate }{% else %}${ "Last 25 Spam" | translate("comments") }{% endif %}</h2>
0
         <table border="0" cellspacing="0" cellpadding="0" class="wide">
0
           <thead>
0
             <tr class="head">
...
23
24
25
26
 
 
27
28
29
 
 
30
31
32
...
34
35
36
 
37
38
39
...
42
43
44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
46
...
23
24
25
 
26
27
28
29
 
30
31
32
33
34
...
36
37
38
39
40
41
42
...
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
0
@@ -23,10 +23,12 @@
0
 .tag_cloud {
0
   text-align: center;
0
 }
0
-.tag_cloud span {
0
+.tag_cloud span,
0
+.post_tags a.tag {
0
   display: inline-block;
0
 }
0
-.tag_cloud span a.tag {
0
+.tag_cloud span a.tag,
0
+.post_tags a.tag {
0
   display: block;
0
   line-height: 2.5em;
0
   padding: 0 .75em;
0
@@ -34,6 +36,7 @@
0
   text-decoration: none;
0
   font-weight: bold;
0
   color: #777;
0
+  text-align: center;
0
 }
0
 .tag_cloud span .controls {
0
   opacity: 0;
0
@@ -42,4 +45,41 @@
0
   background: #f9f9f9;
0
   -webkit-border-bottom-right-radius: .5em;
0
   -webkit-border-bottom-left-radius: .5em;
0
+}
0
+
0
+.post_tags {
0
+  list-style: none;
0
+}
0
+.post_tags li {
0
+  display: block;
0
+  margin-bottom: .5em;
0
+  padding: .75em;
0
+}
0
+.post_tags input,
0
+.post_tags h3 {
0
+  margin: 0 .5em 0 .25em;
0
+}
0
+.post_tags li.odd {
0
+  background: #fafafa;
0
+}
0
+.post_tags li a.tag,
0
+.post_tags li a.edit_tag {
0
+  margin: -.85em 0;
0
+}
0
+.post_tags li a.tag {
0
+  display: inline-block;
0
+  padding: 0 .75em;
0
+  background: #e5e5e5;
0
+  -webkit-border-radius: .5em;
0
+}
0
+.post_tags li a.edit_tag {
0
+  display: inline-block;
0
+  position: relative;
0
+  bottom: -.2em;
0
+  padding: .5em .75em .4em;
0
+  background: #f0f0f0;
0
+  -webkit-border-radius: .5em;
0
+}
0
+.post_tags li a.edit_tag:hover {
0
+  background: #f5f5f5;
0
 }
0
\ No newline at end of file
...
3
4
5
6
 
 
7
8
9
10
11
12
13
 
14
15
16
...
18
19
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
22
...
3
4
5
 
6
7
8
9
10
11
12
13
 
14
15
16
17
...
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
0
@@ -3,14 +3,15 @@
0
 {% block title %}${ "Manage Tags" | translate("tags") }{% endblock %}
0
 
0
 {% block content %}
0
-      <h1>${ "Manage Tags" | translate("tags") } <span class="sub right">${ "(hover for controls)" | translate }</span></h1>
0
+      <h1>${ "Manage Tags" | translate("tags") }</h1>
0
+      <h2>${ "All Tags" | translate("tags") } <span class="sub right">${ "(hover for controls)" | translate }</span></h2>
0
       <div class="tag_cloud">
0
         {% for tag in tag_cloud %}
0
         <span class="tag_wrap">
0
           <a class="tag" href="$tag.url" style="font-size: $tag.size%" title="$tag.title">$tag.name</a>
0
           <div class="controls">
0
             <a class="edit_tag" href="{% admin "rename_tag&name="~ tag.clean %}"><img src="images/icons/edit.png" alt="edit" /></a>
0
-            <a class="delete_tag" href="{% admin "delete_tag&name="~ tag.clean %}"><img src="images/icons/delete.png" alt="edit" /></a>
0
+            <a class="delete_tag" href="{% admin "delete_tag&name="~ (tag.name | urlencode) ~"&clean="~ tag.clean %}"><img src="images/icons/delete.png" alt="edit" /></a>
0
           </div>
0
         </span>
0
         {% else %}
0
@@ -18,4 +19,55 @@
0
         <br />
0
         {% endfor %}
0
       </div>
0
+      <hr />
0
+      <br />
0
+      <h2>${ "Post Tags" | translate("tags") }</h2>
0
+      <br />
0
+      <div class="left pad margin-right">
0
+        <form class="detail" action="index.php" method="get" accept-charset="utf-8">
0
+          <fieldset>
0
+            <input type="hidden" name="action" value="manage_tags" />
0
+            <h3>
0
+              ${ "Search&hellip;" | translate }
0
+              <a href="{% admin "help&id=filtering_results" %}" class="help emblem"><img src="images/icons/help.png" alt="help" /></a>
0
+            </h3>
0
+            <input class="text" type="text" name="query" value="${ GET.query | escape }" id="query" /> <button type="submit" class="inline">${ "Search &rarr;" | translate }</button>
0
+          </fieldset>
0
+        </form>
0
+      </div>
0
+      <form class="detail" action="{% admin "bulk_tag" %}" method="post" accept-charset="utf-8">
0
+        <fieldset>
0
+          <div class="left pad">
0
+            <h3>${ "Tag Selected:" | translate("tags") }</h3>
0
+            <input type="text" name="name" value="" id="name" />
0
+            <button type="submit" class="inline">${ "Tag &rarr;" | translate("tags") }</button>
0
+            <input type="hidden" name="hash" value="$site.secure_hashkey" id="hash" />
0
+          </div>
0
+          <div class="clear"></div>
0
+          <br />
0
+          <h2>{% if GET.query %}${ "Search Results" | translate }{% else %}${ "Last 25 Posts" | translate }{% endif %}</h2>
0
+          <ul class="post_tags">
0
+            <li class="odd js_enabled toggler">
0
+              <h3 class="inline sub">${ "Toggle All" | translate }</h3>
0
+            </li>
0
+          {% for post in posts.paginated %}
0
+            <li class="{% if loop.index | odd %}even{% else %}odd{% endif %}">
0
+              <input type="checkbox" name="post[$loop.index0]" value="$post.id" id="post_checkbox_$post.id" />
0
+              <h3 class="inline"><a href="$post.url">${ post.title | truncate | fallback((post.feather | capitalize) ~ " #" ~ post.id) }</a></h3>
0
+              {% for tag in post.tags.info %}
0
+              <a class="tag" href="$tag.url">$tag.name</a>
0
+              {% endfor %}
0
+              <a class="edit_tag" href="{% admin "edit_tags&id="~ post.id %}"><img src="images/icons/edit.png" alt="edit" /></a>
0
+            </li>
0
+          {% else %}
0
+            <li>
0
+              <span class="sub">${ "(none)" | translate }</span>
0
+            </li>
0
+          {% endfor %}
0
+          </ul>
0
+        </fieldset>
0
+      </form>
0
+      <br />
0
+      $posts.next_link
0
+      $posts.prev_link
0
 {% endblock %}
0
\ No newline at end of file
...
149
150
151
152
 
153
154
155
156
157
158
 
159
160
161
...
200
201
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
204
205
...
229
230
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
 
 
233
234
235
...
256
257
258
259
260
261
262
263
264
265
 
 
 
 
 
 
 
 
 
 
 
266
267
268
269
270
271
272
 
 
 
273
274
275
276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
278
279
...
430
431
432
433
434
435
436
437
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
439
440
...
149
150
151
 
152
153
154
155
156
157
 
158
159
160
161
...
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
...
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
...
299
300
301
 
 
302
303
304
305
 
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
 
 
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
...
500
501
502
 
 
 
 
 
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
0
@@ -149,13 +149,13 @@
0
         return $navs;
0
 
0
       $navs["manage_tags"] = array("title" => __("Tags", "tags"),
0
-                                   "selected" => array("bulk_tags", "rename_tag", "delete_tag"));
0
+                                   "selected" => array("rename_tag", "delete_tag", "edit_tags"));
0
 
0
       return $navs;
0
     }
0
 
0
     static function manage_nav_pages($pages) {
0
-      array_push($pages, "manage_tags", "bulk_tags", "rename_tag", "delete_tag");
0
+      array_push($pages, "manage_tags", "rename_tag", "delete_tag", "edit_tags");
0
       return $pages;
0
     }
0
 
0
@@ -200,6 +200,23 @@
0
                            "url" => url("tag/".$tag2clean[$tag]."/"));
0
 
0
       $admin->context["tag_cloud"] = $context;
0
+
0
+      if (!Post::any_editable() and !Post::any_deletable())
0
+        return;
0
+
0
+      fallback($_GET['query'], "");
0
+      list($where, $params) = keywords(urldecode($_GET['query']), "xml LIKE :query");
0
+
0
+      $visitor = Visitor::current();
0
+      if (!$visitor->group()->can("view_draft", "edit_draft", "edit_post", "delete_draft", "delete_post")) {
0
+        $where[] = "user_id = :visitor_id";
0
+        $params[':visitor_id'] = $visitor->id;
0
+      }
0
+
0
+      $admin->context["posts"] = new Paginator(Post::find(array("placeholders" => true,
0
+                                                               "drafts" => true,
0
+                                                               "where" => $where,
0
+                                                               "params" => $params)), 25);
0
     }
0
 
0
     public function admin_rename_tag($admin) {
0
@@ -229,7 +246,33 @@
0
           return $admin->context["tag"] = array("name" => $tag, "clean" => $tag2clean[$tag]);
0
     }
0
 
0
+    public function admin_edit_tags($admin) {
0
+      $sql = SQL::current();
0
+
0
+      if (!isset($_GET['id']))
0
+        error(__("No ID Specified"), __("Please specify the ID of the post whose tags you would like to edit.", "tags"));
0
+
0
+      $admin->context["post"] = new Post($_GET['id']);
0
+    }
0
+
0
+    public function admin_update_tags($admin) {
0
+      $sql = SQL::current();
0
+
0
+      if (!isset($_POST['hash']) or $_POST['hash'] != Config::current()->secure_hashkey)
0
+        show_403(__("Access Denied"), __("Invalid security key."));
0
+
0
+      if (!isset($_POST['id']))
0
+        error(__("No ID Specified"), __("Please specify the ID of the post whose tags you would like to edit.", "tags"));
0
+
0
+      $this->update_post(new Post($_POST['id']));
0
+
0
+      Flash::notice(__("Tags updated.", "tags"), "/admin/?action=manage_tags");
0
+    }
0
+
0
     public function admin_update_tag($admin) {
0
+      if (!isset($_POST['hash']) or $_POST['hash'] != Config::current()->secure_hashkey)
0
+        show_403(__("Access Denied"), __("Invalid security key."));
0
+
0
       $sql = SQL::current();
0
 
0
       $tags = array();
0
@@ -256,24 +299,51 @@
0
     public function admin_delete_tag($admin) {
0
       $sql = SQL::current();
0
 
0
-      $tags = array();
0
-      $clean = array();
0
       foreach($sql->select("tags",
0
                          "*",
0
                          "clean LIKE :tag",
0
                          null,
0
-                         array(":tag" => "%{{".$_GET['name']."}}%"))->fetchAll() as $tag)
0
+                         array(":tag" => "%{{".$_GET['name']."}}%"))->fetchAll() as $tag)  {
0
+        $names = array();
0
+        foreach (explode("}},{{", substr(substr($tag["tags"], 0, -2), 2)) as $name)
0
+          if ($name != $_GET['name'])
0
+            $names[] = "{{".$name."}}";
0
+
0
+        $cleans = array();
0
+        foreach (explode("}},{{", substr(substr($tag["clean"], 0, -2), 2)) as $clean)
0
+          if ($clean != $_GET['clean'])
0
+            $cleans[] = "{{".$clean."}}";
0
+
0
         $sql->update("tags",
0
                      "id = :id",
0
                      array("tags" => ":tags",
0
                            "clean" => ":clean"),
0
                      array(":id" => $tag["id"],
0
-                           ":tags" => preg_replace("/\{\{{$_GET['name']}\}\},?/", "", $tag["tags"]),
0
-                           ":clean" => preg_replace("/\{\{{$_GET['name']}\}\},?/", "", $tag["clean"])));
0
+                           ":tags" => join(",", $names),
0
+                           ":clean" => join(",", $cleans)));
0
+      }
0
 
0
       Flash::notice(__("Tag deleted.", "tags"), "/admin/?action=manage_tags");
0
     }
0
 
0
+    public function admin_bulk_tag($admin) {
0
+      if (!isset($_POST['hash']) or $_POST['hash'] != Config::current()->secure_hashkey)
0
+        show_403(__("Access Denied"), __("Invalid security key."));
0
+
0
+      if (empty($_POST['name']) or empty($_POST['post']))
0
+        redirect("/admin/?action=manage_tags");
0
+
0
+      $sql = SQL::current();
0
+
0
+      foreach ($_POST['post'] as $post_id) {
0
+        $post = new Post($post_id);
0
+        $_POST['tags'] = join(", ", $post->tags["unlinked"]).", ".$_POST['name'];
0
+        $this->update_post($post);
0
+      }
0
+
0
+      Flash::notice(__("Posts tagged.", "tags"), "/admin/?action=manage_tags");
0
+    }
0
+
0
     public function check_route_tag() {
0
       global $posts;
0
 
0
@@ -430,11 +500,22 @@
0
     }
0
 
0
     public function filter_post($post) {
0
-      if (!isset($post->unclean_tags))
0
-        $post->tags = array("unlinked" => array(), "linked" => array());
0
-      else
0
-        $post->tags = array("unlinked" => self::unlinked_tags($post->unclean_tags),
0
-                            "linked"   => self::linked_tags($post->unclean_tags, $post->clean_tags));
0
+      if (empty($post->unclean_tags)) {
0
+        $post->tags = array("info" => array(), "unlinked" => array(), "linked" => array());
0
+        return;
0
+      }
0
+
0
+      list($tags, $clean, $tag2clean) = $this->parseTags(array($post->unclean_tags), array($post->clean_tags));
0
+
0
+      $post->tags = array();
0
+
0
+      foreach ($tags as $tag => $count)
0
+        $post->tags["info"][] = array("name" => $tag,
0
+                                        "clean" => $tag2clean[$tag],
0
+                                        "url" => url("tag/".$tag2clean[$tag]."/"));
0
+
0
+      $post->tags["unlinked"] = self::unlinked_tags($post->unclean_tags);
0
+      $post->tags["linked"]   = self::linked_tags($post->unclean_tags, $post->clean_tags);
0
     }
0
 
0
     public function sort_tags_name_asc($a, $b) {
...
27
28
29
30
 
31
32
33
...
27
28
29
 
30
31
32
33
0
@@ -27,7 +27,7 @@
0
               {% endif %}
0
               {% if post.tags.linked | length > 0 %}
0
               |
0
-              ${ "Tags" | translate }: ${ post.tags.linked | join }
0
+              ${ "Tags" | translate }: ${ post.tags.linked | join(", ") }
0
               {% endif %}
0
             </span>
0
 {% if visitor.group.can("edit_post", "delete_post") %}

Comments