radiant-taggable-extension 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +125 -0
- data/Rakefile +136 -0
- data/VERSION +1 -0
- data/app/controllers/admin/taggings_controller.rb +8 -0
- data/app/controllers/admin/tags_controller.rb +17 -0
- data/app/models/tag.rb +200 -0
- data/app/models/tagging.rb +50 -0
- data/app/views/admin/pages/_edit_title.html.haml +28 -0
- data/app/views/admin/tags/_form.html.haml +23 -0
- data/app/views/admin/tags/_search_results.html.haml +10 -0
- data/app/views/admin/tags/cloud.html.haml +17 -0
- data/app/views/admin/tags/edit.html.haml +14 -0
- data/app/views/admin/tags/index.html.haml +53 -0
- data/app/views/admin/tags/new.html.haml +13 -0
- data/app/views/admin/tags/show.html.haml +32 -0
- data/config/routes.rb +6 -0
- data/db/migrate/001_create_tags.rb +26 -0
- data/db/migrate/002_import_keywords.rb +11 -0
- data/lib/taggable_admin_page_controller.rb +18 -0
- data/lib/taggable_admin_ui.rb +41 -0
- data/lib/taggable_model.rb +128 -0
- data/lib/taggable_page.rb +48 -0
- data/lib/taggable_tags.rb +456 -0
- data/lib/tasks/taggable_extension_tasks.rake +55 -0
- data/pkg/radiant-taggable-extension-1.2.0.gem +0 -0
- data/public/images/admin/new-tag.png +0 -0
- data/public/images/admin/tag.png +0 -0
- data/public/images/furniture/detag.png +0 -0
- data/public/stylesheets/admin/tags.css +20 -0
- data/public/stylesheets/sass/tagcloud.sass +29 -0
- data/radiant-taggable-extension.gemspec +84 -0
- data/spec/datasets/tag_sites_dataset.rb +9 -0
- data/spec/datasets/tags_dataset.rb +43 -0
- data/spec/lib/taggable_page_spec.rb +93 -0
- data/spec/models/tag_spec.rb +39 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +36 -0
- data/taggable_extension.rb +36 -0
- metadata +123 -0
@@ -0,0 +1,456 @@
|
|
1
|
+
module TaggableTags
|
2
|
+
include Radiant::Taggable
|
3
|
+
|
4
|
+
class TagError < StandardError; end
|
5
|
+
|
6
|
+
# tag sets.
|
7
|
+
|
8
|
+
desc %{
|
9
|
+
The root 'tags' is not usually called directly.
|
10
|
+
All it does is default to the list of page tags.
|
11
|
+
Most tags:* methods are called indirectly: eg 'requested_tags:list'
|
12
|
+
will set context to the requested tags and then render tags:list.
|
13
|
+
In that case we just oblige by expanding.
|
14
|
+
}
|
15
|
+
tag 'tags' do |tag|
|
16
|
+
tags ||= _get_tags(tag);
|
17
|
+
tag.expand
|
18
|
+
end
|
19
|
+
|
20
|
+
desc %{
|
21
|
+
Contents are rendered only if a set of tags is available.
|
22
|
+
|
23
|
+
*Usage:*
|
24
|
+
<pre><code><r:if_tags>...</r:if_tags></code></pre>
|
25
|
+
}
|
26
|
+
tag 'if_tags' do |tag|
|
27
|
+
tag.expand if tag.locals.tags && tag.locals.tags.any?
|
28
|
+
end
|
29
|
+
|
30
|
+
desc %{
|
31
|
+
Contents are rendered only if no set of tags is available.
|
32
|
+
|
33
|
+
*Usage:*
|
34
|
+
<pre><code><r:unless_tags>...</r:unless_tags></code></pre>
|
35
|
+
}
|
36
|
+
tag 'unless_tags' do |tag|
|
37
|
+
tag.expand unless tag.locals.tags && tag.locals.tags.any?
|
38
|
+
end
|
39
|
+
|
40
|
+
################# list-display tags: take a set and display it somehow. Because they're in the tags: namespace they default to tag.locals.page.tags.
|
41
|
+
|
42
|
+
desc %{
|
43
|
+
Summarises in a sentence the list of tags currently active.
|
44
|
+
|
45
|
+
*Usage:*
|
46
|
+
<pre><code>Pages tagged with <r:tags:summary />:</code></pre>
|
47
|
+
|
48
|
+
And the output would be "Pages tagged with tag1, tag2 and tag3:".
|
49
|
+
}
|
50
|
+
tag 'tags:summary' do |tag|
|
51
|
+
if tag.locals.tags && tag.locals.tags.any?
|
52
|
+
options = tag.attr.dup
|
53
|
+
tag.locals.tags.map { |t|
|
54
|
+
tag.locals.tag = t
|
55
|
+
tag.render('tag:title', options)
|
56
|
+
}.to_sentence
|
57
|
+
else
|
58
|
+
"no tags"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
desc %{
|
63
|
+
Cycles through all tags in context. You can also specify a set of tags, which is occasionally
|
64
|
+
a useful shortcut for building a topic list.
|
65
|
+
|
66
|
+
*Usage:*
|
67
|
+
<pre><code><r:tags:each tags="foo, bar">...</r:tags:each></code></pre>
|
68
|
+
}
|
69
|
+
tag 'tags:each' do |tag|
|
70
|
+
result = []
|
71
|
+
tag.locals.tags.each do |item|
|
72
|
+
tag.locals.tag = item
|
73
|
+
result << tag.expand
|
74
|
+
end
|
75
|
+
result
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
# These are never called directly: but are separated here to dry out the tag handling
|
80
|
+
# see r:tag_cloud, or in the library extension, compound forms like r:coincident_tags:tag_cloud and r:requested_tags:list
|
81
|
+
# same goes for r:tags:summary but that's occasionally useful on a page too.
|
82
|
+
|
83
|
+
tag 'tags:cloud' do |tag|
|
84
|
+
if tag.locals.tags && tag.locals.tags.length > 1
|
85
|
+
options = tag.attr.dup
|
86
|
+
tag.locals.tags = Tag.for_cloud(tag.locals.tags).sort_by{|t| t.title.downcase} # nb. for_cloud immediately returns list if already sized
|
87
|
+
result = []
|
88
|
+
result << %{<div class="cloud">}
|
89
|
+
tag.locals.tags.each do |t|
|
90
|
+
tag.locals.tag = t
|
91
|
+
result << tag.render("tag:link", options.merge('style' => "font-size: #{t.cloud_size.to_f * 2.5}em;"))
|
92
|
+
end
|
93
|
+
result << "</div>"
|
94
|
+
result.join(" ")
|
95
|
+
else
|
96
|
+
"No tags"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
tag 'tags:list' do |tag|
|
101
|
+
if tag.locals.tags && tag.locals.tags.any?
|
102
|
+
options = tag.attr.dup
|
103
|
+
show_checkboxes = (options.delete('checklist') == 'true')
|
104
|
+
listclass = options.delete('listclass') || 'taglist'
|
105
|
+
result = %{<ul class="#{listclass}">}
|
106
|
+
tag.locals.tags.each do |t|
|
107
|
+
tag.locals.tag = t
|
108
|
+
result << %{<li>#{tag.render('tag:link', options)}</li>}
|
109
|
+
end
|
110
|
+
result << "</ul>"
|
111
|
+
result
|
112
|
+
else
|
113
|
+
"No tags"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
################# page-candy: these are high level tags that bring in a whole block of stuff.
|
120
|
+
# most can be built out of the smaller tags if you need them to work differently
|
121
|
+
|
122
|
+
desc %{
|
123
|
+
Returns a tag-cloud showing all the tags attached to this page and its descendants,
|
124
|
+
with cloud band css classes determined by popularity *within the group*. This is intended as a way to
|
125
|
+
show what subjects are relevant here, as in the original delicio.us tag clouds. You can achieve similar
|
126
|
+
results with tags like r:all_tags:cloud, but with important differences:
|
127
|
+
|
128
|
+
* here prominence depends on popularity within the retrieved set of tags (not overall)
|
129
|
+
* here we climb down the page tree to build the set of tags: useful for eg. a section front page.
|
130
|
+
|
131
|
+
*Usage:*
|
132
|
+
<pre><code><r:tag_cloud /></code></pre>
|
133
|
+
|
134
|
+
You can supply a url parameter to work from a page other than the present one.
|
135
|
+
|
136
|
+
<pre><code><r:tag_cloud url="/elsewhere" /></code></pre>
|
137
|
+
|
138
|
+
So if you want to show all the tags attached to any page (but ignore their attachment to anything else):
|
139
|
+
|
140
|
+
<pre><code><r:tag_cloud url="/" /></code></pre>
|
141
|
+
|
142
|
+
As usual you can limit the size of the cloud (the most popular will be shown) and set the destination of tag links:
|
143
|
+
|
144
|
+
<pre><code><r:tag_cloud limit="200" linkto="/archive" /></code></pre>
|
145
|
+
}
|
146
|
+
tag 'tag_cloud' do |tag|
|
147
|
+
options = tag.attr.dup
|
148
|
+
limit = options.delete('limit')
|
149
|
+
if url = options.delete('url')
|
150
|
+
found = Page.find_by_url(absolute_path_for(tag.locals.page.url, url))
|
151
|
+
raise TagError, "no page at url #{url}" unless page_found?(found)
|
152
|
+
tag.locals.page = found
|
153
|
+
end
|
154
|
+
raise TagError, "no page for tag_cloud" unless tag.locals.page
|
155
|
+
tag.locals.tags = tag.locals.page.tags_for_cloud(limit) # page.tags_for_cloud does a lot of inheritance work
|
156
|
+
tag.render('tags:cloud', options)
|
157
|
+
end
|
158
|
+
|
159
|
+
desc %{
|
160
|
+
Returns a list of tags showing all the tags attached to this page and its descendants. It's essentially the same
|
161
|
+
as the tag cloud without the band formatting, but accepts the same options as tags:list.
|
162
|
+
|
163
|
+
*Usage:*
|
164
|
+
<pre><code><r:tag_list /></code></pre>
|
165
|
+
|
166
|
+
As usual you can limit the size of the list (the most popular will be shown) and set the destination of tag links:
|
167
|
+
|
168
|
+
<pre><code><r:tag_list limit="200" linkto="/archive" /></code></pre>
|
169
|
+
}
|
170
|
+
tag 'tag_list' do |tag|
|
171
|
+
options = tag.attr.dup
|
172
|
+
limit = options.delete('limit')
|
173
|
+
if url = options.delete('url')
|
174
|
+
found = Page.find_by_url(absolute_path_for(tag.locals.page.url, url))
|
175
|
+
raise TagError, "no page at url #{url}" unless page_found?(found)
|
176
|
+
tag.locals.page = found
|
177
|
+
end
|
178
|
+
raise TagError, "no page for tag_list" unless tag.locals.page
|
179
|
+
tag.locals.tags = tag.locals.page.tags_for_cloud(limit) # page.tags_for_cloud does a lot of inheritance work
|
180
|
+
tag.render('tags:list', options)
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
################# tagged pages. Other extensions define similar tags for eg tagged assets.
|
186
|
+
|
187
|
+
# general purpose pages lister
|
188
|
+
|
189
|
+
desc %{
|
190
|
+
This is a general purpose page lister. It wouldn't normally be accessed directly but a lot of other tags make use of it.
|
191
|
+
}
|
192
|
+
tag 'page_list' do |tag|
|
193
|
+
raise TagError, "no pages for page_list" unless tag.locals.pages
|
194
|
+
result = []
|
195
|
+
tag.locals.pages.each do |page|
|
196
|
+
tag.locals.page = page
|
197
|
+
result << tag.expand
|
198
|
+
end
|
199
|
+
result
|
200
|
+
end
|
201
|
+
|
202
|
+
desc %{
|
203
|
+
Lists all the pages associated with a set of tags, in descending order of relatedness.
|
204
|
+
|
205
|
+
*Usage:*
|
206
|
+
<pre><code><r:tags:pages:each>...</r:tags:pages:each></code></pre>
|
207
|
+
}
|
208
|
+
tag 'tags:pages' do |tag|
|
209
|
+
tag.locals.pages = Page.from_tags(tag.locals.tags)
|
210
|
+
tag.expand
|
211
|
+
end
|
212
|
+
tag 'tags:pages:each' do |tag|
|
213
|
+
tag.render('pages:each', tag.attr.dup, &tag.block)
|
214
|
+
end
|
215
|
+
|
216
|
+
desc %{
|
217
|
+
Renders the contained elements only if there are any pages associated with the current set of tags.
|
218
|
+
|
219
|
+
*Usage:*
|
220
|
+
<pre><code><r:tags:if_pages>...</r:tags:if_pages></code></pre>
|
221
|
+
}
|
222
|
+
tag "tags:if_pages" do |tag|
|
223
|
+
tag.locals.pages = Page.from_tags(tag.locals.tags)
|
224
|
+
tag.expand if tag.locals.pages.to_a.any?
|
225
|
+
end
|
226
|
+
|
227
|
+
desc %{
|
228
|
+
Renders the contained elements only if there are no pages associated with the current set of tags.
|
229
|
+
|
230
|
+
*Usage:*
|
231
|
+
<pre><code><r:tags:unless_pages>...</r:tags:unless_pages></code></pre>
|
232
|
+
}
|
233
|
+
tag "tags:unless_pages" do |tag|
|
234
|
+
tag.locals.pages = Page.from_tags(tag.locals.tags)
|
235
|
+
tag.expand unless tag.locals.pages.to_a.any?
|
236
|
+
end
|
237
|
+
|
238
|
+
# just a shortcut, but a useful one
|
239
|
+
|
240
|
+
desc %{
|
241
|
+
Lists all the pages similar to this page (based on its tagging), in descending order of relatedness.
|
242
|
+
|
243
|
+
*Usage:*
|
244
|
+
<pre><code><r:related_pages:each>...</r:related_pages:each></code></pre>
|
245
|
+
}
|
246
|
+
tag 'related_pages' do |tag|
|
247
|
+
raise TagError, "page must be defined for related_pages tag" unless tag.locals.page
|
248
|
+
tag.locals.pages = tag.locals.page.related_pages
|
249
|
+
tag.expand
|
250
|
+
end
|
251
|
+
tag 'related_pages:each' do |tag|
|
252
|
+
tag.render('pages:each', tag.attr.dup, &tag.block)
|
253
|
+
end
|
254
|
+
|
255
|
+
|
256
|
+
desc %{
|
257
|
+
Shows a link to the target page with a (non-linked) breadcrumb trail to give it context.
|
258
|
+
This is the opposite of r:breadcrumbs, which shows a linked trail but doesn't link the current page.
|
259
|
+
Link and breadcrumb attributes should work in the usual way, and by default we omit the home page
|
260
|
+
from the list since it adds no information. pass omit_root='false' to show the whole chain.
|
261
|
+
|
262
|
+
*Usage:*
|
263
|
+
<pre><code><r:tag:pages:each>
|
264
|
+
<r:crumbed_link [omit_root="false"] [separator=" → "] />
|
265
|
+
<r:crumbed_link>Link text</r:crumbed_link>
|
266
|
+
etc
|
267
|
+
</r:tag:pages:each></code></pre>
|
268
|
+
}
|
269
|
+
tag 'crumbed_link' do |tag|
|
270
|
+
page = tag.locals.page
|
271
|
+
ancestors = page.ancestors
|
272
|
+
ancestors.pop unless tag.attr['omit_root'] == 'false'
|
273
|
+
breadcrumbs = [tag.render('link')]
|
274
|
+
ancestors.each do |ancestor|
|
275
|
+
tag.locals.page = ancestor
|
276
|
+
breadcrumbs.unshift tag.render('breadcrumb')
|
277
|
+
end
|
278
|
+
separator = tag.attr['separator'] || ' > '
|
279
|
+
breadcrumbs.join(separator)
|
280
|
+
end
|
281
|
+
|
282
|
+
|
283
|
+
|
284
|
+
################# single tag expansion for simple lists of tagged items or for customised display of each item in a list or cloud context
|
285
|
+
|
286
|
+
desc %{
|
287
|
+
This is the namespace for referencing a single tag. It's not usually called directly,
|
288
|
+
but you can supply a 'title' or 'id' attribute.
|
289
|
+
|
290
|
+
*Usage:*
|
291
|
+
<pre><code><r:tag [title="tag_title"]>...</r:tag></code></pre>
|
292
|
+
}
|
293
|
+
tag 'tag' do |tag|
|
294
|
+
tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
|
295
|
+
tag.expand
|
296
|
+
end
|
297
|
+
|
298
|
+
desc %{
|
299
|
+
Contents are rendered if a tag is currently defined. Useful on a LibraryPage page where you may or
|
300
|
+
may not have received a tag parameter.
|
301
|
+
|
302
|
+
*Usage:*
|
303
|
+
<pre><code><r:if_tag>...</r:if_tag></code></pre>
|
304
|
+
}
|
305
|
+
tag 'if_tag' do |tag|
|
306
|
+
tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
|
307
|
+
tag.expand if tag.locals.tag
|
308
|
+
end
|
309
|
+
|
310
|
+
desc %{
|
311
|
+
Contents are rendered if no tag is currently defined. Useful on a LibraryPage page where you may or
|
312
|
+
may not have a tag parameter.
|
313
|
+
|
314
|
+
*Usage:*
|
315
|
+
<pre><code><r:unless_tag>...</r:unless_tag></code></pre>
|
316
|
+
}
|
317
|
+
tag 'unless_tag' do |tag|
|
318
|
+
tag.locals.tag ||= _get_tag(tag, tag.attr.dup)
|
319
|
+
tag.expand unless tag.locals.tag
|
320
|
+
end
|
321
|
+
|
322
|
+
desc %{
|
323
|
+
Shows name of current tag.
|
324
|
+
|
325
|
+
*Usage:*
|
326
|
+
<pre><code><r:tag:name /></code></pre>
|
327
|
+
}
|
328
|
+
tag 'tag:name' do |tag|
|
329
|
+
raise TagError, "tag must be defined for tag:title tag" unless tag.locals.tag
|
330
|
+
tag.locals.tag.title
|
331
|
+
end
|
332
|
+
|
333
|
+
desc %{
|
334
|
+
Makes a link to the current tag. If the current page is a library page, we amend the
|
335
|
+
list of requested tags. Otherwise, the 'linkto' parameter can be the address of a
|
336
|
+
LibraryPage, or you can specify a global tags page with a 'library.path' config entry.
|
337
|
+
|
338
|
+
If no destination is specified we return a relative link to the escaped name of the tag.
|
339
|
+
|
340
|
+
*Usage:*
|
341
|
+
<pre><code><r:tag:link linkto='/library' /></code></pre>
|
342
|
+
}
|
343
|
+
tag 'tag:link' do |tag|
|
344
|
+
raise TagError, "tag must be defined for tag:link tag" unless tag.locals.tag
|
345
|
+
options = tag.attr.dup
|
346
|
+
anchor = options['anchor'] ? "##{options.delete('anchor')}" : ''
|
347
|
+
attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
|
348
|
+
attributes = " #{attributes}" unless attributes.empty?
|
349
|
+
text = tag.double? ? tag.expand : tag.render('tag:name')
|
350
|
+
if tag.locals.page.is_a? LibraryPage
|
351
|
+
tagset = tag.locals.page.requested_tags + [tag.locals.tag]
|
352
|
+
destination = tag.locals.page.url(tagset)
|
353
|
+
elsif page_url = (options.delete('linkto') || Radiant::Config['library.path'])
|
354
|
+
destination = clean_url(page_url + '/' + tag.locals.tag.clean_title)
|
355
|
+
else
|
356
|
+
# note that this only works if you're at a url with a trailing slash...
|
357
|
+
destination = Rack::Utils.escape("#{tag.locals.tag.title}") + '/'
|
358
|
+
end
|
359
|
+
%{<a href="#{destination}#{anchor}"#{attributes}>#{text}</a>}
|
360
|
+
end
|
361
|
+
|
362
|
+
desc %{
|
363
|
+
Shows description of current tag.
|
364
|
+
|
365
|
+
*Usage:*
|
366
|
+
<pre><code><r:tag:description /></code></pre>
|
367
|
+
}
|
368
|
+
tag 'tag:description' do |tag|
|
369
|
+
raise TagError, "tag must be defined for tag:description tag" unless tag.locals.tag
|
370
|
+
tag.locals.tag.description
|
371
|
+
end
|
372
|
+
|
373
|
+
desc %{
|
374
|
+
Shows use_count of current tag (which will normally only be set if we're within a tag_cloud tag)
|
375
|
+
|
376
|
+
*Usage:*
|
377
|
+
<pre><code><r:tag:use_count /></code></pre>
|
378
|
+
}
|
379
|
+
tag 'tag:use_count' do |tag|
|
380
|
+
raise TagError, "tag must be defined for tag:use_count tag" unless tag.locals.tag
|
381
|
+
tag.locals.tag.use_count
|
382
|
+
end
|
383
|
+
|
384
|
+
desc %{
|
385
|
+
Contents are rendered if the current tag has been applied to any pages.
|
386
|
+
|
387
|
+
*Usage:*
|
388
|
+
<pre><code><r:tag:if_pages>...</r:tag:if_pages></code></pre>
|
389
|
+
}
|
390
|
+
tag 'tag:if_pages' do |tag|
|
391
|
+
tag.expand if tag.locals.tag.pages.any?
|
392
|
+
end
|
393
|
+
|
394
|
+
desc %{
|
395
|
+
Contents are rendered unless the current tag has been applied to any pages.
|
396
|
+
|
397
|
+
*Usage:*
|
398
|
+
<pre><code><r:tag:unless_pages>...</r:tag:unless_pages></code></pre>
|
399
|
+
}
|
400
|
+
tag 'tag:unless_pages' do |tag|
|
401
|
+
tag.expand unless tag.locals.tag.pages.any?
|
402
|
+
end
|
403
|
+
|
404
|
+
desc %{
|
405
|
+
Loops through the pages to which this tag has been applied
|
406
|
+
setting page context for all contained tags. Works just like children:each
|
407
|
+
or other page tags.
|
408
|
+
|
409
|
+
*Usage:*
|
410
|
+
<pre><code><r:tag:pages:each>...</r:tag:pages:each></code></pre>
|
411
|
+
}
|
412
|
+
tag 'tag:pages' do |tag|
|
413
|
+
raise TagError, "tag must be defined for tag:pages tag" unless tag.locals.tag
|
414
|
+
tag.expand
|
415
|
+
end
|
416
|
+
tag 'tag:pages:each' do |tag|
|
417
|
+
result = []
|
418
|
+
tag.locals.tag.pages.each do |page|
|
419
|
+
tag.locals.page = page
|
420
|
+
result << tag.expand
|
421
|
+
end
|
422
|
+
result
|
423
|
+
end
|
424
|
+
|
425
|
+
|
426
|
+
|
427
|
+
private
|
428
|
+
|
429
|
+
def _get_tag(tag, options)
|
430
|
+
if title = options.delete('title')
|
431
|
+
tag.locals.tag ||= Tag.find_by_title(title)
|
432
|
+
end
|
433
|
+
if tag.locals.page.respond_to? :requested_tags
|
434
|
+
tag.locals.tag ||= tag.locals.page.requested_tags.first
|
435
|
+
end
|
436
|
+
tag.locals.tag
|
437
|
+
end
|
438
|
+
|
439
|
+
# this is the default used for bare tags:* tags.
|
440
|
+
# among other things it catches the tags="" attribute
|
441
|
+
# but change is likely here and anything not documented shouldn't be relied upon.
|
442
|
+
|
443
|
+
def _get_tags(tag)
|
444
|
+
tags = if tag.attr['tags'] && !tag.attr['tags'].blank?
|
445
|
+
Tag.from_list(tag.attr['tags'], false) # false parameter -> not to create missing tags
|
446
|
+
elsif tag.locals.page.respond_to?(:requested_tags)
|
447
|
+
tag.locals.page.requested_tags
|
448
|
+
elsif tag.locals.page
|
449
|
+
tag.locals.page.attached_tags
|
450
|
+
else
|
451
|
+
[]
|
452
|
+
end
|
453
|
+
tags = tags.uniq.select{|t| !t.nil? }
|
454
|
+
end
|
455
|
+
|
456
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
namespace :radiant do
|
2
|
+
namespace :extensions do
|
3
|
+
namespace :taggable do
|
4
|
+
|
5
|
+
desc "Runs the migration of the Taggable extension"
|
6
|
+
task :migrate => :environment do
|
7
|
+
require 'radiant/extension_migrator'
|
8
|
+
if ENV["VERSION"]
|
9
|
+
TaggableExtension.migrator.migrate(ENV["VERSION"].to_i)
|
10
|
+
Rake::Task['db:schema:dump'].invoke
|
11
|
+
else
|
12
|
+
TaggableExtension.migrator.migrate
|
13
|
+
Rake::Task['db:schema:dump'].invoke
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Copies public assets of the Taggable to the instance public/ directory."
|
18
|
+
task :update => :environment do
|
19
|
+
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
20
|
+
puts "Copying assets from TaggableExtension"
|
21
|
+
Dir[TaggableExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
22
|
+
path = file.sub(TaggableExtension.root, '')
|
23
|
+
directory = File.dirname(path)
|
24
|
+
mkdir_p RAILS_ROOT + directory, :verbose => false
|
25
|
+
cp file, RAILS_ROOT + path, :verbose => false
|
26
|
+
end
|
27
|
+
unless TaggableExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
|
28
|
+
puts "Copying rake tasks from TaggableExtension"
|
29
|
+
local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
|
30
|
+
mkdir_p local_tasks_path, :verbose => false
|
31
|
+
Dir[File.join TaggableExtension.root, %w(lib tasks *.rake)].each do |file|
|
32
|
+
cp file, local_tasks_path, :verbose => false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Syncs all available translations for this ext to the English ext master"
|
38
|
+
task :sync => :environment do
|
39
|
+
# The main translation root, basically where English is kept
|
40
|
+
language_root = TaggableExtension.root + "/config/locales"
|
41
|
+
words = TranslationSupport.get_translation_keys(language_root)
|
42
|
+
|
43
|
+
Dir["#{language_root}/*.yml"].each do |filename|
|
44
|
+
next if filename.match('_available_tags')
|
45
|
+
basename = File.basename(filename, '.yml')
|
46
|
+
puts "Syncing #{basename}"
|
47
|
+
(comments, other) = TranslationSupport.read_file(filename, basename)
|
48
|
+
words.each { |k,v| other[k] ||= words[k] } # Initializing hash variable as empty if it does not exist
|
49
|
+
other.delete_if { |k,v| !words[k] } # Remove if not defined in en.yml
|
50
|
+
TranslationSupport.write_file(filename, basename, comments, other)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#tags-table table { margin-bottom: 0; }
|
2
|
+
td.tag-title { font-size: 115%; font-weight: bold;}
|
3
|
+
td.tag-title a { text-decoration: none; color: black; }
|
4
|
+
td.tag-description {
|
5
|
+
font-size: 80%;
|
6
|
+
color: #999;
|
7
|
+
}
|
8
|
+
|
9
|
+
ul.cloud {
|
10
|
+
list-style: none;
|
11
|
+
margin: 0;
|
12
|
+
padding: 0;
|
13
|
+
line-height: 20px; }
|
14
|
+
ul.cloud li {
|
15
|
+
display: inline;
|
16
|
+
font-family: "Lucida Grande", "Bitstream Vera Sans", Helvetica, Verdana, Arial, sans-serif;
|
17
|
+
letter-spacing: -0.04em;
|
18
|
+
white-space: nowrap;
|
19
|
+
line-height: 20px;
|
20
|
+
margin: 0; }
|
@@ -0,0 +1,29 @@
|
|
1
|
+
ul.cloud
|
2
|
+
:position relative
|
3
|
+
:list-style none
|
4
|
+
:margin 0
|
5
|
+
:padding 0
|
6
|
+
:overflow hidden
|
7
|
+
:line-height 1.6em
|
8
|
+
:margin-left -5px
|
9
|
+
|
10
|
+
li
|
11
|
+
:display inline
|
12
|
+
:float left
|
13
|
+
:letter-spacing -0.04em
|
14
|
+
:height 1.6em
|
15
|
+
|
16
|
+
a
|
17
|
+
:display inline
|
18
|
+
:white-space nowrap
|
19
|
+
:padding 5px
|
20
|
+
|
21
|
+
a.filter, a.defilter
|
22
|
+
:padding-left 11px
|
23
|
+
:font-size 12px
|
24
|
+
a.filter
|
25
|
+
:background transparent url(/images/furniture/entag.png) no-repeat top left
|
26
|
+
:color #5da454
|
27
|
+
a.defilter
|
28
|
+
:background transparent url(/images/furniture/detag.png) no-repeat top left
|
29
|
+
:color #9d313d
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{radiant-taggable-extension}
|
8
|
+
s.version = "1.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["spanner"]
|
12
|
+
s.date = %q{2010-09-10}
|
13
|
+
s.description = %q{General purpose tagging extension: more versatile but less focused than the tags extension}
|
14
|
+
s.email = %q{will@spanner.org}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"README.md",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"app/controllers/admin/taggings_controller.rb",
|
23
|
+
"app/controllers/admin/tags_controller.rb",
|
24
|
+
"app/models/tag.rb",
|
25
|
+
"app/models/tagging.rb",
|
26
|
+
"app/views/admin/pages/_edit_title.html.haml",
|
27
|
+
"app/views/admin/tags/_form.html.haml",
|
28
|
+
"app/views/admin/tags/_search_results.html.haml",
|
29
|
+
"app/views/admin/tags/cloud.html.haml",
|
30
|
+
"app/views/admin/tags/edit.html.haml",
|
31
|
+
"app/views/admin/tags/index.html.haml",
|
32
|
+
"app/views/admin/tags/new.html.haml",
|
33
|
+
"app/views/admin/tags/show.html.haml",
|
34
|
+
"config/routes.rb",
|
35
|
+
"db/migrate/001_create_tags.rb",
|
36
|
+
"db/migrate/002_import_keywords.rb",
|
37
|
+
"lib/taggable_admin_page_controller.rb",
|
38
|
+
"lib/taggable_admin_ui.rb",
|
39
|
+
"lib/taggable_model.rb",
|
40
|
+
"lib/taggable_page.rb",
|
41
|
+
"lib/taggable_tags.rb",
|
42
|
+
"lib/tasks/taggable_extension_tasks.rake",
|
43
|
+
"pkg/radiant-taggable-extension-1.2.0.gem",
|
44
|
+
"public/images/admin/new-tag.png",
|
45
|
+
"public/images/admin/tag.png",
|
46
|
+
"public/images/furniture/detag.png",
|
47
|
+
"public/stylesheets/admin/tags.css",
|
48
|
+
"public/stylesheets/sass/tagcloud.sass",
|
49
|
+
"radiant-taggable-extension.gemspec",
|
50
|
+
"spec/datasets/tag_sites_dataset.rb",
|
51
|
+
"spec/datasets/tags_dataset.rb",
|
52
|
+
"spec/lib/taggable_page_spec.rb",
|
53
|
+
"spec/models/tag_spec.rb",
|
54
|
+
"spec/spec.opts",
|
55
|
+
"spec/spec_helper.rb",
|
56
|
+
"taggable_extension.rb"
|
57
|
+
]
|
58
|
+
s.homepage = %q{http://github.com/spanner/radiant-taggable-extension}
|
59
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
60
|
+
s.require_paths = ["lib"]
|
61
|
+
s.rubygems_version = %q{1.3.7}
|
62
|
+
s.summary = %q{Taggable Extension for Radiant CMS}
|
63
|
+
s.test_files = [
|
64
|
+
"spec/datasets/tag_sites_dataset.rb",
|
65
|
+
"spec/datasets/tags_dataset.rb",
|
66
|
+
"spec/lib/taggable_page_spec.rb",
|
67
|
+
"spec/models/tag_spec.rb",
|
68
|
+
"spec/spec_helper.rb"
|
69
|
+
]
|
70
|
+
|
71
|
+
if s.respond_to? :specification_version then
|
72
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
73
|
+
s.specification_version = 3
|
74
|
+
|
75
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
76
|
+
s.add_runtime_dependency(%q<radiant>, [">= 0.9.0"])
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<radiant>, [">= 0.9.0"])
|
79
|
+
end
|
80
|
+
else
|
81
|
+
s.add_dependency(%q<radiant>, [">= 0.9.0"])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class TagSitesDataset < Dataset::Base
|
2
|
+
|
3
|
+
def load
|
4
|
+
create_record Site, :mysite, :name => 'My Site', :domain => 'mysite.domain.com', :base_domain => 'mysite.domain.com', :position => 1
|
5
|
+
create_record Site, :yoursite, :name => 'Your Site', :domain => '^yoursite', :base_domain => 'yoursite.test.com', :position => 2
|
6
|
+
create_record Site, :test, :name => 'Test host', :domain => '^test\.', :base_domain => 'test.host', :position => 3
|
7
|
+
Page.current_site = sites(:test) if defined? Site
|
8
|
+
end
|
9
|
+
end
|