Permalink
Browse files

initial commit

Signed-off-by: Balazs Nagy <julsevern@gmail.com>
  • Loading branch information...
0 parents commit 5651b9b80e4b81963ab0717edb032dadd70f48f3 @julian7 committed Aug 21, 2009
Showing with 228 additions and 0 deletions.
  1. +20 −0 MIT-LICENSE
  2. +26 −0 README
  3. +23 −0 Rakefile
  4. +3 −0 init.rb
  5. +151 −0 lib/semantic_menu.rb
  6. +5 −0 lib/semantic_menu_helper.rb
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Balazs Nagy
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 README
@@ -0,0 +1,26 @@
+SemanticMenus
+=============
+
+It's a semantic menu generator which works well with Lockdown, and has both hierarchical and breadcrumbs support.
+
+Inspired by and based on Daniel Haran's semantic-menu.
+
+Example
+=======
+
+def AdminMenu
+ build_menu do |root|
+ add "User functions" do |user|
+ add "New user..." new_user_path
+ add "Manage users" users_path
+ add "Manage group access" groups_path
+ end
+ add "Messages" do |msg|
+ add "New message" new_message_path
+ add "INBOX" messages_path
+ end
+ end
+end
+
+
+Copyright (c) 2009 Balazs Nagy, released under the MIT license
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the semantic_menus plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the semantic_menus plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'SemanticMenus'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
@@ -0,0 +1,3 @@
+#require 'semantic_menu'
+#require 'semantic_menu_helper'
+ActionView::Base.send :include, SemanticMenuHelper
@@ -0,0 +1,151 @@
+module SemanticMenu
+ class MenuItem
+ attr_accessor :children, :link, :title
+ cattr_accessor :controller
+ cattr_accessor :view
+ extend ActiveSupport::Memoizable
+
+ def initialize(title, link, level = 0, opts = {})
+ @title = title
+ @link = link
+ @method = opts.delete(:method) || :get
+ @ctrl = opts.delete(:controller) || false
+ @level = level
+ @opts = opts
+ @children = []
+ end
+
+ def add(title, link = nil, opts = {}, &block)
+ returning (MenuItem.new(title, link, @level + 1, opts)) do |item|
+ @children << item
+ yield item if block_given?
+ end
+ end
+
+ def to_s
+ ret = ""
+ unless @link.nil?
+ has_link = true
+ ret = view.link_to(@title, @link, @opts)
+ end
+ if ret.empty?
+ has_link = false
+ ret = view.content_tag(:span, @title)
+ end
+ children = to_s_children
+ unless children.empty?
+ has_link = true
+ ret += children
+ end
+ if has_link and !ret.empty?
+ ret = view.content_tag :li, ret, active? ? {:class => "active"} : {}
+ end
+ end
+
+ protected
+
+ def get_breadcrumb
+ unless active?
+ return nil
+ end
+ @children.map{ |child| child.get_breadcrumb }.
+ flatten.compact.unshift(self)
+ end
+
+ def to_s_breadcrumb
+ ret = ""
+ unless @link.nil?
+ ret = view.link_to(@title, @link, @opts)
+ end
+ if ret.empty?
+ ret = view.content_tag(:span, @title)
+ end
+ ret
+ end
+
+ def to_s_children
+ if (@children.empty?)
+ return ''
+ end
+ ret = @children.collect(&:to_s).join
+ if ret.empty?
+ ''
+ else
+ css = ["menu_level_#{@level}"]
+ if active?
+ css << "active"
+ end
+ if self.on_current_page? or @children.any?(&:on_current_page?)
+ css << "current"
+ end
+ view.content_tag(:ul, ret, :class => css.join(" "))
+ end
+ end
+
+ def active?
+ @children.any?(&:active?) || on_current_page?
+ end
+
+ def on_current_page?
+ if (@link == nil)
+ return false
+ end
+ if (@link == @@controller.request.request_uri)
+ return true
+ end
+ link_points_to = ActionController::Routing::Routes.recognize_path(@link, :method => @method)
+ req_points_to = @@controller.instance_variable_get(:@_params)
+ if (@ctrl != false && req_points_to[:controller] == link_points_to[:controller])
+ return true
+ end
+ req_points_to == link_points_to
+ end
+
+ memoize :get_breadcrumb
+ memoize :active?
+ memoize :on_current_page?
+ end
+
+ class Menu < MenuItem
+ def initialize(controller, view, opts = {}, &block)
+ @@controller = controller
+ @@view = view
+ @level = 0
+ @opts = {:class => 'menu'}.merge opts
+ @children = []
+ yield self if block_given?
+ end
+
+ def to_s
+ opts = @opts
+ if (!active?)
+ opts[:class] += " current"
+ end
+ view.content_tag(:ul, @children.collect(&:to_s).join, opts)
+ end
+
+ def to_breadcrumb
+ bc = get_breadcrumb
+ ret = [ MenuItem.new(I18n.t(:menu_root), "/", 0) ]
+ if bc.nil?
+ ret += [view.content_tag :li, view.title]
+ else
+ bc = bc.dup
+ last = bc.pop.dup
+ last.link = nil
+ bc.push(last)
+ ret += bc.collect{|item| item.to_s_breadcrumb}.
+ reject{|item| item.nil? or item.empty?}.
+ collect { |item| view.content_tag :li, item }
+ end
+ view.content_tag :ul, ret.join,
+ :class => "breadcrumbs" + (active? ? "" : " current")
+ end
+
+ protected
+
+ def to_s_breadcrumb
+ nil
+ end
+ end
+end
@@ -0,0 +1,5 @@
+module SemanticMenuHelper
+ def semantic_menu(opts = {}, &block)
+ ::SemanticMenu::Menu.new(controller, self, opts, &block)
+ end
+end

0 comments on commit 5651b9b

Please sign in to comment.