Hi,
I am writing a plugin with some view helpers, and have hit a wall. The
helper method uses a class that specifies specific behavior depending
on an model object. The problem is that I need that class to be able
to use the rest of Rails helpers, such as content_tag.
The class extends a general class which is mixed with a module. It
uses method_missing to define methods to the class used by the helper
method if it hasn’t been defined.
This is the code with the problem:
init.rb
#The other stuff plus
ActionView::Base.send :include, Microformat::ViewHelpers
microformat_helper.rb
module Microformat
module ViewHelpers
# User will type:
# <% geo_for location, "Location:", :geo_tag
=> :div, :internal_tag => :span do |g| %>
# <% g.latitude "Latitude: #{location.latitude}, " %>
# <% g.longitude “Longitude: #{location.longitude}” %>
# <% end %>
# Output
# <div class="geo">GEO:
# <span class="latitude">37.386013</span>,
# <span class="longitude">-122.082932</span>
# </div>
def geo_for(geo_obj, text, options = {})
raise ArgumentError, "Missing block" unless block_given?
geo_tag = options.delete :geo_tag
internal_tag = options.delete :internal_tag
content_tag geo_tag, :class => "geo" do
text
yield GeoInternal.new(internal_tag, geo_obj)
end
end
end
module MicroformatCreator
def method_missing(name, *args)
block = Proc.new{|b_args, b_name|
tag, text = b_args.pop, b_args.pop
content_tag tag, :class => b_name do
text unless text.nil?
end
}
self.class.send(:define_method, name, block)
block.call(args, name)
end
end
class InvalidMicroformatField < StandardError
end
class Microformat
include MicroformatCreator
def initialize(tag, m_obj)
@i_tag = tag
@m_obj = m_obj
end
def method_missing(name, *args)
raise InvalidMicroformatField, "The field #{name} does not
exist" unless @m_obj.attribute_names.include?(name.to_s)
args.push @i_tag
super(name, args)
end
end
class GeoInternal < Microformat
def initialize(tag, g_obj)
super(tag, g_obj)
end
end
end
What is happening right now when I use ‘geo_for’ in a view is that the
content_tag in the MicroformatCreator method_missing is caught by the
raise of the Microformat class. I need to find a way to make the rails
helper methods to the GeoInternal class.
I have tried including MicroformatGenerator in init.rb, hoping then
that method missing could call content_tag, but it didn’t work. I also
tried including to MicroformatGenerator the necessary Rails helpers,
such as TagHelper, but then I got an error related to _erbout.
If anyone has a workaround to make the helpers available to
GeoInternal it would be great, or let me know if this is not possible.
Thanks,
Alan