radiant-taggable-extension 1.2.5 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,655 @@
1
+ module Radius
2
+ module TaggableTags
3
+ include Radiant::Taggable
4
+
5
+ class TagError < StandardError; end
6
+
7
+ ################# general purpose lister utilities and dryers-out
8
+ # can be contained or nested within any list-defining tag
9
+ # eg.<r:structural_tags:each_tag>...
10
+ # or just.<r:tags:each_tag>... (aka r:tags:each)
11
+
12
+ desc %{
13
+ Contents are rendered only if tags are available to display.
14
+
15
+ <pre><code><r:if_tags>...</r:if_tags></code></pre>
16
+
17
+ Can also be nested inside a set-definition container tag:
18
+
19
+ <pre><code><r:structural_tags:if_tags>...</r:structural_tags:if_tags></code></pre>
20
+ }
21
+ tag 'if_tags' do |tag|
22
+ tag.locals.tags ||= _get_tags(tag)
23
+ tag.expand if tag.locals.tags && tag.locals.tags.any?
24
+ end
25
+
26
+ desc %{
27
+ Contents are rendered only if no tags are available.
28
+ Can also be nested inside a set-definition container tag.
29
+ }
30
+ tag 'unless_tags' do |tag|
31
+ tag.locals.tags ||= _get_tags(tag)
32
+ tag.expand unless tag.locals.tags && tag.locals.tags.any?
33
+ end
34
+
35
+ desc %{
36
+ Loops through the current list of tags.
37
+ Only works when nested within a set-defining tag.
38
+ }
39
+ tag "each_tag" do |tag|
40
+ result = []
41
+ tag.locals.tags.each do |item|
42
+ tag.locals.tag = item
43
+ result << tag.expand
44
+ end
45
+ result
46
+ end
47
+
48
+ desc %{
49
+ Displays a UL of the current list of tags.
50
+ Only works when nested within a set-defining tag.
51
+ }
52
+ tag "tag_list" do |tag|
53
+ if tag.locals.tags && tag.locals.tags.any?
54
+ options = tag.attr.dup
55
+ show_checkboxes = (options.delete('checklist') == 'true')
56
+ listclass = options.delete('listclass') || 'taglist'
57
+ result = %{<ul class="#{listclass}">}
58
+ tag.locals.tags.each do |t|
59
+ tag.locals.tag = t
60
+ result << %{<li>#{tag.render('tag_link', options)}</li>}
61
+ end
62
+ result << "</ul>"
63
+ result
64
+ else
65
+ "No tags"
66
+ end
67
+ end
68
+
69
+ desc %{
70
+ Builds a cloud to display the current list of tags.
71
+ Only works when nested within a set-defining tag.
72
+ For simple page tag-clouding use r:tags:cloud.
73
+ }
74
+ tag "tag_cloud" do |tag|
75
+ if tag.locals.tags && tag.locals.tags.length > 1
76
+ options = tag.attr.dup
77
+ tag.locals.tags = Tag.for_cloud(tag.locals.tags).sort
78
+ result = []
79
+ result << %{<div class="cloud">}
80
+ tag.locals.tags.sort.each do |t|
81
+ tag.locals.tag = t
82
+ result << tag.render("tag_link", options.merge('style' => "font-size: #{t.cloud_size.to_f * 2.5}em;"))
83
+ end
84
+ result << "</div>"
85
+ result.join(" ")
86
+ else
87
+ "No tags"
88
+ end
89
+ end
90
+
91
+ desc %{
92
+ Summarises in a sentence the current list of tags.
93
+ Only works when nested within a set-defining tag.
94
+ }
95
+ tag "tag_summary" do |tag|
96
+ if tag.locals.tags && tag.locals.tags.any?
97
+ options = tag.attr.dup
98
+ tag.locals.tags.map { |t|
99
+ tag.locals.tag = t
100
+ tag.render('tag:title', options)
101
+ }.to_sentence
102
+ else
103
+ "no tags"
104
+ end
105
+ end
106
+
107
+
108
+ ################# set-defining tags are meant to contain clouds and summaries and lists and so on
109
+ # there are many more in the library
110
+
111
+
112
+ tag 'structural_tags' do |tag|
113
+ tag.locals.tags = tag.locals.page.attached_tags.structural.visible
114
+ tag.expand
115
+ end
116
+
117
+ tag 'all_structural_tags' do |tag|
118
+ tag.locals.tags = Tag.structural.visible
119
+ tag.expand
120
+ end
121
+
122
+ tag 'descriptive_tags' do |tag|
123
+ tag.locals.tags = tag.locals.page.attached_tags.descriptive.visible
124
+ tag.expand
125
+ end
126
+
127
+ tag 'all_descriptive_tags' do |tag|
128
+ tag.locals.tags = Tag.descriptive.visible
129
+ tag.expand
130
+ end
131
+
132
+ tag 'hidden_tags' do |tag|
133
+ tag.locals.tags = tag.locals.page.attached_tags.hidden
134
+ tag.expand
135
+ end
136
+
137
+ tag 'all_hidden_tags' do |tag|
138
+ tag.locals.tags = Tag.hidden.visible
139
+ tag.expand
140
+ end
141
+
142
+ ################# page-tag shortcuts call the above listers and clouders after first defaulting to
143
+ # current page tags (or in the case of the clouds and lists, page and descendants)
144
+
145
+ tag 'tags' do |tag|
146
+ tag.expand
147
+ end
148
+
149
+ tag 'tags:summary' do |tag|
150
+ tag.locals.tags ||= _get_tags(tag)
151
+ tag.render('tag_summary', tag.attr.dup)
152
+ end
153
+
154
+ tag 'tags:each' do |tag|
155
+ tag.locals.tags ||= _get_tags(tag)
156
+ tag.render('each_tag', tag.attr.dup, &tag.block)
157
+ end
158
+
159
+ desc %{
160
+ Returns a tag-cloud showing all the tags attached to this page and its descendants,
161
+ with cloud band css classes determined by popularity *within the group*. This is intended as a way to
162
+ show what subjects are relevant here, as in the original delicio.us tag clouds. You can achieve similar
163
+ results with tags like r:all_tags:cloud, but with important differences:
164
+
165
+ * here prominence depends on popularity within the retrieved set of tags (not overall)
166
+ * here we climb down the page tree to build the set of tags: useful for eg. a section front page.
167
+
168
+ *Usage:*
169
+ <pre><code><r:tag_cloud /></code></pre>
170
+
171
+ You can supply a url parameter to work from a page other than the present one.
172
+
173
+ <pre><code><r:tag_cloud url="/elsewhere" /></code></pre>
174
+
175
+ So if you want to show all the tags attached to any page (but ignore their attachment to anything else):
176
+
177
+ <pre><code><r:tag_cloud url="/" /></code></pre>
178
+
179
+ As usual you can limit the size of the cloud (the most popular will be shown) and set the destination of tag links:
180
+
181
+ <pre><code><r:tags:cloud limit="200" linkto="/archive" /></code></pre>
182
+ }
183
+ tag 'tags:cloud' do |tag|
184
+ tag.locals.tags ||= _get_tags(tag)
185
+ options = tag.attr.dup
186
+ limit = options.delete('limit')
187
+ if url = options.delete('url')
188
+ found = Page.find_by_url(absolute_path_for(tag.locals.page.url, url))
189
+ raise TagError, "no page at url #{url}" unless page_found?(found)
190
+ tag.locals.page = found
191
+ end
192
+ raise TagError, "no page for tag_cloud" unless tag.locals.page
193
+ tag.locals.tags = tag.locals.page.tags_for_cloud(limit).sort # page.tags_for_cloud does a lot of inheritance work
194
+ tag.render('tag_cloud', options)
195
+ end
196
+
197
+ desc %{
198
+ Returns a list of tags showing all the tags attached to this page and its descendants. It's essentially the same
199
+ as the tag cloud without the band formatting.
200
+
201
+ *Usage:*
202
+ <pre><code><r:tag_list /></code></pre>
203
+
204
+ As usual you can limit the size of the list (the most popular will be shown) and set the destination of tag links:
205
+
206
+ <pre><code><r:tag_list limit="200" linkto="/archive" /></code></pre>
207
+ }
208
+ tag 'tags:list' do |tag|
209
+ tag.locals.tags ||= _get_tags(tag)
210
+ options = tag.attr.dup
211
+ limit = options.delete('limit')
212
+ if url = options.delete('url')
213
+ found = Page.find_by_url(absolute_path_for(tag.locals.page.url, url))
214
+ raise TagError, "no page at url #{url}" unless page_found?(found)
215
+ tag.locals.page = found
216
+ end
217
+ raise TagError, "no page for tag_list" unless tag.locals.page
218
+ tag.locals.tags = tag.locals.page.tags_for_cloud(limit).sort
219
+ tag.render('tags:list', options)
220
+ end
221
+
222
+
223
+
224
+
225
+
226
+
227
+ ################# tagged pages. Other extensions define similar tags for eg tagged assets.
228
+
229
+ tag 'page_list' do |tag|
230
+ raise TagError, "no pages for page_list" unless tag.locals.pages
231
+ result = []
232
+ options = children_find_options(tag)
233
+ paging = pagination_find_options(tag)
234
+ displayed_children = paging ? tag.locals.pages.paginate(options.merge(paging)) : tag.locals.pages.all(options)
235
+ displayed_children.each do |item|
236
+ tag.locals.page = item
237
+ result << tag.expand
238
+ end
239
+ result
240
+ end
241
+
242
+ desc %{
243
+ Lists all the pages associated with a set of tags, in descending order of relatedness.
244
+
245
+ *Usage:*
246
+ <pre><code><r:tagged_pages:each>...</r:tags:pages:each></code></pre>
247
+ }
248
+ tag 'tagged_pages' do |tag|
249
+ tag.locals.pages = Page.from_tags(tag.locals.tags)
250
+ tag.expand
251
+ end
252
+
253
+ tag 'tagged_pages:each' do |tag|
254
+ tag.render('page_list', tag.attr.dup, &tag.block)
255
+ end
256
+
257
+ desc %{
258
+ Renders the contained elements only if there are any pages associated with the current set of tags.
259
+
260
+ <pre><code><r:if_tagged_pages>...</r:if_tagged_pages></code></pre>
261
+
262
+ Can be nested in any set-defining tag:
263
+
264
+ <pre><code><r:requested_tags:if_tagged_pages>...</r:requested_tags:if_tagged_pages></code></pre>
265
+ }
266
+ tag "if_tagged_pages" do |tag|
267
+ tag.locals.pages = Page.from_tags(tag.locals.tags)
268
+ tag.expand if tag.locals.pages.to_a.any?
269
+ end
270
+
271
+ desc %{
272
+ Renders the contained elements only if there are no pages associated with the current set of tags.
273
+
274
+ *Usage:*
275
+ <pre><code><r:unless_tagged_pages>...</r:unless_tagged_pages></code></pre>
276
+ }
277
+ tag "tags:unless_pages" do |tag|
278
+ tag.locals.pages = Page.from_tags(tag.locals.tags)
279
+ tag.expand unless tag.locals.pages.to_a.any?
280
+ end
281
+
282
+ # just a shortcut, but a useful one
283
+
284
+ desc %{
285
+ Lists all the pages similar to this page (based on its tagging), in descending order of relatedness.
286
+
287
+ *Usage:*
288
+ <pre><code><r:related_pages:each>...</r:related_pages:each></code></pre>
289
+ }
290
+ tag 'related_pages' do |tag|
291
+ tag.locals.pages = tag.locals.page.related_pages
292
+ tag.expand
293
+ end
294
+ tag 'related_pages:each' do |tag|
295
+ tag.render('page_list', tag.attr.dup, &tag.block)
296
+ end
297
+
298
+ desc %{
299
+ Shows a link to the target page with a (non-linked) breadcrumb trail to give it context.
300
+ This is the opposite of r:breadcrumbs, which shows a linked trail but doesn't link the current page.
301
+ Link and breadcrumb attributes should work in the usual way, and by default we omit the home page
302
+ from the list since it adds no information. pass omit_root='false' to show the whole chain.
303
+
304
+ *Usage:*
305
+ <pre><code><r:tag:pages:each>
306
+ <r:crumbed_link [omit_root="false"] [separator=" &rarr; "] />
307
+ <r:crumbed_link>Link text</r:crumbed_link>
308
+ etc
309
+ </r:tag:pages:each></code></pre>
310
+ }
311
+ tag 'crumbed_link' do |tag|
312
+ page = tag.locals.page
313
+ ancestors = page.ancestors
314
+ ancestors.pop unless tag.attr['omit_root'] == 'false'
315
+ breadcrumbs = [tag.render('link')]
316
+ ancestors.each do |ancestor|
317
+ tag.locals.page = ancestor
318
+ breadcrumbs.unshift tag.render('breadcrumb')
319
+ end
320
+ separator = tag.attr['separator'] || ' &gt; '
321
+ breadcrumbs.join(separator)
322
+ end
323
+
324
+ tag 'tags:pages' do |tag|
325
+ tag.render('tagged_pages', tag.attr.dup, &tag.block)
326
+ end
327
+
328
+ tag "tags:if_pages" do |tag|
329
+ tag.render('if_tagged_pages', tag.attr.dup, &tag.block)
330
+ end
331
+
332
+ tag "tags:unless_pages" do |tag|
333
+ tag.render('unless_tagged_pages', tag.attr.dup, &tag.block)
334
+ end
335
+
336
+
337
+
338
+ ################# single tag expansion for simple lists of tagged items or for customised display of each item in a list or cloud context
339
+
340
+ desc %{
341
+ This is the namespace for referencing a single tag. It's not usually called directly,
342
+ but you can supply a 'title' or 'id' attribute.
343
+
344
+ *Usage:*
345
+ <pre><code><r:tag [title="tag_title"]>...</r:tag></code></pre>
346
+ }
347
+ tag 'tag' do |tag|
348
+ tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
349
+ tag.expand
350
+ end
351
+
352
+ desc %{
353
+ Contents are rendered if a tag is currently defined. Useful on a LibraryPage page where you may or
354
+ may not have received a tag parameter.
355
+
356
+ *Usage:*
357
+ <pre><code><r:if_tag>...</r:if_tag></code></pre>
358
+ }
359
+ tag 'if_tag' do |tag|
360
+ tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
361
+ tag.expand if tag.locals.tag
362
+ end
363
+
364
+ desc %{
365
+ Contents are rendered if no tag is currently defined. Useful on a LibraryPage page where you may or
366
+ may not have a tag parameter.
367
+
368
+ *Usage:*
369
+ <pre><code><r:unless_tag>...</r:unless_tag></code></pre>
370
+ }
371
+ tag 'unless_tag' do |tag|
372
+ tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
373
+ tag.expand unless tag.locals.tag
374
+ end
375
+
376
+ desc %{
377
+ Shows name of current tag.
378
+
379
+ *Usage:*
380
+ <pre><code><r:tag:name /></code></pre>
381
+ }
382
+ tag 'tag:name' do |tag|
383
+ raise TagError, "tag must be defined for tag:name tag" unless tag.locals.tag
384
+ tag.locals.tag.title
385
+ end
386
+
387
+ desc %{
388
+ Sets context to the page association of the current tag
389
+ (that is, the page towards which this tag is a pointer, if any)
390
+
391
+ If there is no page, nothing is displayed.
392
+
393
+ <pre><code><r:tag:page><r:link /></r:tag:page></code></pre>
394
+ }
395
+ tag 'tag:page' do |tag|
396
+ raise TagError, "tag must be defined for tag:page tag" unless tag.locals.tag
397
+ tag.expand if tag.locals.page = tag.locals.tag.page
398
+ end
399
+
400
+ desc %{
401
+ Makes a link to the current tag. If the current page is a library page, we amend the
402
+ list of requested tags. Otherwise, the 'linkto' parameter can be the address of a
403
+ LibraryPage, or you can specify a global tags page with a 'library.path' config entry.
404
+
405
+ If no destination is specified we return a relative link to the escaped name of the tag.
406
+
407
+ *Usage:*
408
+ <pre><code><r:tag_link linkto='/library' /></code></pre>
409
+ }
410
+ tag 'tag_link' do |tag|
411
+ raise TagError, "tag must be defined for tag_link tag" unless tag.locals.tag
412
+ options = tag.attr.dup
413
+ anchor = options['anchor'] ? "##{options.delete('anchor')}" : ''
414
+ attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
415
+ attributes = " #{attributes}" unless attributes.empty?
416
+ text = tag.double? ? tag.expand : tag.render('tag:name')
417
+ if tag.locals.page.is_a? LibraryPage
418
+ tagset = tag.locals.page.requested_tags + [tag.locals.tag]
419
+ destination = tag.locals.page.url(tagset)
420
+ elsif page_url = (options.delete('linkto') || Radiant::Config['library.path'])
421
+ destination = clean_url(page_url + '/' + tag.locals.tag.clean_title)
422
+ else
423
+ # note that this only works if you're at a url with a trailing slash...
424
+ destination = Rack::Utils.escape("#{tag.locals.tag.title}") + '/'
425
+ end
426
+ %{<a href="#{destination}#{anchor}"#{attributes}>#{text}</a>}
427
+ end
428
+
429
+ desc %{
430
+ Shows description of current tag.
431
+
432
+ *Usage:*
433
+ <pre><code><r:tag:description /></code></pre>
434
+ }
435
+ tag 'tag:description' do |tag|
436
+ raise TagError, "tag must be defined for tag:description tag" unless tag.locals.tag
437
+ tag.locals.tag.description
438
+ end
439
+
440
+ desc %{
441
+ Shows use_count of current tag (which will normally only be set if we're within a tag_cloud tag)
442
+
443
+ *Usage:*
444
+ <pre><code><r:tag:use_count /></code></pre>
445
+ }
446
+ tag 'tag:use_count' do |tag|
447
+ raise TagError, "tag must be defined for tag:use_count tag" unless tag.locals.tag
448
+ tag.locals.tag.use_count
449
+ end
450
+
451
+ desc %{
452
+ Contents are rendered if the current tag has been applied to any pages.
453
+
454
+ *Usage:*
455
+ <pre><code><r:tag:if_pages>...</r:tag:if_pages></code></pre>
456
+ }
457
+ tag 'tag:if_pages' do |tag|
458
+ tag.expand if tag.locals.tag.pages.any?
459
+ end
460
+
461
+ desc %{
462
+ Contents are rendered unless the current tag has been applied to any pages.
463
+
464
+ *Usage:*
465
+ <pre><code><r:tag:unless_pages>...</r:tag:unless_pages></code></pre>
466
+ }
467
+ tag 'tag:unless_pages' do |tag|
468
+ tag.expand unless tag.locals.tag.pages.any?
469
+ end
470
+
471
+ desc %{
472
+ Loops through the pages to which this tag has been applied
473
+ setting page context for all contained tags. Works just like children:each
474
+ or other page tags.
475
+
476
+ *Usage:*
477
+ <pre><code><r:tag:pages:each>...</r:tag:pages:each></code></pre>
478
+ }
479
+ tag 'tag:pages' do |tag|
480
+ raise TagError, "tag must be defined for tag:pages tag" unless tag.locals.tag
481
+ tag.expand
482
+ end
483
+ tag 'tag:pages:each' do |tag|
484
+ result = []
485
+ options = children_find_options(tag)
486
+ tag.locals.pages = tag.locals.tag.pages.scoped(options)
487
+ if paging = pagination_find_options(tag)
488
+ tag.locals.pages = tag.locals.pages.paginate(paging)
489
+ end
490
+ tag.locals.pages.each do |page|
491
+ tag.locals.page = page
492
+ result << tag.expand
493
+ end
494
+ result
495
+ end
496
+
497
+ ############### asset-listing equivalents of page tags
498
+ # the main use for these tags is to pull related images and documents into pages
499
+ # in the same way as you would pull in related pages
500
+
501
+ desc %{
502
+ Lists all the assets associated with a set of tags, in descending order of relatedness.
503
+ We default to the set of tags attached to this page.
504
+
505
+ *Usage:*
506
+ <pre><code><r:tags:assets:each>...</r:tags:assets:each></code></pre>
507
+ }
508
+ tag 'tags:assets' do |tag|
509
+ tag.expand
510
+ end
511
+ tag 'tags:assets:each' do |tag|
512
+ tag.locals.assets ||= _asset_finder(tag)
513
+ tag.render('asset_list', tag.attr.dup, &tag.block)
514
+ end
515
+
516
+ desc %{
517
+ Renders the contained elements only if there are any assets associated with the current set of tags.
518
+
519
+ *Usage:*
520
+ <pre><code><r:tags:if_assets>...</r:tags:if_assets></code></pre>
521
+ }
522
+ tag "tags:if_assets" do |tag|
523
+ tag.locals.assets = _assets_for_tags(tag.locals.tags)
524
+ tag.expand if tag.locals.assets.any?
525
+ end
526
+
527
+ desc %{
528
+ Renders the contained elements only if there are no assets associated with the current set of tags.
529
+
530
+ *Usage:*
531
+ <pre><code><r:tags:unless_assets>...</r:tags:unless_assets></code></pre>
532
+ }
533
+ tag "tags:unless_assets" do |tag|
534
+ tag.locals.assets = _assets_for_tags(tag.locals.tags)
535
+ tag.expand unless tag.locals.assets.any?
536
+ end
537
+
538
+ desc %{
539
+ Lists all the assets similar to this page (based on its tagging), in descending order of relatedness.
540
+
541
+ *Usage:*
542
+ <pre><code><r:related_assets:each>...</r:related_assets:each></code></pre>
543
+ }
544
+ tag 'related_assets' do |tag|
545
+ raise TagError, "page must be defined for related_assets tag" unless tag.locals.page
546
+ tag.locals.assets = Asset.not_furniture.from_tags(tag.locals.page.attached_tags)
547
+ tag.expand
548
+ end
549
+ tag 'related_assets:each' do |tag|
550
+ tag.render('asset_list', tag.attr.dup, &tag.block)
551
+ end
552
+
553
+ Asset.known_types.each do |type|
554
+ desc %{
555
+ Lists all the #{type} assets similar to this page (based on its tagging), in descending order of relatedness.
556
+
557
+ *Usage:*
558
+ <pre><code><r:related_#{type.to_s.pluralize}:each>...</r:related_#{type.to_s.pluralize}:each></code></pre>
559
+ }
560
+ tag "related_#{type.to_s.pluralize}" do |tag|
561
+ raise TagError, "page must be defined for related_#{type.to_s.pluralize} tag" unless tag.locals.page
562
+ tag.locals.assets = Asset.not_furniture.from_tags(tag.locals.page.attached_tags).send("#{type.to_s.pluralize}".intern)
563
+ tag.expand
564
+ end
565
+ tag "related_#{type.to_s.pluralize}:each" do |tag|
566
+ tag.render('asset_list', tag.attr.dup, &tag.block)
567
+ end
568
+ end
569
+
570
+ ############### tags: tags for displaying assets when we have a tag
571
+ # similar tags already exist for pages
572
+
573
+ desc %{
574
+ Loops through the assets to which the present tag has been applied
575
+
576
+ *Usage:*
577
+ <pre><code><r:tag:assets:each>...</r:tag:assets:each></code></pre>
578
+ }
579
+ tag 'tag:assets' do |tag|
580
+ raise TagError, "tag must be defined for tag:assets tag" unless tag.locals.tag
581
+ tag.locals.assets = tag.locals.tag.assets
582
+ tag.expand
583
+ end
584
+ tag 'tag:assets:each' do |tag|
585
+ tag.render('assets:each', tag.attr.dup, &tag.block)
586
+ end
587
+
588
+ desc %{
589
+ Renders the contained elements only if there are any assets associated with the current tag.
590
+
591
+ *Usage:*
592
+ <pre><code><r:tag:if_assets>...</r:tag:if_assets></code></pre>
593
+ }
594
+ tag "tag:if_assets" do |tag|
595
+ raise TagError, "tag must be defined for tag:if_assets tag" unless tag.locals.tag
596
+ tag.locals.assets = tag.locals.tag.assets
597
+ tag.expand if tag.locals.assets.any?
598
+ end
599
+
600
+ desc %{
601
+ Renders the contained elements only if there are no assets associated with the current tag.
602
+
603
+ *Usage:*
604
+ <pre><code><r:tag:unless_assets>...</r:tag:unless_assets></code></pre>
605
+ }
606
+ tag "tag:unless_assets" do |tag|
607
+ raise TagError, "tag must be defined for tag:unless_assets tag" unless tag.locals.tag
608
+ tag.locals.assets = tag.locals.tag.assets
609
+ tag.expand unless tag.locals.assets.any?
610
+ end
611
+
612
+
613
+
614
+ private
615
+
616
+ def _get_tag(tag, options)
617
+ if title = options.delete('title')
618
+ tag.locals.tag ||= Tag.find_by_title(title)
619
+ elsif id = options.delete('id')
620
+ tag.locals.tag ||= Tag.find_by_id(id)
621
+ end
622
+ if tag.locals.page.respond_to? :requested_tags
623
+ tag.locals.tag ||= tag.locals.page.requested_tags.first
624
+ end
625
+ tag.locals.tag
626
+ end
627
+
628
+ # this is the default used for bare tags:* tags.
629
+ # among other things it catches the tags="" attribute
630
+ # but change is likely here and anything not documented shouldn't be relied upon.
631
+
632
+ def _get_tags(tag)
633
+ tags = if tag.attr['tags'] && !tag.attr['tags'].blank?
634
+ Tag.from_list(tag.attr['tags'], false) # false parameter -> not to create missing tags
635
+ elsif tag.locals.page.respond_to?(:requested_tags)
636
+ tag.locals.page.requested_tags
637
+ elsif tag.locals.page
638
+ tag.locals.page.attached_tags.visible
639
+ else
640
+ []
641
+ end
642
+ tag.locals.tags = tags.uniq.compact
643
+ end
644
+
645
+
646
+ def _asset_finder(tag)
647
+ if (tag.locals.tags)
648
+ Asset.from_all_tags(tag.locals.tags).not_furniture
649
+ else
650
+ Asset.not_furniture
651
+ end
652
+ end
653
+
654
+ end
655
+ end
@@ -0,0 +1,16 @@
1
+ module Taggable
2
+ module AdminPagesController
3
+
4
+ def self.included(base)
5
+
6
+ base.class_eval {
7
+ def initialize_meta_rows_and_buttons_with_tags
8
+ initialize_meta_rows_and_buttons_without_tags
9
+ @meta.delete(@meta.find{|m| m[:field] == 'keywords'})
10
+ end
11
+ alias_method_chain :initialize_meta_rows_and_buttons, :tags
12
+ }
13
+
14
+ end
15
+ end
16
+ end