radiant-taggable-extension 2.0.0.rc2 → 2.0.0

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.
data/README.md CHANGED
@@ -10,26 +10,33 @@ This extension differs from `tags` in a few ways that matter to me but may not t
10
10
 
11
11
  * We're not so focused on tag clouds - though you can still make them - but more on archival and linking functions.
12
12
  * It provides faceted search of any tagged class.
13
- * We subvert the keywords mechanism on pages rather than adding another one. I may change this soon to play more nicely with page fields.
13
+ * We subvert the keywords mechanism on pages rather than adding another one. I am likely to change this soon to play more nicely with page fields.
14
14
  * The tag-choosing and tag-removal interface is (about to be) quite nice.
15
15
  * It's editorially versatile: tags can be used as page pointers and their visibility is controllable
16
- * Anything can be tagged. By default we only do pages but other extensions can participate with a single line in a model class. See the [taggable_events](https://github.com/spanner/radiant-taggable_events-extension) extension for a minimal example or just put `has_tags` at the top of a model class.
16
+ * Anything can be tagged. By default we only do pages and assets but other extensions can participate with a single line in a model class. See the [taggable_events](https://github.com/spanner/radiant-taggable_events-extension) extension for a minimal example or just put `has_tags` at the top of a model class.
17
17
  * We don't use `has_many_polymorphs` (it burns!)
18
18
  * Or any of the tagging libraries: it only takes a few scopes
19
+ * Because the library is entirely scope-based it's easy to add more retrieval filters. Want a tagged and faceted googlemap of your calendar events? `event_calendar` + `event_map` * `taggable` + `taggable_events`.
19
20
 
20
- When you first install the extension you shouldn't see much difference: all we do out of the box is to take over (and make more prominent) the keywords field in the page-edit view.
21
+ When you first install the extension you shouldn't see much difference: all we do out of the box is to take over (and make more prominent) the keywords field in the page and asset editing views.
21
22
 
22
- ## New
23
+ ## Compatibility
23
24
 
24
- * API change: `has_tags` instead of `is_taggable`.
25
+ Versions 2.x of taggable are meant for use with radiant 1. They expect to be included in your application as a bundled gem. There is a '0.9.1' tag in the repository for the latest version compatible with older versions of radiant.
25
26
 
26
- * The library extension has been reincorporated into taggable, since radiant 1 has assets. Out of the box you get tags, clouds and faceting of both pages and assets. It should work with 0.9.1 too but you will need paperclipped.
27
+ ## Installation
28
+
29
+ Install the gem:
30
+
31
+ sudo gem install radiant-taggable-extension
32
+
33
+ and add it to your application's Gemfile:
27
34
 
28
- * The long-promised tag-suggester is there in a useable though slightly basic form.
35
+ gem radiant-taggable-extension, '~>2.0.0'
29
36
 
30
37
  ## Status
31
38
 
32
- Apart from any crumpling caused by the recent reincorporation of Library this is all mature code that has been in use for years.
39
+ Apart from any crumpling caused by the recent re-incorporation of Library and all its asset tags, this is all mature code that has been in use for years.
33
40
 
34
41
  ## Efficiency
35
42
 
@@ -51,11 +58,11 @@ The **LibraryPage** page type is a handy cache-friendly way of catching tag para
51
58
 
52
59
  /archive/lasagne/chips/pudding
53
60
 
54
- and the right tags will be retrieved, if they exist.
61
+ The right tags will be retrieved, if they exist, and with the radius tags below they can be used to populate the page.
55
62
 
56
63
  ## Radius tags
57
64
 
58
- This extension creates a great many radius tags. There are several kinds:
65
+ This extension creates a great many radius tags but in an orderly way. There are four kinds:
59
66
 
60
67
  ### Tag information
61
68
 
@@ -168,26 +175,6 @@ Seek venture capital immediately.
168
175
  <r:assets:image size="standard" />
169
176
  <p class="caption"><r:assets:caption /></p>
170
177
  </r:related_images:each>
171
-
172
- ## Requirements
173
-
174
- * Radiant 1 or radiant 0.9.x with the paperclipped extension.
175
-
176
- Radiant 1 is strongly recommended.
177
-
178
- ## Installation
179
-
180
- As usual:
181
-
182
- git clone git://github.com/spanner/radiant-taggable-extension.git vendor/extensions/taggable
183
- rake radiant:extensions:taggable:migrate
184
- rake radiant:extensions:taggable:update
185
-
186
- The update task will bring over a couple of CSS files for styling tags but you'll want to improve those.
187
-
188
- ## Bugs
189
-
190
- Quite likely. [Github issues](http://github.com/spanner/radiant-taggable-extension/issues), please, or for little things an email or github message is fine.
191
178
 
192
179
  ## Author and copyright
193
180
 
@@ -1,21 +1,22 @@
1
+ require 'sanitize'
2
+
1
3
  module TaggableHelper
2
4
 
3
5
  def clean_html(text)
4
6
  Sanitize.clean(text, Sanitize::Config::RELAXED)
5
7
  end
6
8
 
7
- def strip_html(text)
9
+ def scrub_html(text)
8
10
  Sanitize.clean(text)
9
11
  end
10
12
 
11
13
  def truncate_words(text='', options={})
12
14
  return '' if text.blank?
13
- ellipsis = options[:ellipsis] || '&hellip;'
14
- limit = (options[:limit] || 64).to_i
15
- text = strip_html(text) if options[:strip]
15
+ options.reverse_merge!(:length => 30, :omission => '&hellip;')
16
16
  words = text.split
17
- ellipsis = '' unless words.size > limit
18
- words[0..(limit-1)].join(" ") + ellipsis
17
+ length = options[:length].to_i
18
+ options[:omission] = '' unless words.size > length
19
+ words[0..(length-1)].join(" ") + options[:omission]
19
20
  end
20
21
 
21
22
  def available_pointer_pages()
data/app/models/tag.rb CHANGED
@@ -102,6 +102,23 @@ class Tag < ActiveRecord::Base
102
102
  }
103
103
  }
104
104
 
105
+ # returns all the tags that have been applied alongside any of these tags: that is, the
106
+ # set of tags that if applied will reduce further a set of tagged objects.
107
+
108
+ named_scope :coincident_with, lambda { |tags|
109
+ tag_ids = tags.map(&:id).join(',')
110
+ {
111
+ :select => "your_tags.*, COUNT(your_tags.id) AS use_count",
112
+ :joins => %{
113
+ INNER JOIN taggings AS my_taggings ON my_taggings.tag_id = tags.id
114
+ INNER JOIN taggings AS your_taggings ON my_taggings.tagged_type = your_taggings.tagged_type AND my_taggings.tagged_id = your_taggings.tagged_id
115
+ INNER JOIN tags AS your_tags ON your_taggings.tag_id = your_tags.id
116
+ },
117
+ :conditions => "tags.id IN (#{tag_ids}) AND NOT your_tags.id IN (#{tag_ids})",
118
+ :group => "your_tags.id"
119
+ }
120
+ }
121
+
105
122
  def <=>(othertag)
106
123
  String.natcmp(self.title, othertag.title) # natural sort method defined in lib/natcomp.rb
107
124
  end
@@ -152,27 +169,9 @@ class Tag < ActiveRecord::Base
152
169
  # Returns a list of all the tags that have been applied alongside this one.
153
170
 
154
171
  def coincident_tags
155
- tags = []
156
- self.tagged.each do |t|
157
- tags += t.attached_tags if t
158
- end
159
- tags.uniq - [self]
172
+ self.class.coincident_with(self)
160
173
  end
161
-
162
- # Returns a list of all the tags that have been applied alongside _all_ of the supplied tags.
163
- # used to offer reductive facets on library pages
164
- # not very efficient at the moment, largely thanks to polymorphic tagging relationship
165
- # TODO: omit tags with no reductive power (ie those applied to all the tagged items)
166
-
167
- def self.coincident_with(tags)
168
- related_tags = []
169
- tagged = Tagging.with_all_of_these(tags).map(&:tagged)
170
- tagged.each do |t|
171
- related_tags += t.attached_tags if t
172
- end
173
- related_tags.uniq - tags
174
- end
175
-
174
+
176
175
  # returns true if tags are site-scoped
177
176
 
178
177
  def self.sited?
@@ -1,5 +1,5 @@
1
1
  module RadiantTaggableExtension
2
- VERSION = '2.0.0.rc2'
2
+ VERSION = '2.0.0'
3
3
  SUMMARY = %q{Tagging, clouding and faceting extension for Radiant CMS}
4
4
  DESCRIPTION = %q{General purpose tagging and retrieval extension: more versatile but less focused than the tags extension. A good way to support faceted search.}
5
5
  URL = "http://spanner.org/radiant/taggable"
@@ -174,11 +174,11 @@ module Radius
174
174
  </code></pre>
175
175
  }
176
176
  tag "library:assets" do |tag|
177
- tag.locals.assets = _get_assets(tag)
178
177
  tag.expand
179
178
  end
180
179
  tag "library:assets:each" do |tag|
181
- tag.render('asset_list', tag.attr.dup, &tag.block) # r:page_list is defined in spanner's paperclipped
180
+ tag.locals.assets = _get_assets(tag)
181
+ tag.render('asset_list', tag.attr.dup, &tag.block)
182
182
  end
183
183
 
184
184
  desc %{
@@ -206,10 +206,10 @@ module Radius
206
206
  </code></pre>
207
207
  }
208
208
  tag "library:#{these}" do |tag|
209
- tag.locals.assets = _get_assets(tag).send(these.intern)
210
209
  tag.expand
211
210
  end
212
211
  tag "library:#{these}:each" do |tag|
212
+ tag.locals.assets = _get_assets(tag).send(these.to_sym)
213
213
  tag.render('asset_list', tag.attr.dup, &tag.block)
214
214
  end
215
215
 
@@ -222,166 +222,132 @@ module Radius
222
222
  </code></pre>
223
223
  }
224
224
  tag "library:if_#{these}" do |tag|
225
- tag.locals.assets = _get_assets(tag).send(these.intern)
225
+ tag.locals.assets = _get_assets(tag).send(these.to_sym)
226
226
  tag.expand if tag.locals.assets.any?
