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.
data/lib/taggable_tags.rb DELETED
@@ -1,529 +0,0 @@
1
- module TaggableTags
2
- include Radiant::Taggable
3
-
4
- class TagError < StandardError; end
5
-
6
- ################# general purpose lister utilities
7
- # can be contained or nested within any list-defining tag
8
- # eg.<r:structural_tags:each_tag>...
9
- # or just.<r:tags:each_tag>... (aka r:tags:each)
10
-
11
- desc %{
12
- Contents are rendered only if tags are available to display.
13
-
14
- <pre><code><r:if_tags>...</r:if_tags></code></pre>
15
-
16
- Can also be nested inside a set-definition container tag:
17
-
18
- <pre><code><r:structural_tags:if_tags>...</r:structural_tags:if_tags></code></pre>
19
- }
20
- tag 'if_tags' do |tag|
21
- tag.locals.tags ||= _get_tags(tag)
22
- tag.expand if tag.locals.tags && tag.locals.tags.any?
23
- end
24
-
25
- desc %{
26
- Contents are rendered only if no tags are available.
27
- Can also be nested inside a set-definition container tag.
28
- }
29
- tag 'unless_tags' do |tag|
30
- tag.locals.tags ||= _get_tags(tag)
31
- tag.expand unless tag.locals.tags && tag.locals.tags.any?
32
- end
33
-
34
- desc %{
35
- Loops through the current list of tags.
36
- Only works when nested within a set-defining tag.
37
- }
38
- tag "each_tag" do |tag|
39
- Rails.logger.warn ">> each_tag. tag.locals.tags is #{tag.locals.tags.inspect}"
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
- Rails.logger.warn ">> tags. tag.locals.tags is #{tag.locals.tags.inspect}"
147
- tag.locals.tags ||= _get_tags(tag)
148
- tag.expand
149
- end
150
-
151
- tag 'tags:summary' do |tag|
152
- tag.render('tag_summary', tag.attr.dup)
153
- end
154
-
155
- tag 'tags:each' do |tag|
156
- Rails.logger.warn ">> tags:each. tag.locals.tags is #{tag.locals.tags.inspect}"
157
- tag.render('each_tag', tag.attr.dup, &tag.block)
158
- end
159
-
160
- desc %{
161
- Returns a tag-cloud showing all the tags attached to this page and its descendants,
162
- with cloud band css classes determined by popularity *within the group*. This is intended as a way to
163
- show what subjects are relevant here, as in the original delicio.us tag clouds. You can achieve similar
164
- results with tags like r:all_tags:cloud, but with important differences:
165
-
166
- * here prominence depends on popularity within the retrieved set of tags (not overall)
167
- * here we climb down the page tree to build the set of tags: useful for eg. a section front page.
168
-
169
- *Usage:*
170
- <pre><code><r:tag_cloud /></code></pre>
171
-
172
- You can supply a url parameter to work from a page other than the present one.
173
-
174
- <pre><code><r:tag_cloud url="/elsewhere" /></code></pre>
175
-
176
- So if you want to show all the tags attached to any page (but ignore their attachment to anything else):
177
-
178
- <pre><code><r:tag_cloud url="/" /></code></pre>
179
-
180
- As usual you can limit the size of the cloud (the most popular will be shown) and set the destination of tag links:
181
-
182
- <pre><code><r:tags:cloud limit="200" linkto="/archive" /></code></pre>
183
- }
184
- tag 'tags:cloud' do |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
- options = tag.attr.dup
210
- limit = options.delete('limit')
211
- if url = options.delete('url')
212
- found = Page.find_by_url(absolute_path_for(tag.locals.page.url, url))
213
- raise TagError, "no page at url #{url}" unless page_found?(found)
214
- tag.locals.page = found
215
- end
216
- raise TagError, "no page for tag_list" unless tag.locals.page
217
- tag.locals.tags = tag.locals.page.tags_for_cloud(limit).sort
218
- tag.render('tags:list', options)
219
- end
220
-
221
-
222
-
223
-
224
-
225
-
226
- ################# tagged pages. Other extensions define similar tags for eg tagged assets.
227
-
228
- tag 'page_list' do |tag|
229
- raise TagError, "no pages for page_list" unless tag.locals.pages
230
- result = []
231
- options = children_find_options(tag)
232
- paging = pagination_find_options(tag)
233
- displayed_children = paging ? tag.locals.pages.paginate(options.merge(paging)) : tag.locals.pages.all(options)
234
- displayed_children.each do |item|
235
- tag.locals.page = item
236
- result << tag.expand
237
- end
238
- result
239
- end
240
-
241
- desc %{
242
- Lists all the pages associated with a set of tags, in descending order of relatedness.
243
-
244
- *Usage:*
245
- <pre><code><r:tagged_pages:each>...</r:tags:pages:each></code></pre>
246
- }
247
- tag 'tagged_pages' do |tag|
248
- tag.locals.pages = Page.from_tags(tag.locals.tags)
249
- tag.expand
250
- end
251
-
252
- tag 'tagged_pages:each' do |tag|
253
- tag.render('page_list', tag.attr.dup, &tag.block)
254
- end
255
-
256
- desc %{
257
- Renders the contained elements only if there are any pages associated with the current set of tags.
258
-
259
- <pre><code><r:if_tagged_pages>...</r:if_tagged_pages></code></pre>
260
-
261
- Can be nested in any set-defining tag:
262
-
263
- <pre><code><r:requested_tags:if_tagged_pages>...</r:requested_tags:if_tagged_pages></code></pre>
264
- }
265
- tag "if_tagged_pages" do |tag|
266
- tag.locals.pages = Page.from_tags(tag.locals.tags)
267
- tag.expand if tag.locals.pages.to_a.any?
268
- end
269
-
270
- desc %{
271
- Renders the contained elements only if there are no pages associated with the current set of tags.
272
-
273
- *Usage:*
274
- <pre><code><r:unless_tagged_pages>...</r:unless_tagged_pages></code></pre>
275
- }
276
- tag "tags:unless_pages" do |tag|
277
- tag.locals.pages = Page.from_tags(tag.locals.tags)
278
- tag.expand unless tag.locals.pages.to_a.any?
279
- end
280
-
281
- # just a shortcut, but a useful one
282
-
283
- desc %{
284
- Lists all the pages similar to this page (based on its tagging), in descending order of relatedness.
285
-
286
- *Usage:*
287
- <pre><code><r:related_pages:each>...</r:related_pages:each></code></pre>
288
- }
289
- tag 'related_pages' do |tag|
290
- tag.locals.pages = tag.locals.page.related_pages
291
- tag.expand
292
- end
293
- tag 'related_pages:each' do |tag|
294
- tag.render('page_list', tag.attr.dup, &tag.block)
295
- end
296
-
297
- desc %{
298
- Shows a link to the target page with a (non-linked) breadcrumb trail to give it context.
299
- This is the opposite of r:breadcrumbs, which shows a linked trail but doesn't link the current page.
300
- Link and breadcrumb attributes should work in the usual way, and by default we omit the home page
301
- from the list since it adds no information. pass omit_root='false' to show the whole chain.
302
-
303
- *Usage:*
304
- <pre><code><r:tag:pages:each>
305
- <r:crumbed_link [omit_root="false"] [separator=" &rarr; "] />
306
- <r:crumbed_link>Link text</r:crumbed_link>
307
- etc
308
- </r:tag:pages:each></code></pre>
309
- }
310
- tag 'crumbed_link' do |tag|
311
- page = tag.locals.page
312
- ancestors = page.ancestors
313
- ancestors.pop unless tag.attr['omit_root'] == 'false'
314
- breadcrumbs = [tag.render('link')]
315
- ancestors.each do |ancestor|
316
- tag.locals.page = ancestor
317
- breadcrumbs.unshift tag.render('breadcrumb')
318
- end
319
- separator = tag.attr['separator'] || ' &gt; '
320
- breadcrumbs.join(separator)
321
- end
322
-
323
- tag 'tags:pages' do |tag|
324
- tag.render('tagged_pages', tag.attr.dup, &tag.block)
325
- end
326
-
327
- tag "tags:if_pages" do |tag|
328
- tag.render('if_tagged_pages', tag.attr.dup, &tag.block)
329
- end
330
-
331
- tag "tags:unless_pages" do |tag|
332
- tag.render('unless_tagged_pages', tag.attr.dup, &tag.block)
333
- end
334
-
335
-
336
-
337
- ################# single tag expansion for simple lists of tagged items or for customised display of each item in a list or cloud context
338
-
339
- desc %{
340
- This is the namespace for referencing a single tag. It's not usually called directly,
341
- but you can supply a 'title' or 'id' attribute.
342
-
343
- *Usage:*
344
- <pre><code><r:tag [title="tag_title"]>...</r:tag></code></pre>
345
- }
346
- tag 'tag' do |tag|
347
- tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
348
- tag.expand
349
- end
350
-
351
- desc %{
352
- Contents are rendered if a tag is currently defined. Useful on a LibraryPage page where you may or
353
- may not have received a tag parameter.
354
-
355
- *Usage:*
356
- <pre><code><r:if_tag>...</r:if_tag></code></pre>
357
- }
358
- tag 'if_tag' do |tag|
359
- tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
360
- tag.expand if tag.locals.tag
361
- end
362
-
363
- desc %{
364
- Contents are rendered if no tag is currently defined. Useful on a LibraryPage page where you may or
365
- may not have a tag parameter.
366
-
367
- *Usage:*
368
- <pre><code><r:unless_tag>...</r:unless_tag></code></pre>
369
- }
370
- tag 'unless_tag' do |tag|
371
- tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
372
- tag.expand unless tag.locals.tag
373
- end
374
-
375
- desc %{
376
- Shows name of current tag.
377
-
378
- *Usage:*
379
- <pre><code><r:tag:name /></code></pre>
380
- }
381
- tag 'tag:name' do |tag|
382
- raise TagError, "tag must be defined for tag:name tag" unless tag.locals.tag
383
- tag.locals.tag.title
384
- end
385
-
386
- desc %{
387
- Sets context to the page association of the current tag
388
- (that is, the page towards which this tag is a pointer, if any)
389
-
390
- If there is no page, nothing is displayed.
391
-
392
- <pre><code><r:tag:page><r:link /></r:tag:page></code></pre>
393
- }
394
- tag 'tag:page' do |tag|
395
- raise TagError, "tag must be defined for tag:page tag" unless tag.locals.tag
396
- tag.expand if tag.locals.page = tag.locals.tag.page
397
- end
398
-
399
- desc %{
400
- Makes a link to the current tag. If the current page is a library page, we amend the
401
- list of requested tags. Otherwise, the 'linkto' parameter can be the address of a
402
- LibraryPage, or you can specify a global tags page with a 'library.path' config entry.
403
-
404
- If no destination is specified we return a relative link to the escaped name of the tag.
405
-
406
- *Usage:*
407
- <pre><code><r:tag_link linkto='/library' /></code></pre>
408
- }
409
- tag 'tag_link' do |tag|
410
- raise TagError, "tag must be defined for tag_link tag" unless tag.locals.tag
411
- options = tag.attr.dup
412
- anchor = options['anchor'] ? "##{options.delete('anchor')}" : ''
413
- attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
414
- attributes = " #{attributes}" unless attributes.empty?
415
- text = tag.double? ? tag.expand : tag.render('tag:name')
416
- if tag.locals.page.is_a? LibraryPage
417
- tagset = tag.locals.page.requested_tags + [tag.locals.tag]
418
- destination = tag.locals.page.url(tagset)
419
- elsif page_url = (options.delete('linkto') || Radiant::Config['library.path'])
420
- destination = clean_url(page_url + '/' + tag.locals.tag.clean_title)
421
- else
422
- # note that this only works if you're at a url with a trailing slash...
423
- destination = Rack::Utils.escape("#{tag.locals.tag.title}") + '/'
424
- end
425
- %{<a href="#{destination}#{anchor}"#{attributes}>#{text}</a>}
426
- end
427
-
428
- desc %{
429
- Shows description of current tag.
430
-
431
- *Usage:*
432
- <pre><code><r:tag:description /></code></pre>
433
- }
434
- tag 'tag:description' do |tag|
435
- raise TagError, "tag must be defined for tag:description tag" unless tag.locals.tag
436
- tag.locals.tag.description
437
- end
438
-
439
- desc %{
440
- Shows use_count of current tag (which will normally only be set if we're within a tag_cloud tag)
441
-
442
- *Usage:*
443
- <pre><code><r:tag:use_count /></code></pre>
444
- }
445
- tag 'tag:use_count' do |tag|
446
- raise TagError, "tag must be defined for tag:use_count tag" unless tag.locals.tag
447
- tag.locals.tag.use_count
448
- end
449
-
450
- desc %{
451
- Contents are rendered if the current tag has been applied to any pages.
452
-
453
- *Usage:*
454
- <pre><code><r:tag:if_pages>...</r:tag:if_pages></code></pre>
455
- }
456
- tag 'tag:if_pages' do |tag|
457
- tag.expand if tag.locals.tag.pages.any?
458
- end
459
-
460
- desc %{
461
- Contents are rendered unless the current tag has been applied to any pages.
462
-
463
- *Usage:*
464
- <pre><code><r:tag:unless_pages>...</r:tag:unless_pages></code></pre>
465
- }
466
- tag 'tag:unless_pages' do |tag|
467
- tag.expand unless tag.locals.tag.pages.any?
468
- end
469
-
470
- desc %{
471
- Loops through the pages to which this tag has been applied
472
- setting page context for all contained tags. Works just like children:each
473
- or other page tags.
474
-
475
- *Usage:*
476
- <pre><code><r:tag:pages:each>...</r:tag:pages:each></code></pre>
477
- }
478
- tag 'tag:pages' do |tag|
479
- raise TagError, "tag must be defined for tag:pages tag" unless tag.locals.tag
480
- tag.expand
481
- end
482
- tag 'tag:pages:each' do |tag|
483
- result = []
484
- options = children_find_options(tag)
485
- tag.locals.pages = tag.locals.tag.pages.scoped(options)
486
- if paging = pagination_find_options(tag)
487
- tag.locals.pages = tag.locals.pages.paginate(paging)
488
- end
489
- tag.locals.pages.each do |page|
490
- tag.locals.page = page
491
- result << tag.expand
492
- end
493
- result
494
- end
495
-
496
-
497
- private
498
-
499
- def _get_tag(tag, options)
500
- if title = options.delete('title')
501
- tag.locals.tag ||= Tag.find_by_title(title)
502
- elsif id = options.delete('id')
503
- tag.locals.tag ||= Tag.find_by_id(id)
504
- end
505
- if tag.locals.page.respond_to? :requested_tags
506
- tag.locals.tag ||= tag.locals.page.requested_tags.first
507
- end
508
- tag.locals.tag
509
- end
510
-
511
- # this is the default used for bare tags:* tags.
512
- # among other things it catches the tags="" attribute
513
- # but change is likely here and anything not documented shouldn't be relied upon.
514
-
515
- def _get_tags(tag)
516
- Rails.logger.warn "<< _get_tags"
517
- tags = if tag.attr['tags'] && !tag.attr['tags'].blank?
518
- Tag.from_list(tag.attr['tags'], false) # false parameter -> not to create missing tags
519
- elsif tag.locals.page.respond_to?(:requested_tags)
520
- tag.locals.page.requested_tags
521
- elsif tag.locals.page
522
- tag.locals.page.attached_tags.visible
523
- else
524
- []
525
- end
526
- tag.locals.tags = tags.uniq.compact
527
- end
528
-
529
- end