ActsAsTaggableRedux additions

ActsAsTaggableRedux is a super nice tag plugin. If anyone’s interested here are some additions I made.

1) Bug in README: Need to add “acts_as_taggable” to model being tagged (items in your example)

2) Modified find_tagged_with in ActsAsTaggable to work with will_paginate plugin
[source:ruby]
def find_tagged_with(tags, options = {})
#options.assert_valid_keys([:match, :user]) #, :page, :per_page])

tags = Tag.parse(tags)
return [] if tags.empty?

page = options[:page].to_i
per_page = options[:per_page].to_i
page = 1 if page < 1 per_page = 10 if per_page < 1 group = "#{table_name}_taggings.taggable_id HAVING COUNT(#{table_name}_taggings.taggable_id) = #{tags.size}" if options[:match] == :all conditions = sanitize_sql(["#{table_name}_tags.name IN (?)", tags]) conditions += sanitize_sql([" AND #{table_name}_taggings.user_id = ?", options[:user]]) if options[:user] paginate(:all, :select => “DISTINCT #{table_name}.*”,
:joins => %(
LEFT OUTER JOIN taggings
#{table_name}_taggings ON
#{table_name}_taggings.taggable_id = #{table_name}.#{primary_key}
AND #{table_name}_taggings.taggable_type = ‘#{name}’
LEFT OUTER JOIN tags #{table_name}_tags ON
#{table_name}_tags.id = #{table_name}_taggings.tag_id
),
:conditions => conditions,
:group => group,
:page => page,
:per_page => per_page
)
end
[/source]

I also had to change will_paginate – haven’t looked closely into this yet – so it’s a hack. I had to add this to will_paginate/finder.rb:
[source:ruby]
if options[:select] =~ /^\s*DISTINCT/i
options[:select].gsub!(“.*”, “.id”)
end
[/source]
… so the resulting method looks like:
[source:ruby]
def wp_count!(options, args, finder)
excludees = [:count, :order, :limit, :offset]
unless options[:select] and options[:select] =~ /^\s*DISTINCT/i
excludees < < :select # only exclude the select param if it doesn't begin with DISTINCT end if options[:select] =~ /^\s*DISTINCT/i options[:select].gsub!(".*", ".id") end # count expects (almost) the same options as find count_options = options.except *excludees # merge the hash found in :count # this allows you to specify :select, :order, or anything else just for the count query count_options.update(options.delete(:count) || {}) if options.key? :count # we may have to scope ... counter = Proc.new { count(count_options) } # we may be in a model or an association proxy! klass = (@owner and @reflection) ? @reflection.klass : self count = if finder =~ /^find_/ and klass.respond_to?(scoper = finder.sub(/^find_/, 'with_')) # scope_out adds a 'with_finder' method which acts like with_scope, if it's present # then execute the count with the scoping provided by the with_finder send(scoper, &counter) elsif conditions = wp_extract_finder_conditions(finder, args) # extracted the conditions from calls like "paginate_by_foo_and_bar" with_scope(:find => { :conditions => conditions }, &counter)
else
counter.call
end

count.respond_to?(:length) ? count.length : count
end
[/source]
3) Modified helper for better seo – added this to ActsAsTaggableHelper
[source:ruby]
def tag_url(tag)
“/tags/#{tag.name}”
end
[/source]

4) Added delicious styled tagging form helper to do this:
a) add this to ActsAsTaggableHelper
[source:ruby]
def delicious_tags(obj, f)
res = %(
Tags: #{f.text_field :tag_list})
res < < %(

)
res < < spaced_tags_delicious(obj) res << "


return res
end

def spaced_tags_delicious(obj)
res = []
Tag.find(:all, :order => “name”).each do |tag|
link = %(javascript:swap_tag(‘#{tag.name}’,’#{obj.class.name.tableize.singularize}_tag_list’))
res < < link_to(tag.name, link) end return res.join(" ") end [/source] b) include tags.js [source:javascript] //modified selections from http://del.icio.us/ui/static/post.js?v=3o3 tag_delimitor = " " function swap_tag(tag,elem) { swap_tag(tag,elem,true) } function swap_tag(tag,elem,change_case){ if (change_case == true) { tag = trim(tag).toLowerCase(); } else { tag = trim(tag) } tags = document.getElementById(elem) var tagArray = trim(tags.value).split(tag_delimitor) var present = false; if (trim(tagArray[0]) == '') tagArray.splice(0,1); for (t=0; t 1) ? content + ‘, ‘ : content
tags.value = content;
//focusTo(tags)
}

function trim(str)
{
return str.replace(/^\s*|\s*$/g,””);
}
[/source]

c) Call from your form like
[source:ruby]
< %=delicious_tags (@blog_entry, f)%>
[/source]

4) Also added a simple “spaced tag” helper to ActsAsTaggableHelper to put tags in blog footers (or whatever)

[source:ruby]
def spaced_tags(obj)
res = []
obj.tags.each do |tag|
res << link_to_tag(tag) end return res.join(" ") end [/source]