radiant-taggable-extension 1.2.5 → 2.0.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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