lib/wrap_it/helpers.rb
#
# Registering helpers
#
# To use your classes and helpers in templates you should register your
# library. First, in your framework initialization, you should register
# your library in WrapIt. You can have separate module for it or WrapIt
# will make anonymous one. After this, your module will have `register`
# and `unregister` methods to register your classes.
#
# @example usual case - library in separate module
# # initialization time
# module Library
# module Helpers; end
# end
# WrapIt.register_module Library::Helpers, prefix: 'lib_'
#
# # controller
# class MyController < ApplicationController
# helper Library::Helpers
# end
#
# # implementation
# module Library
# module Helpers
# class Button < WrapIt::Base
# ...
# end
#
# register :super_button, Button
# end
# end
#
# # in template:
# <%= lib_super_button 'text' %>
#
# @example anonymous module
# helpers = WrapIt.register_module prefix: 'lib_'
#
# class Button < WrapIt::Base
# ...
# end
#
# helpers.register :super_button, Button
#
# class MyController
# helper helpers
# end
#
# @author Alexey Ovchinnikov <alexiss@cybernetlab.ru>
#
module WrapIt
using EnsureIt if ENSURE_IT_REFINED
#
# Registers helpers module
#
# @overload register_module(mod = nil, opts = {})
# @param mod [Module] module for register. Anonymous module will be
# created if ommited.
# @param opts [Hash] options
# @option opts [String] :prefix prefix for helper methods
#
# @return [void]
def self.register_module(*args)
options = args.extract_options!
options.symbolize_keys!
options = {prefix: ''}.merge(options)
mod = args.shift
mod.is_a?(Module) || mod = Module.new
mod.instance_eval do
define_singleton_method(:register, &WrapIt.register_block(options))
define_singleton_method(:unregister, &WrapIt.unregister_block(options))
end
mod
end
# @!method register([name, ...], class_name)
# adds to template list of helpers for creating elements of specified class
# @param name [Symbol, String] name of helper. Will be prefixed with prefix
# option, specified in {WrapIt#register_module} call.
# @param class_name [String, Class] element class
# @!method unregister([name, ...])
# removes list of helpers from template
# @param name [Symbol, String] name of helper to remove from tampate
private
def self.register_block(options)
# Runs in helpers module class context
proc do |*args|
class_name = args.pop.ensure_class!(
string: true,
message: "Last argument for #{name}.register_helper should be" \
" a class name"
).name
helpers = instance_methods
args.ensure_array(:ensure_symbol!).each do |helper|
helpers.include?(helper) && fail(
ArgumentError, "Helper #{helper} for WrapIt.register allready exists"
)
define_method(
"#{options[:prefix]}#{helper}",
WrapIt.method_block(helper, class_name)
)
end
end
end
def self.unregister_block(options)
# Runs in helpers module class context
proc do |*list|
helpers = instance_methods
list.each do |helper|
helper.is_a?(String) && helper = helper.to_sym
next unless helper.is_a?(Symbol)
helper_name = "#{options[:prefix]}#{helper}"
next unless helpers.include?(helper_name)
remove_method helper_name
end
end
end
def self.method_block(name, class_name)
# Runs in helpers module context
proc do |*args, &block|
opts = args.extract_options!
opts[:helper_name] = name
args << opts
obj = Object.const_get(class_name).new(self, *args, &block)
obj.render
end
end
end