227
227
  end
228
+ end
228
229
 
229
- ############### tags:* tags that only make sense on library pages
230
+ ############### extra tags:* tags that only make sense on library pages
230
231
 
231
- desc %{
232
- Summarises in a sentence the list of tags currently active, with each one presented as a defaceting link.
233
- }
234
- tag 'tags:unlink_list' do |tag|
235
- requested = _get_requested_tags(tag)
236
- if requested.any?
237
- requested.map { |t|
238
- tag.locals.tag = t
239
- tag.render('tag:unlink', tag.attr.dup)
240
- }.to_sentence
241
- else
242
- ""
243
- end
232
+ desc %{
233
+ Summarises in a sentence the list of tags currently active, with each one presented as a defaceting link.
234
+ }
235
+ tag 'tags:unlink_list' do |tag|
236
+ requested = _get_requested_tags(tag)
237
+ if requested.any?
238
+ requested.map { |t|
239
+ tag.locals.tag = t
240
+ tag.render('tag:unlink', tag.attr.dup)
241
+ }.to_sentence
242
+ else
243
+ ""
244
244
  end
245
+ end
245
246
 
246
- desc %{
247
- Makes a link that removes the current tag from the active set. Other options as for tag:link.
248
-
249
- *Usage:*
250
- <pre><code><r:tag:unlink linkto='/library' /></code></pre>
251
- }
252
- tag 'tag:unlink' do |tag|
253
- raise TagError, "tag must be defined for tag:unlink tag" unless tag.locals.tag
254
- options = tag.attr.dup
255
- options['class'] ||= 'detag'
256
- anchor = options['anchor'] ? "##{options.delete('anchor')}" : ''
257
- attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
258
- attributes = " #{attributes}" unless attributes.empty?
259
- text = tag.double? ? tag.expand : tag.render('tag:name')
260
-
261
- if tag.locals.page.is_a?(LibraryPage)
262
- href = tag.locals.page.url(tag.locals.page.requested_tags - [tag.locals.tag])
263
- elsif page_url = (options.delete('tagpage') || Radiant::Config['tags.page'])
264
- href = clean_url(page_url + '/-' + tag.locals.tag.clean_title)
265
- else
266
- href ||= Rack::Utils.escape("-#{tag.locals.tag.title}") + '/'
267
- end
247
+ desc %{
248
+ Makes a link that removes the current tag from the active set. Other options as for tag:link.
268
249
 
269
- %{<a href="#{href}#{anchor}"#{attributes}>#{text}</a>}
250
+ *Usage:*
251
+ <pre><code><r:tag:unlink linkto='/library' /></code></pre>
252
+ }
253
+ tag 'tag:unlink' do |tag|
254
+ raise TagError, "tag must be defined for tag:unlink tag" unless tag.locals.tag
255
+ options = tag.attr.dup
256
+ options['class'] ||= 'detag'
257
+ anchor = options['anchor'] ? "##{options.delete('anchor')}" : ''
258
+ attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
259
+ attributes = " #{attributes}" unless attributes.empty?
260
+ text = tag.double? ? tag.expand : tag.render('tag:name')
261
+
262
+ if tag.locals.page.is_a?(LibraryPage)
263
+ href = tag.locals.page.url(tag.locals.page.requested_tags - [tag.locals.tag])
264
+ elsif page_url = (options.delete('tagpage') || Radiant::Config['tags.page'])
265
+ href = clean_url(page_url + '/-' + tag.locals.tag.clean_title)
266
+ else
267
+ href ||= Rack::Utils.escape("-#{tag.locals.tag.title}") + '/'
270
268
  end
271
269
 
270
+ %{<a href="#{href}#{anchor}"#{attributes}>#{text}</a>}
271
+ end
272
272
 
273
- ############### libraryish utility tags that don't really belong here
273
+ private
274
274
 
275
- desc %{
276
- Truncates the contained text to the specified number of words. Attributes:
277
- * `limit` sets the number of words shown. Default is 64.
278
- * `ellipsis` is the suffix used to indicate truncation. Default is '&hellip;'
279
- * `strip="true"` will cause all html tags to be stripped from the contained text before it is truncated. Default is false.
280
- }
281
- tag "truncate" do |tag|
282
- # truncate_words is in LibraryHelper
283
- truncate_words tag.expand, :limit => tag.attr['limit'], :ellipsis => tag.attr['ellipsis'], :strip => tag.attr['strip'] == 'true'
284
- end
275
+ def _get_requested_tags(tag)
276
+ tag.locals.page.requested_tags
277
+ end
285
278
 
286
- desc %{
287
- Strips all html tags from the contained text, leaving the text itself unchanged.
288
- Useful when, for example, using a page part to populate a meta tag.
289
- }
290
- tag "strip" do |tag|
291
- # strip_html is in LibraryHelper
292
- strip_html tag.expand
279
+ def _get_coincident_tags(tag)
280
+ requested = _get_requested_tags(tag)
281
+ limit = tag.attr['limit'] || 50
282
+ if requested.any?
283
+ Tag.coincident_with(requested)
284
+ else
285
+ Tag.most_popular(limit)
293
286
  end
287
+ end
294
288
 
295
- desc %{
296
- Removes all unsafe html tags and attributes from the enclosed text, protecting from cross-site scripting attacks while leaving the text intact.
289
+ # a bit of extra logic so that in the absence of any requested tags we default to all, not none
290
+
291
+ def _default_library_find_options
292
+ {
293
+ :by => 'created_at',
294
+ :order => 'desc'
297
295
  }
298
- tag "clean" do |tag|
299
- # clean_html is in LibraryHelper
300
- clean_html tag.expand
301
- end
302
-
303
-
296
+ end
297
+
298
+ def _get_pages(tag)
299
+ options = children_find_options(tag)
300
+ requested = _get_requested_tags(tag)
301
+ pages = Page.scoped(options)
302
+ pages = pages.tagged_with(requested) if requested.any?
303
+ pages
304
+ end
304
305
 
305
- private
306
+ def _get_assets(tag)
307
+ options = asset_find_options(tag)
308
+ requested = _get_requested_tags(tag)
309
+ assets = Asset.scoped(options)
310
+ assets = assets.tagged_with(requested) if requested.any?
311
+ assets
312
+ end
313
+
314
+ # duplicate of children_find_options except:
315
+ # no virtual or status options
316
+ # defaults to chronological descending
317
+
318
+ def asset_find_options(tag)
319
+ attr = tag.attr.symbolize_keys
306
320
 
307
- def _get_requested_tags(tag)
308
- tag.locals.page.requested_tags
309
- end
321
+ options = {}
310
322
 
311
- def _get_coincident_tags(tag)
312
- requested = _get_requested_tags(tag)
313
- limit = tag.attr['limit'] || 50
314
- if requested.any?
315
- Tag.coincident_with(requested)
323
+ [:limit, :offset].each do |symbol|
324
+ if number = attr[symbol]
325
+ if number =~ /^\d{1,4}$/
326
+ options[symbol] = number.to_i
316
327
  else
317
- Tag.most_popular(limit)
328
+ raise TagError.new("`#{symbol}' attribute of `each' tag must be a positive number between 1 and 4 digits")
318
329
  end
319
330
  end
320
331
  end
321
332
 
322
- # a bit of extra logic so that in the absence of any requested tags we default to all, not none
323
-
324
- def _default_library_find_options
325
- {
326
- :by => 'created_at',
327
- :order => 'desc'
328
- }
329
- end
330
-
331
- def _get_pages(tag)
332
- options = children_find_options(tag)
333
- requested = _get_requested_tags(tag)
334
- pages = Page.scoped(options)
335
- pages = pages.tagged_with(requested) if requested.any?
336
- pages
337
- end
338
-
339
- def _get_assets(tag)
340
- options = asset_find_options(tag)
341
- requested = _get_requested_tags(tag)
342
- assets = Asset.scoped(options)
343
- assets = assets.tagged_with(requested) if requested.any?
344
- assets
333
+ by = (attr[:by] || 'created_at').strip
334
+ order = (attr[:order] || 'desc').strip
335
+ order_string = ''
336
+ if self.attributes.keys.include?(by)
337
+ order_string << by
338
+ else
339
+ raise TagError.new("`by' attribute of `each' tag must be set to a valid field name")
345
340
  end
346
-
347
- # duplicate of children_find_options except:
348
- # no virtual or status options
349
- # defaults to chronological descending
350
-
351
- def asset_find_options(tag)
352
- attr = tag.attr.symbolize_keys
353
-
354
- options = {}
355
-
356
- [:limit, :offset].each do |symbol|
357
- if number = attr[symbol]
358
- if number =~ /^\d{1,4}$/
359
- options[symbol] = number.to_i
360
- else
361
- raise TagError.new("`#{symbol}' attribute of `each' tag must be a positive number between 1 and 4 digits")
362
- end
363
- end
364
- end
365
-
366
- by = (attr[:by] || 'created_at').strip
367
- order = (attr[:order] || 'desc').strip
368
- order_string = ''
369
- if self.attributes.keys.include?(by)
370
- order_string << by
371
- else
372
- raise TagError.new("`by' attribute of `each' tag must be set to a valid field name")
373
- end
374
- if order =~ /^(asc|desc)$/i
375
- order_string << " #{$1.upcase}"
376
- else
377
- raise TagError.new(%{`order' attribute of `each' tag must be set to either "asc" or "desc"})
378
- end
379
- options[:order] = order_string
380
- options
341
+ if order =~ /^(asc|desc)$/i
342
+ order_string << " #{$1.upcase}"
343
+ else
344
+ raise TagError.new(%{`order' attribute of `each' tag must be set to either "asc" or "desc"})
381
345
  end
382
-
346
+ options[:order] = order_string
347
+ options
383
348
  end
384
349
 
350
+ end
385
351
  end
386
352
 
387
353
 
@@ -1,7 +1,8 @@
1
1
  module Radius
2
2
  module TaggableTags
3
3
  include Radiant::Taggable
4
-
4
+ include TaggableHelper
5
+
5
6
  class TagError < StandardError; end
6
7
 
7
8
  ################# general purpose lister utilities and dryers-out
@@ -609,7 +610,52 @@ module Radius
609
610
  tag.expand unless tag.locals.assets.any?
610
611
  end
611
612
 
613
+ ############### libraryish utility tags that don't really belong here
614
+ # btw. the truncation tags are duplicated from the reader extension, which may
615
+ # or may not be installed here. I'll move them into radiant proper in the end
612
616
 
617
+ desc %{
618
+ Truncates the contained text or html to the specified length. Unless you supply a
619
+ html="true" parameter, all html tags will be removed before truncation. You probably
620
+ don't want to do that: open tags will not be closed and the truncated
621
+ text length will vary.
622
+
623
+ <pre><code>
624
+ <r:truncated words="30"><r:content part="body" /></r:truncated>
625
+ <r:truncated chars="100" omission=" (continued)"><r:post:body /></r:truncated>
626
+ <r:truncated words="100" allow_html="true"><r:reader:description /></r:truncated>
627
+ </code></pre>
628
+ }
629
+ tag "truncated" do |tag|
630
+ content = tag.expand
631
+ tag.attr['words'] ||= tag.attr['length']
632
+ omission = tag.attr['omission'] || '&hellip;'
633
+ content = scrub_html(content) unless tag.attr['allow_html'] == 'true'
634
+ if tag.attr['chars']
635
+ truncate(content, :length => tag.attr['chars'].to_i, :omission => omission)
636
+ else
637
+ truncate_words(content, :length => tag.attr['words'].to_i, :omission => omission) # defined in TaggableHelper
638
+ end
639
+ end
640
+
641
+ deprecated_tag "truncate", :substitute => "truncated"
642
+
643
+ desc %{
644
+ Strips all html tags from the contained text, leaving the text itself unchanged.
645
+ Useful when, for example, using a page part to populate a meta tag.
646
+ }
647
+ tag "strip" do |tag|
648
+ # strip_html is in TaggableHelper
649
+ scrub_html tag.expand
650
+ end
651
+
652
+ desc %{
653
+ Removes all unsafe html tags and attributes from the enclosed text, protecting from cross-site scripting attacks while leaving the text intact.
654
+ }
655
+ tag "clean" do |tag|
656
+ # clean_html is in TaggableHelper
657
+ clean_html tag.expand
658
+ end
613
659
 
614
660
  private
615
661
 
@@ -642,7 +688,6 @@ module Radius
642
688
  tag.locals.tags = tags.uniq.compact
643
689
  end
644
690
 
645
-
646
691
  def _asset_finder(tag)
647
692
  if (tag.locals.tags)
648
693
  Asset.from_all_tags(tag.locals.tags).not_furniture
@@ -7,12 +7,15 @@ module Taggable
7
7
  attr_accessor :tag
8
8
  alias_method :tags, :tag
9
9
 
10
- def load_default_regions_with_tags
11
- load_default_regions_without_tags
10
+ def load_taggable_regions
12
11
  @tag = load_default_tag_regions
13
12
  end
14
-
15
- alias_method_chain :load_default_regions, :tags
13
+
14
+ # def load_default_regions_with_tags
15
+ # load_default_regions_without_tags
16
+ # load_taggable_regions
17
+ # end
18
+ # alias_method_chain :load_default_regions, :tags
16
19
 
17
20
  protected
18
21
 
@@ -35,9 +38,8 @@ module Taggable
35
38
  tag.new = tag.edit
36
39
  end
37
40
  end
38
-
41
+
39
42
  end
40
43
  end
41
44
  end
42
-
43
45
  end
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.homepage = RadiantTaggableExtension::URL
12
12
  s.summary = RadiantTaggableExtension::SUMMARY
13
13
  s.description = RadiantTaggableExtension::DESCRIPTION
14
+ s.add_dependency 'sanitize', "~> 2.0.1"
14
15
 
15
16
  ignores = if File.exist?('.gitignore')
16
17
  File.read('.gitignore').split("\n").inject([]) {|a,p| a + Dir[p] }
@@ -23,9 +24,9 @@ Gem::Specification.new do |s|
23
24
  s.require_paths = ["lib"]
24
25
 
25
26
  s.post_install_message = %{
26
- Add this to your radiant project with:
27
+ Add this to your Gemfile with:
27
28
 
28
- config.gem 'radiant-taggable-extension', :version => '~> #{RadiantTaggableExtension::VERSION}'
29
+ gem 'radiant-taggable-extension', '~> #{RadiantTaggableExtension::VERSION}'
29
30
 
30
31
  }
31
32
  end
@@ -48,6 +48,9 @@ describe Tag do
48
48
  it "should return its list of pages" do
49
49
  @tag.pages.should == [pages(:first)]
50
50
  end
51
+ end
52
+
53
+ describe "coinciding" do
51
54
 
52
55
  end
53
56
  end
@@ -5,7 +5,7 @@ class TaggableExtension < Radiant::Extension
5
5
  version RadiantTaggableExtension::VERSION
6
6
  description RadiantTaggableExtension::DESCRIPTION
7
7
  url RadiantTaggableExtension::URL
8
-
8
+
9
9
  def activate
10
10
  require 'natcmp' # a natural sort algorithm. possibly not that efficient.
11
11
  ActiveRecord::Base.send :include, Taggable::Model # provide has_tags for everything but don't call it for anything
@@ -20,7 +20,7 @@ class TaggableExtension < Radiant::Extension
20
20
 
21
21
  unless defined? admin.tag
22
22
  Radiant::AdminUI.send :include, Taggable::AdminUI
23
- admin.tag = Radiant::AdminUI.load_default_tag_regions
23
+ Radiant::AdminUI.load_taggable_regions
24
24
  end
25
25
 
26
26
  tab("Content") do
metadata CHANGED
@@ -1,15 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radiant-taggable-extension
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15424081
5
- prerelease: 6
4
+ hash: 15
5
+ prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
9
  - 0
10
- - rc
11
- - 2
12
- version: 2.0.0.rc2
10
+ version: 2.0.0
13
11
  platform: ruby
14
12
  authors:
15
13
  - William Ross
@@ -17,9 +15,25 @@ autorequire:
17
15
  bindir: bin
18
16
  cert_chain: []
19
17
 
20
- date: 2011-07-05 00:00:00 Z
21
- dependencies: []
22
-
18
+ date: 2011-09-06 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: sanitize
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 2
32
+ - 0
33
+ - 1
34
+ version: 2.0.1
35
+ type: :runtime
36
+ version_requirements: *id001
23
37
  description: "General purpose tagging and retrieval extension: more versatile but less focused than the tags extension. A good way to support faceted search."
24
38
  email:
25
39
  - radiant@spanner.org
@@ -86,10 +100,11 @@ files:
86
100
  - spec/spec.opts
87
101
  - spec/spec_helper.rb
88
102
  - taggable_extension.rb
103
+ has_rdoc: true
89
104
  homepage: http://spanner.org/radiant/taggable
90
105
  licenses: []
91
106
 
92
- post_install_message: "\n Add this to your radiant project with:\n\n config.gem 'radiant-taggable-extension', :version => '~> 2.0.0.rc2'\n\n "
107
+ post_install_message: "\n Add this to your Gemfile with:\n\n gem 'radiant-taggable-extension', '~> 2.0.0'\n\n "
93
108
  rdoc_options: []
94
109
 
95
110
  require_paths:
@@ -106,18 +121,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
106
121
  required_rubygems_version: !ruby/object:Gem::Requirement
107
122
  none: false
108
123
  requirements:
109
- - - ">"
124
+ - - ">="
110
125
  - !ruby/object:Gem::Version
111
- hash: 25
126
+ hash: 3
112
127
  segments:
113
- - 1
114
- - 3
115
- - 1
116
- version: 1.3.1
128
+ - 0
129
+ version: "0"
117
130
  requirements: []
118
131
 
119
132
  rubyforge_project:
120
- rubygems_version: 1.7.2
133
+ rubygems_version: 1.5.3
121
134
  signing_key:
122
135
  specification_version: 3
123
136
  summary: Tagging, clouding and faceting extension for Radiant CMS