radiant-taggable-extension 1.2.3 → 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +38 -30
- data/VERSION +1 -1
- data/app/controllers/admin/tags_controller.rb +9 -3
- data/app/helpers/taggable_helper.rb +21 -0
- data/app/models/tag.rb +63 -8
- data/app/views/admin/pages/_edit_title.html.haml +6 -22
- data/app/views/admin/tags/_form.html.haml +34 -20
- data/app/views/admin/tags/cloud.html.haml +0 -7
- data/app/views/admin/tags/edit.html.haml +4 -7
- data/app/views/admin/tags/index.html.haml +14 -9
- data/app/views/admin/tags/new.html.haml +4 -3
- data/config/locales/en.yml +9 -0
- data/db/migrate/20110316210834_structural_tags.rb +17 -0
- data/db/migrate/20110411075109_metaphones.rb +15 -0
- data/lib/taggable_admin_ui.rb +3 -3
- data/lib/taggable_model.rb +15 -6
- data/lib/taggable_page.rb +6 -2
- data/lib/taggable_tags.rb +172 -99
- data/lib/text/double_metaphone.rb +356 -0
- data/lib/text/metaphone.rb +97 -0
- data/public/javascripts/admin/taggable.js +19 -0
- data/public/javascripts/autocomplete.js +334 -0
- data/public/stylesheets/sass/admin/taggable.sass +89 -0
- data/radiant-taggable-extension.gemspec +11 -3
- data/taggable_extension.rb +3 -16
- metadata +13 -5
- data/public/stylesheets/admin/tags.css +0 -20
@@ -1,4 +1,6 @@
|
|
1
|
-
-
|
1
|
+
- @page_title = "New tag" + ' - ' + default_page_title
|
2
|
+
- include_stylesheet 'admin/taggable'
|
3
|
+
- include_javascript 'admin/taggable'
|
2
4
|
|
3
5
|
- render_region :main do |main|
|
4
6
|
- main.edit_header do
|
@@ -9,5 +11,4 @@
|
|
9
11
|
If you'd like a bit more control than that, you can also create and describe tags one at a time here:
|
10
12
|
|
11
13
|
- main.edit_form do
|
12
|
-
|
13
|
-
= render :partial => 'form', :object => form
|
14
|
+
= render :partial => 'form'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class StructuralTags < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :tags, :page_id, :integer
|
4
|
+
add_column :tags, :visible, :boolean, :default => true
|
5
|
+
|
6
|
+
Tag.reset_column_information
|
7
|
+
Tag.all.each do |tag|
|
8
|
+
tag.visible = true
|
9
|
+
tag.save
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.down
|
14
|
+
remove_column :tags, :page_id
|
15
|
+
remove_column :tags, :visible
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Metaphones < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :tags, :metaphone, :string
|
4
|
+
add_column :tags, :metaphone_secondary, :string
|
5
|
+
Tag.reset_column_information
|
6
|
+
Tag.all.each do |tag|
|
7
|
+
tag.send :save # metaphone is calculated before_save
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
remove_column :tags, :metaphone
|
13
|
+
remove_column :tags, :metaphone_secondary
|
14
|
+
end
|
15
|
+
end
|
data/lib/taggable_admin_ui.rb
CHANGED
@@ -19,15 +19,15 @@ module TaggableAdminUI
|
|
19
19
|
returning OpenStruct.new do |tag|
|
20
20
|
tag.edit = Radiant::AdminUI::RegionSet.new do |edit|
|
21
21
|
edit.main.concat %w{edit_header edit_form}
|
22
|
-
edit.form.concat %w{edit_name edit_description}
|
22
|
+
edit.form.concat %w{edit_name edit_role edit_description}
|
23
23
|
edit.form_bottom.concat %w{edit_timestamp edit_buttons}
|
24
24
|
end
|
25
25
|
tag.show = Radiant::AdminUI::RegionSet.new do |show|
|
26
26
|
show.main.concat %w{show_header show_pages}
|
27
27
|
end
|
28
28
|
tag.index = Radiant::AdminUI::RegionSet.new do |index|
|
29
|
-
index.thead.concat %w{title_header description_header usage_header modify_header}
|
30
|
-
index.tbody.concat %w{title_cell description_cell usage_cell modify_cell}
|
29
|
+
index.thead.concat %w{title_header link_header description_header usage_header modify_header}
|
30
|
+
index.tbody.concat %w{title_cell link_cell description_cell usage_cell modify_cell}
|
31
31
|
index.bottom.concat %w{new_button}
|
32
32
|
end
|
33
33
|
tag.remove = tag.index
|
data/lib/taggable_model.rb
CHANGED
@@ -19,6 +19,15 @@ module TaggableModel # for inclusion into ActiveRecord::Base
|
|
19
19
|
has_many :taggings, :as => :tagged
|
20
20
|
has_many :attached_tags, :through => :taggings, :source => :tag # can't be just has_many :tags because that stomps on the radius tags in Page.
|
21
21
|
|
22
|
+
named_scope :from_tag, lambda { |tag|
|
23
|
+
tag = Tag.find_by_title(tag) unless tag.is_a? Tag
|
24
|
+
{
|
25
|
+
:joins => "INNER JOIN taggings as tt on tt.tagged_id = #{self.table_name}.id AND tt.tagged_type = '#{self.to_s}'",
|
26
|
+
:conditions => ["tt.tag_id = ?", tag.id],
|
27
|
+
:readonly => false
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
22
31
|
named_scope :from_tags, lambda { |tags|
|
23
32
|
{
|
24
33
|
:joins => "INNER JOIN taggings as tt on tt.tagged_id = #{self.table_name}.id AND tt.tagged_type = '#{self.to_s}'",
|
@@ -46,11 +55,9 @@ module TaggableModel # for inclusion into ActiveRecord::Base
|
|
46
55
|
end
|
47
56
|
end
|
48
57
|
|
49
|
-
#
|
50
|
-
#
|
51
|
-
|
52
|
-
# tag.models_count
|
53
|
-
Tag.define_class_retrieval_methods(self.to_s)
|
58
|
+
# creates eg. tag.pages, tag.assets
|
59
|
+
# (returning the from_tag scope defined above)
|
60
|
+
Tag.define_retrieval_methods(self.to_s)
|
54
61
|
|
55
62
|
class_eval {
|
56
63
|
extend TaggableModel::TaggableClassMethods
|
@@ -65,7 +72,9 @@ module TaggableModel # for inclusion into ActiveRecord::Base
|
|
65
72
|
|
66
73
|
module TaggableClassMethods
|
67
74
|
def tagged_with(somewords=[])
|
68
|
-
if somewords.is_a?(
|
75
|
+
if somewords.is_a?(Tag)
|
76
|
+
self.from_tag(somewords)
|
77
|
+
elsif somewords.is_a?(Array)
|
69
78
|
self.from_all_tags(somewords)
|
70
79
|
else
|
71
80
|
self.from_all_tags( Tag.from_list(somewords) )
|
data/lib/taggable_page.rb
CHANGED
@@ -4,8 +4,8 @@ module TaggablePage # for inclusion into Page
|
|
4
4
|
# because of the page tree
|
5
5
|
|
6
6
|
def self.included(base)
|
7
|
-
|
8
7
|
base.class_eval {
|
8
|
+
has_one :pointer, :class_name => 'Tag'
|
9
9
|
named_scope :children_of, lambda { |these|
|
10
10
|
{ :conditions => ["parent_id IN (#{these.map{'?'}.join(',')})", *these.map{|t| t.id}] }
|
11
11
|
}
|
@@ -19,6 +19,10 @@ module TaggablePage # for inclusion into Page
|
|
19
19
|
|
20
20
|
module InstanceMethods
|
21
21
|
|
22
|
+
def has_pointer?
|
23
|
+
!pointer.nil?
|
24
|
+
end
|
25
|
+
|
22
26
|
# note varying logic here: tag clouds are used differently when describing a group.
|
23
27
|
# if only one object is relevant, all of its tags will be equally (locally) important.
|
24
28
|
# Presumably that cloud should show global tag importance.
|
@@ -26,7 +30,7 @@ module TaggablePage # for inclusion into Page
|
|
26
30
|
# probably want to show local tag importance, ie prominence within that list.
|
27
31
|
|
28
32
|
def tags_for_cloud(limit=50, bands=6)
|
29
|
-
tags = Tag.attached_to(self.with_children).most_popular(limit)
|
33
|
+
tags = Tag.attached_to(self.with_children).visible.most_popular(limit)
|
30
34
|
Tag.sized(tags, bands)
|
31
35
|
end
|
32
36
|
|
data/lib/taggable_tags.rb
CHANGED
@@ -2,85 +2,76 @@ module TaggableTags
|
|
2
2
|
include Radiant::Taggable
|
3
3
|
|
4
4
|
class TagError < StandardError; end
|
5
|
-
|
6
|
-
|
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)
|
7
10
|
|
8
11
|
desc %{
|
9
|
-
|
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.
|
12
|
+
Contents are rendered only if tags are available to display.
|
22
13
|
|
23
|
-
*Usage:*
|
24
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>
|
25
19
|
}
|
26
20
|
tag 'if_tags' do |tag|
|
21
|
+
tag.locals.tags ||= _get_tags(tag)
|
27
22
|
tag.expand if tag.locals.tags && tag.locals.tags.any?
|
28
23
|
end
|
29
24
|
|
30
25
|
desc %{
|
31
|
-
Contents are rendered only if no
|
32
|
-
|
33
|
-
*Usage:*
|
34
|
-
<pre><code><r:unless_tags>...</r:unless_tags></code></pre>
|
26
|
+
Contents are rendered only if no tags are available.
|
27
|
+
Can also be nested inside a set-definition container tag.
|
35
28
|
}
|
36
29
|
tag 'unless_tags' do |tag|
|
30
|
+
tag.locals.tags ||= _get_tags(tag)
|
37
31
|
tag.expand unless tag.locals.tags && tag.locals.tags.any?
|
38
32
|
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
33
|
|
42
34
|
desc %{
|
43
|
-
|
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
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
And the output would be "Pages tagged with tag1, tag2 and tag3:".
|
48
|
+
desc %{
|
49
|
+
Displays a UL of the current list of tags.
|
50
|
+
Only works when nested within a set-defining tag.
|
49
51
|
}
|
50
|
-
tag
|
52
|
+
tag "tag_list" do |tag|
|
51
53
|
if tag.locals.tags && tag.locals.tags.any?
|
52
54
|
options = tag.attr.dup
|
53
|
-
|
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|
|
54
59
|
tag.locals.tag = t
|
55
|
-
tag.render('
|
56
|
-
|
60
|
+
result << %{<li>#{tag.render('tag_link', options)}</li>}
|
61
|
+
end
|
62
|
+
result << "</ul>"
|
63
|
+
result
|
57
64
|
else
|
58
|
-
"
|
65
|
+
"No tags"
|
59
66
|
end
|
60
67
|
end
|
61
68
|
|
62
69
|
desc %{
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
*Usage:*
|
67
|
-
<pre><code><r:tags:each tags="foo, bar">...</r:tags:each></code></pre>
|
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.
|
68
73
|
}
|
69
|
-
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|
|
74
|
+
tag "tag_cloud" do |tag|
|
84
75
|
if tag.locals.tags && tag.locals.tags.length > 1
|
85
76
|
options = tag.attr.dup
|
86
77
|
tag.locals.tags = Tag.for_cloud(tag.locals.tags).sort
|
@@ -88,7 +79,7 @@ module TaggableTags
|
|
88
79
|
result << %{<div class="cloud">}
|
89
80
|
tag.locals.tags.sort.each do |t|
|
90
81
|
tag.locals.tag = t
|
91
|
-
result << tag.render("
|
82
|
+
result << tag.render("tag_link", options.merge('style' => "font-size: #{t.cloud_size.to_f * 2.5}em;"))
|
92
83
|
end
|
93
84
|
result << "</div>"
|
94
85
|
result.join(" ")
|
@@ -96,28 +87,75 @@ module TaggableTags
|
|
96
87
|
"No tags"
|
97
88
|
end
|
98
89
|
end
|
99
|
-
|
100
|
-
|
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|
|
101
96
|
if tag.locals.tags && tag.locals.tags.any?
|
102
97
|
options = tag.attr.dup
|
103
|
-
|
104
|
-
listclass = options.delete('listclass') || 'taglist'
|
105
|
-
result = %{<ul class="#{listclass}">}
|
106
|
-
tag.locals.tags.each do |t|
|
98
|
+
tag.locals.tags.map { |t|
|
107
99
|
tag.locals.tag = t
|
108
|
-
|
109
|
-
|
110
|
-
result << "</ul>"
|
111
|
-
result
|
100
|
+
tag.render('tag:title', options)
|
101
|
+
}.to_sentence
|
112
102
|
else
|
113
|
-
"
|
103
|
+
"no tags"
|
114
104
|
end
|
115
105
|
end
|
116
106
|
|
117
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
|
+
|
118
111
|
|
119
|
-
|
120
|
-
|
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
|
121
159
|
|
122
160
|
desc %{
|
123
161
|
Returns a tag-cloud showing all the tags attached to this page and its descendants,
|
@@ -141,9 +179,9 @@ module TaggableTags
|
|
141
179
|
|
142
180
|
As usual you can limit the size of the cloud (the most popular will be shown) and set the destination of tag links:
|
143
181
|
|
144
|
-
<pre><code><r:
|
182
|
+
<pre><code><r:tags:cloud limit="200" linkto="/archive" /></code></pre>
|
145
183
|
}
|
146
|
-
tag '
|
184
|
+
tag 'tags:cloud' do |tag|
|
147
185
|
options = tag.attr.dup
|
148
186
|
limit = options.delete('limit')
|
149
187
|
if url = options.delete('url')
|
@@ -153,12 +191,12 @@ module TaggableTags
|
|
153
191
|
end
|
154
192
|
raise TagError, "no page for tag_cloud" unless tag.locals.page
|
155
193
|
tag.locals.tags = tag.locals.page.tags_for_cloud(limit).sort # page.tags_for_cloud does a lot of inheritance work
|
156
|
-
tag.render('
|
194
|
+
tag.render('tag_cloud', options)
|
157
195
|
end
|
158
196
|
|
159
197
|
desc %{
|
160
198
|
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
|
199
|
+
as the tag cloud without the band formatting.
|
162
200
|
|
163
201
|
*Usage:*
|
164
202
|
<pre><code><r:tag_list /></code></pre>
|
@@ -167,7 +205,7 @@ module TaggableTags
|
|
167
205
|
|
168
206
|
<pre><code><r:tag_list limit="200" linkto="/archive" /></code></pre>
|
169
207
|
}
|
170
|
-
tag '
|
208
|
+
tag 'tags:list' do |tag|
|
171
209
|
options = tag.attr.dup
|
172
210
|
limit = options.delete('limit')
|
173
211
|
if url = options.delete('url')
|
@@ -182,20 +220,21 @@ module TaggableTags
|
|
182
220
|
|
183
221
|
|
184
222
|
|
185
|
-
################# tagged pages. Other extensions define similar tags for eg tagged assets.
|
186
223
|
|
187
|
-
# general purpose pages lister
|
188
224
|
|
189
|
-
|
190
|
-
|
191
|
-
|
225
|
+
|
226
|
+
################# tagged pages. Other extensions define similar tags for eg tagged assets.
|
227
|
+
|
192
228
|
tag 'page_list' do |tag|
|
193
229
|
raise TagError, "no pages for page_list" unless tag.locals.pages
|
194
230
|
result = []
|
195
|
-
|
196
|
-
|
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
|
197
236
|
result << tag.expand
|
198
|
-
end
|
237
|
+
end
|
199
238
|
result
|
200
239
|
end
|
201
240
|
|
@@ -203,23 +242,27 @@ module TaggableTags
|
|
203
242
|
Lists all the pages associated with a set of tags, in descending order of relatedness.
|
204
243
|
|
205
244
|
*Usage:*
|
206
|
-
<pre><code><r:
|
245
|
+
<pre><code><r:tagged_pages:each>...</r:tags:pages:each></code></pre>
|
207
246
|
}
|
208
|
-
tag '
|
247
|
+
tag 'tagged_pages' do |tag|
|
209
248
|
tag.locals.pages = Page.from_tags(tag.locals.tags)
|
210
249
|
tag.expand
|
211
250
|
end
|
212
|
-
|
213
|
-
|
251
|
+
|
252
|
+
tag 'tagged_pages:each' do |tag|
|
253
|
+
tag.render('page_list', tag.attr.dup, &tag.block)
|
214
254
|
end
|
215
255
|
|
216
256
|
desc %{
|
217
257
|
Renders the contained elements only if there are any pages associated with the current set of tags.
|
218
258
|
|
219
|
-
|
220
|
-
|
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>
|
221
264
|
}
|
222
|
-
tag "
|
265
|
+
tag "if_tagged_pages" do |tag|
|
223
266
|
tag.locals.pages = Page.from_tags(tag.locals.tags)
|
224
267
|
tag.expand if tag.locals.pages.to_a.any?
|
225
268
|
end
|
@@ -228,7 +271,7 @@ module TaggableTags
|
|
228
271
|
Renders the contained elements only if there are no pages associated with the current set of tags.
|
229
272
|
|
230
273
|
*Usage:*
|
231
|
-
<pre><code><r:
|
274
|
+
<pre><code><r:unless_tagged_pages>...</r:unless_tagged_pages></code></pre>
|
232
275
|
}
|
233
276
|
tag "tags:unless_pages" do |tag|
|
234
277
|
tag.locals.pages = Page.from_tags(tag.locals.tags)
|
@@ -244,15 +287,13 @@ module TaggableTags
|
|
244
287
|
<pre><code><r:related_pages:each>...</r:related_pages:each></code></pre>
|
245
288
|
}
|
246
289
|
tag 'related_pages' do |tag|
|
247
|
-
raise TagError, "page must be defined for related_pages tag" unless tag.locals.page
|
248
290
|
tag.locals.pages = tag.locals.page.related_pages
|
249
291
|
tag.expand
|
250
292
|
end
|
251
293
|
tag 'related_pages:each' do |tag|
|
252
|
-
tag.render('
|
294
|
+
tag.render('page_list', tag.attr.dup, &tag.block)
|
253
295
|
end
|
254
296
|
|
255
|
-
|
256
297
|
desc %{
|
257
298
|
Shows a link to the target page with a (non-linked) breadcrumb trail to give it context.
|
258
299
|
This is the opposite of r:breadcrumbs, which shows a linked trail but doesn't link the current page.
|
@@ -279,6 +320,18 @@ module TaggableTags
|
|
279
320
|
breadcrumbs.join(separator)
|
280
321
|
end
|
281
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
|
+
|
282
335
|
|
283
336
|
|
284
337
|
################# single tag expansion for simple lists of tagged items or for customised display of each item in a list or cloud context
|
@@ -326,10 +379,23 @@ module TaggableTags
|
|
326
379
|
<pre><code><r:tag:name /></code></pre>
|
327
380
|
}
|
328
381
|
tag 'tag:name' do |tag|
|
329
|
-
raise TagError, "tag must be defined for tag:
|
382
|
+
raise TagError, "tag must be defined for tag:name tag" unless tag.locals.tag
|
330
383
|
tag.locals.tag.title
|
331
384
|
end
|
332
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
|
+
|
333
399
|
desc %{
|
334
400
|
Makes a link to the current tag. If the current page is a library page, we amend the
|
335
401
|
list of requested tags. Otherwise, the 'linkto' parameter can be the address of a
|
@@ -338,10 +404,10 @@ module TaggableTags
|
|
338
404
|
If no destination is specified we return a relative link to the escaped name of the tag.
|
339
405
|
|
340
406
|
*Usage:*
|
341
|
-
<pre><code><r:
|
407
|
+
<pre><code><r:tag_link linkto='/library' /></code></pre>
|
342
408
|
}
|
343
|
-
tag '
|
344
|
-
raise TagError, "tag must be defined for
|
409
|
+
tag 'tag_link' do |tag|
|
410
|
+
raise TagError, "tag must be defined for tag_link tag" unless tag.locals.tag
|
345
411
|
options = tag.attr.dup
|
346
412
|
anchor = options['anchor'] ? "##{options.delete('anchor')}" : ''
|
347
413
|
attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
|
@@ -415,20 +481,26 @@ module TaggableTags
|
|
415
481
|
end
|
416
482
|
tag 'tag:pages:each' do |tag|
|
417
483
|
result = []
|
418
|
-
|
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|
|
419
490
|
tag.locals.page = page
|
420
491
|
result << tag.expand
|
421
|
-
end
|
492
|
+
end
|
422
493
|
result
|
423
494
|
end
|
424
495
|
|
425
496
|
|
426
|
-
|
427
497
|
private
|
428
498
|
|
429
499
|
def _get_tag(tag, options)
|
430
500
|
if title = options.delete('title')
|
431
501
|
tag.locals.tag ||= Tag.find_by_title(title)
|
502
|
+
elsif id = options.delete('id')
|
503
|
+
tag.locals.tag ||= Tag.find_by_id(id)
|
432
504
|
end
|
433
505
|
if tag.locals.page.respond_to? :requested_tags
|
434
506
|
tag.locals.tag ||= tag.locals.page.requested_tags.first
|
@@ -441,16 +513,17 @@ private
|
|
441
513
|
# but change is likely here and anything not documented shouldn't be relied upon.
|
442
514
|
|
443
515
|
def _get_tags(tag)
|
516
|
+
Rails.logger.warn "<< _get_tags"
|
444
517
|
tags = if tag.attr['tags'] && !tag.attr['tags'].blank?
|
445
518
|
Tag.from_list(tag.attr['tags'], false) # false parameter -> not to create missing tags
|
446
519
|
elsif tag.locals.page.respond_to?(:requested_tags)
|
447
520
|
tag.locals.page.requested_tags
|
448
521
|
elsif tag.locals.page
|
449
|
-
tag.locals.page.attached_tags
|
522
|
+
tag.locals.page.attached_tags.visible
|
450
523
|
else
|
451
524
|
[]
|
452
525
|
end
|
453
|
-
tags = tags.uniq.
|
526
|
+
tag.locals.tags = tags.uniq.compact
|
454
527
|
end
|
455
528
|
|
456
529
|
end
|