| Class | Webgen::Tag::Menu |
| In: |
lib/webgen/tag/menu.rb
|
| Parent: | Object |
Generates a menu that can be configured extensively.
Generate the menu.
# File lib/webgen/tag/menu.rb, line 57
57: def call(tag, body, context)
58: tree = specific_menu_tree_for(context.content_node)
59:
60: (context.dest_node.node_info[:tag_menu_menus] ||= {})[[@params.to_a.sort, context.content_node.alcn]] = (tree ? tree.to_lcn_list : nil)
61:
62: if !tree || tree.children.empty?
63: ''
64: elsif param('tag.menu.nested')
65: create_output_nested(context, tree)
66: else
67: create_output_not_nested(context, tree)
68: end
69: end
Build a menu tree for content_node from the tree menu_node.
# File lib/webgen/tag/menu.rb, line 108
108: def build_specific_menu_tree(content_node, menu_node, level = 1)
109: if menu_node.nil? \
110: || level > param('tag.menu.max_levels') + param('tag.menu.start_level') - 1 \
111: || ((level > param('tag.menu.min_levels') + param('tag.menu.start_level') - 1) \
112: && (menu_node.node.level >= content_node.level \
113: || (param('tag.menu.show_current_subtree_only') && !content_node.in_subtree_of?(menu_node.node))
114: )
115: ) \
116: || (level == param('tag.menu.start_level') && !content_node.in_subtree_of?(menu_node.node))
117: return nil
118: end
119:
120: sub_menu_tree = MenuNode.new(nil, menu_node.node)
121: menu_tree = MenuNode.new(nil, menu_node.node)
122: menu_node.children.each do |child|
123: next if param('tag.menu.used_nodes') == 'files' && !child.is_in_tree_of_files?
124: menu_tree.children << (this_node = MenuNode.new(menu_tree, child.node))
125: sub_node = child.children.length > 0 ? build_specific_menu_tree(content_node, child, level + 1) : nil
126: sub_node.children.each {|n| this_node.children << n; sub_menu_tree.children << n} if sub_node
127: end
128:
129: if level < param('tag.menu.start_level')
130: sub_menu_tree
131: else
132: menu_tree
133: end
134: end
Create and return a menu tree if at least one node is in the menu or nil otherwise.
# File lib/webgen/tag/menu.rb, line 191
191: def create_menu_tree(node, parent, lang)
192: menu_node = MenuNode.new(parent, node)
193:
194: node.children.select do |child|
195: child.lang == lang || child.lang.nil? || child.is_directory?
196: end.each do |child|
197: sub_node = create_menu_tree(child, menu_node, lang)
198: menu_node.children << sub_node unless sub_node.nil?
199: end
200: menu_node.is_in_tree_of_files = (!node.is_fragment? && node['in_menu']) || menu_node.children.any? {|c| c.is_in_tree_of_files?}
201:
202: menu_node.children.empty? ? (node['in_menu'] ? menu_node : nil) : menu_node
203: end
Create the nested HTML menu of the tree using the provided context.
# File lib/webgen/tag/menu.rb, line 137
137: def create_output_nested(context, tree, level = 1)
138: out = "<ul>"
139: tree.children.each do |child|
140: menu = child.children.length > 0 ? create_output_nested(context, child, level + 1) : ''
141: style, link = menu_item_details(context.dest_node, child.node, context.content_node.lang, level)
142:
143: out << "<li #{style}>#{link}"
144: out << menu
145: out << "</li>"
146: end
147: out << "</ul>"
148: out
149: end
Create the not nested HTML menu of the tree using the provided context.
# File lib/webgen/tag/menu.rb, line 152
152: def create_output_not_nested(context, tree, level = 1)
153: submenu = ''
154: out = "<ul>"
155: tree.children.each do |child|
156: submenu << (child.children.length > 0 ? create_output_not_nested(context, child, level + 1) : '')
157: style, link = menu_item_details(context.dest_node, child.node, context.content_node.lang, level)
158:
159: out << "<li #{style}>#{link}</li>"
160: end
161: out << "</ul>"
162: out << submenu
163: out
164: end
Return style information (node is selected, …) and a link from dest_node to node.
# File lib/webgen/tag/menu.rb, line 167
167: def menu_item_details(dest_node, node, lang, level)
168: styles = ['webgen-menu-level' + level.to_s]
169: styles << 'webgen-menu-submenu' if node.is_directory? || (node.is_fragment? && node.children.length > 0)
170: styles << 'webgen-menu-submenu-inhierarchy' if (node.is_directory? || (node.is_fragment? && node.children.length > 0)) &&
171: dest_node.in_subtree_of?(node)
172: styles << 'webgen-menu-item-selected' if node == dest_node
173: style = "class=\"#{styles.join(' ')}\"" if styles.length > 0
174:
175: link = dest_node.link_to(node, :lang => lang)
176:
177: [style, link]
178: end
Return the menu tree for the language lang.
# File lib/webgen/tag/menu.rb, line 181
181: def menu_tree_for_lang(lang, root)
182: menus = (website.cache.volatile[:menutrees] ||= {})
183: unless menus[lang]
184: menus[lang] = create_menu_tree(root, nil, lang)
185: menus[lang].sort! if menus[lang]
186: end
187: menus[lang]
188: end
Check if the menus for node have changed.
# File lib/webgen/tag/menu.rb, line 76
76: def node_changed?(node)
77: return if !node.node_info[:tag_menu_menus]
78:
79: node.node_info[:tag_menu_menus].each do |(params, cn_alcn), cached_tree|
80: cn = node.tree[cn_alcn]
81: menu_tree = menu_tree_for_lang(cn.lang, cn.tree.root)
82:
83: set_params(params.to_hash)
84: tree = build_specific_menu_tree(cn, menu_tree)
85: tree_list = tree.to_lcn_list if tree
86: set_params({})
87:
88: if (tree.nil? && !cached_tree.nil?) || (tree_list && tree_list != cached_tree) ||
89: (tree_list && tree_list.flatten.any? do |alcn|
90: (n = node.tree[alcn]) && (r = n.routing_node(cn.lang)) && r != node && r.meta_info_changed?
91: end)
92: node.flag(:dirty)
93: break
94: end
95: end
96: end
Wrapper method for returning the specific menu tree for content_node.
# File lib/webgen/tag/menu.rb, line 99
99: def specific_menu_tree_for(content_node)
100: tree = menu_tree_for_lang(content_node.lang, content_node.tree.root)
101: if param('tag.menu.used_nodes') == 'fragments'
102: @params['tag.menu.start_level'] = param('tag.menu.start_level') + content_node.level
103: end
104: build_specific_menu_tree(content_node, tree)
105: end