module Alchemy::Modules

Public Class Methods

included(base) click to toggle source
# File lib/alchemy/modules.rb, line 10
def included(base)
  base.send :helper_method, :alchemy_modules, :module_definition_for
end
register_module(module_definition) click to toggle source

Register a Alchemy module.

A module is a Hash that must have at least a name and a navigation key that has a controller and action name.

Example:

name: 'module',
navigation: {
  controller: 'admin/controller_name',
  action: 'index'
}
# File lib/alchemy/modules.rb, line 27
def register_module(module_definition)
  definition_hash = module_definition.deep_stringify_keys

  ### Validate controller(s) existence
  if definition_hash["navigation"].is_a?(Hash)
    defined_controllers = [definition_hash["navigation"]["controller"]]

    if definition_hash["navigation"]["sub_navigation"].is_a?(Array)
      defined_controllers.concat(definition_hash["navigation"]["sub_navigation"].map { |x| x["controller"] })
    end

    validate_controllers_existence(defined_controllers, definition_hash)
  end

  @@alchemy_modules |= [definition_hash]
end

Private Class Methods

validate_controllers_existence(controllers, definition_hash) click to toggle source
# File lib/alchemy/modules.rb, line 46
def validate_controllers_existence(controllers, definition_hash)
  controllers.each do |controller_val|
    next if controller_val.blank?

    controller_name = "#{controller_val.camelize}Controller"

    begin
      controller_name.constantize
    rescue NameError
      raise "Error in AlchemyCMS module definition: '#{definition_hash["name"]}'. Could not find the matching controller class #{controller_name.sub(/^::/, "")} for the specified controller: '#{controller_val}'"
    end
  end
end

Public Instance Methods

module_definition_for(name_or_params) click to toggle source

Get the module definition for given module name

You can also pass a hash of an module definition. It then tries to find the module defintion from controller name and action name

# File lib/alchemy/modules.rb, line 66
def module_definition_for(name_or_params)
  case name_or_params
  when String
    alchemy_modules.detect { |m| m["name"] == name_or_params }
  when Hash
    name_or_params.stringify_keys!
    alchemy_modules.detect do |alchemy_module|
      module_navi = alchemy_module.fetch("navigation", {})
      definition_from_mainnavi(module_navi, name_or_params) ||
        definition_from_subnavi(module_navi, name_or_params) ||
        definition_from_nested(module_navi, name_or_params)
    end
  else
    raise ArgumentError, "Could not find module definition for #{name_or_params}"
  end
end

Private Instance Methods

action_matches?(navi, params) click to toggle source
# File lib/alchemy/modules.rb, line 111
def action_matches?(navi, params)
  navi["action"] == params["action"]
end
controller_matches?(navi, params) click to toggle source
# File lib/alchemy/modules.rb, line 107
def controller_matches?(navi, params)
  remove_slash(navi["controller"]) == remove_slash(params["controller"])
end
definition_from_mainnavi(module_navi, params) click to toggle source
# File lib/alchemy/modules.rb, line 85
def definition_from_mainnavi(module_navi, params)
  controller_matches?(module_navi, params) && action_matches?(module_navi, params)
end
definition_from_nested(module_navi, params) click to toggle source
# File lib/alchemy/modules.rb, line 98
def definition_from_nested(module_navi, params)
  nested = module_navi["nested"]
  return if nested.nil?

  nested.any? do |navi|
    controller_matches?(navi, params) && action_matches?(navi, params)
  end
end
definition_from_subnavi(module_navi, params) click to toggle source
# File lib/alchemy/modules.rb, line 89
def definition_from_subnavi(module_navi, params)
  subnavi = module_navi["sub_navigation"]
  return if subnavi.nil?

  subnavi.any? do |navi|
    controller_matches?(navi, params) && action_matches?(navi, params)
  end
end
remove_slash(str) click to toggle source
# File lib/alchemy/modules.rb, line 115
def remove_slash(str)
  str.gsub(/^\//, "")
end