Last active
January 4, 2016 13:21
-
-
Save douglaslise/66c466a652bd7ff7ddf3 to your computer and use it in GitHub Desktop.
DSL Menus Wonder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{:label=>"Início", :path=>nil} | |
{:label=>"Oportunidades", :path=>nil} | |
{:label=>"Cadastros", :path=>nil} | |
{:label=>"Oportunidades", :path=>"cml_motivos_estagios_oportunidade"} | |
{:label=>"Oportunidade 1", :path=>"/cml/oportunidades/5"} | |
{:label=>"Itens", :path=>nil} | |
{:label=>"Instância de item da oportunidade Oportunidade 1", :path=>nil} | |
************************************************** | |
{:label=>"Início", :path=>nil} | |
{:label=>"Oportunidades", :path=>nil} | |
{:label=>"Cadastros", :path=>nil} | |
{:label=>"Oportunidades", :path=>"cml_motivos_estagios_oportunidade"} | |
{:label=>"Oportunidade 1", :path=>"/cml/oportunidades/5"} | |
{:label=>"Edição", :path=>"edit_/cml/oportunidades/5"} | |
************************************************** | |
{:id=>:root, | |
:label=>"Início", | |
:path=>nil, | |
:subitems=> | |
[{:id=>:oport, | |
:label=>"Oportunidades", | |
:path=>nil, | |
:subitems=> | |
[{:id=>:oport_cadastros, | |
:label=>"Cadastros", | |
:path=>nil, | |
:subitems=> | |
[{:id=>:oport_oportunidades, :label=>"Oportunidades", :path=>"cml_motivos_estagios_oportunidade"}, | |
{:id=>:oport_estagios, :label=>"Estágios", :path=>"cml_motivos_estagios_oportunidade"}]}]}]} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Menu | |
attr_reader :items | |
def initialize(&block) | |
@items = {} | |
items[:root] = MenuItem.new(self, 0, :root, "Início") | |
items[:root].instance_eval(&block) | |
end | |
def breadcrumb_for(id, object = nil) | |
items[id].breadcrumbs(object) | |
end | |
def menu_tree(options = {}) | |
active = options[:active] | |
max_depth = options[:max_depth] | |
items[:root].tree(active, max_depth) | |
end | |
end | |
class MenuItem | |
attr_accessor :menu_instance, :level, :id, :label_text, :label_proc, :path_fixed, :path_proc, :block, :parent_item, :parent_block, :subitems | |
def initialize(menu_instance, level, id, label = nil, options = {}, &block) | |
if label.is_a?(Hash) | |
options = label | |
label = options.delete(:label) | |
end | |
@level = level | |
@menu_instance = menu_instance | |
@id = id | |
@label_text = label | |
@path_fixed = options[:path] | |
@block = block | |
@subitems = [] | |
end | |
def menu(id, label = nil, options = {}, &block) | |
sub_item = MenuItem.new(menu_instance, level + 1, id, label, options, &block) | |
menu_instance.items[id] = sub_item | |
sub_item.parent_item = self | |
if block_given? | |
#sub_item.instance_eval(&block)# yield | |
sub_item.instance_exec(&block) | |
raise "MenuItem #{id} sem label definido" unless sub_item.label_proc || sub_item.label_text | |
end | |
end | |
def breadcrumbs(object = nil) | |
result = [] | |
if parent_item | |
if parent_block | |
parent_object = parent_block.call(object) | |
else | |
parent_object = object | |
end | |
result += parent_item.breadcrumbs(parent_object) | |
end | |
current = {} | |
current[:label] = resolve_label(object) | |
current[:path] = resolve_path(object) | |
result << current | |
end | |
def tree(active, max_depth) | |
result = { | |
id: id, | |
label: resolve_label(nil), | |
path: resolve_path(nil) | |
} | |
puts "max_depth: #{max_depth}" | |
if !max_depth || level < max_depth | |
result[:subitems] = subitems.collect do |sub_item| | |
sub_item.tree(active, max_depth) | |
end | |
end | |
result | |
end | |
def parent_item=(parent_item) | |
if parent_item | |
@parent_item = parent_item | |
parent_item.subitems << self | |
else | |
@parent_item.subitems.delete(self) | |
@parent_item = nil | |
end | |
end | |
private | |
def label(&block) | |
@label_proc = block | |
end | |
def path(&block) | |
@path_proc = block | |
end | |
def parent(&block) | |
@parent_block = block | |
end | |
def resolve_label(object) | |
label_text || label_proc.call(object) | |
end | |
def resolve_path(object) | |
if path_fixed | |
path_fixed | |
elsif path_proc && object | |
path_proc.call(object) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment