1 module MenuRenderer
2
3 def exclude(*type_names)
4 @excluded_class_names ||= []
5 @excluded_class_names.concat(type_names).uniq!
6 end
7 module_function :exclude
8
9 def excluded_class_names
10 MenuRenderer.instance_variable_get(:@excluded_class_names)
11 end
12
13 module_function :excluded_class_names
14 public :excluded_class_names
15
16 def view=(val)
17 @view = val
18 end
19
20 def view
21 @view
22 end
23
24 def additional_menu_features?
25 @additional_menu_features ||= (menu_renderer_module_name != 'MenuRenderer' && Object.const_defined?(menu_renderer_module_name))
26 end
27
28 def menu_renderer_module_name
29 simple_name = self.class_name.to_s.sub('Page','')
30 "#{simple_name}MenuRenderer"
31 end
32
33 def menu_renderer_modules
34 [Object.const_get(menu_renderer_module_name)]
35 end
36
37 def allowed_child_classes
38 (allowed_children_cache.to_s.split(',') - Array(excluded_class_names)).map do |name|
39 begin
40 name.constantize
41 rescue LoadError, NameError => e
42 nil
43 end
44 end.compact
45 end
46
47
48 def default_child_item
49 menu_item(default_child)
50 end
51
52 def separator_item
53 view.content_tag :li, '', :class => 'separator'
54 end
55
56 def child_items
57 (allowed_child_classes - [self.class.default_child]).map do |child|
58 menu_item(child)
59 end
60 end
61
62 def menu_items
63 [default_child_item, separator_item] + child_items
64 end
65
66 def menu_list
67 view.content_tag :ul, menu_items.join, :class => 'menu', :id => "allowed_children_#{id}"
68 end
69
70 def remove_link
71 view.link_to view.image('minus') + ' ' + I18n.t('remove'), view.remove_admin_page_url(self), :class => "action"
72 end
73
74 def remove_option
75 remove_link
76 end
77
78 def add_child_disabled?
79 allowed_child_classes.size == 0
80 end
81
82 def disabled_add_child_link
83 view.content_tag :span, view.image('plus_disabled') + ' ' + I18n.t('add_child'), :class => 'action disabled'
84 end
85
86 def add_child_link
87 view.link_to((view.image('plus') + ' ' + I18n.t('add_child')), view.new_admin_page_child_path(self, :page_class => default_child.name), :class => "action")
88 end
89
90 def add_child_link_with_menu_hook
91 view.link_to((view.image('plus') + ' ' + I18n.t('add_child')), "#allowed_children_#{id}", :class => "action dropdown")
92 end
93
94 def add_child_menu
95 menu_list
96 end
97
98 def add_child_link_with_menu
99 add_child_link_with_menu_hook + add_child_menu
100 end
101
102 def add_child_option
103 if add_child_disabled?
104 disabled_add_child_link
105 else
106 if allowed_child_classes.size == 1
107 add_child_link
108 else
109 add_child_link_with_menu
110 end
111 end
112 end
113
114 private
115
116 def clean_page_description(page_class)
117 page_class.description.to_s.strip.gsub(/\t/,'').gsub(/\s+/,' ')
118 end
119
120 def menu_item(child_class)
121 view.content_tag(:li, menu_link(child_class))
122 end
123
124 def menu_link(child_class)
125 title = clean_page_description(child_class)
126 path = view.new_admin_page_child_path(self, :page_class => child_class.name)
127 text = link_text_for_child_class(child_class.name)
128 view.link_to(text, path, :title => title)
129 end
130
131 def link_text_for_child_class(given_class_name)
132 translation_key = if given_class_name == 'Page' || given_class_name.blank?
133 'normal_page'
134 else
135 given_class_name.sub('Page','').underscore
136 end
137 fallback = given_class_name == 'Page' ? 'Page' : given_class_name.sub('Page','').titleize
138 I18n.t(translation_key, :default => fallback)
139 end
140 en