migrate to new menu handling system

This commit is contained in:
2012-11-25 09:52:46 +01:00
parent bb8efcb616
commit 58f7ba93b6
7 changed files with 299 additions and 16 deletions
+15 -14
View File
@@ -34,19 +34,20 @@ html lang="en"
.container.nav-collapse
- if user_signed_in?
ul.nav
li[ class=(controller_name == 'pages' ? 'ui-state-active' : 'ui-state-default') ]=link_to Page.model_name.human_plural, cmtool.pages_path
li[ class=(controller_name == 'news' ? 'ui-state-active' : 'ui-state-default') ]=link_to Cmtool::News.model_name.human_plural, cmtool.news_index_path
li[ class=(controller_name == 'keywords' ? 'ui-state-active' : 'ui-state-default') ]=link_to Cmtool::Keyword.model_name.human_plural, cmtool.keywords_path
li[ class=(controller_name == 'faqs' ? 'ui-state-active' : 'ui-state-default') ]=link_to Cmtool::Faq.model_name.human_plural, cmtool.faqs_path
li[ class=(controller_name == 'quotes' ? 'ui-state-active' : 'ui-state-default') ]=link_to Cmtool::Quote.model_name.human_plural, cmtool.quotes_path
li[ class=(%w[contact_forms demo_requests call_requests newsletter_subscriptions].include?(controller_name) ? ['ui-state-active', 'parent'] : ['ui-state-default', 'parent']) ]
span.title= t('cmtool.menu.forms.title')
ul.child-menu
li[ class=(controller_name == 'contact_forms' ? 'ui-state-active' : 'ui-state-default') ]=link_to Cmtool::ContactForm.model_name.human_plural, cmtool.contact_forms_path
li[ class=(controller_name == 'newsletter_subscriptions' ? 'ui-state-active' : 'ui-state-default') ]=link_to Cmtool::NewsletterSubscription.model_name.human_plural, cmtool.newsletter_subscriptions_path
li[ class=(controller_name == 'users' ? 'ui-state-active' : 'ui-state-default') ]=link_to User.model_name.human_plural, cmtool.users_path
li[ class=(controller_name == 'images' ? 'ui-state-active' : 'ui-state-default') ]=link_to Cmtool::Image.model_name.human_plural, cmtool.images_path
li[ class=(controller_name == 'directories' ? 'ui-state-active' : 'ui-state-default') ]=link_to Cmtool::Directory.model_name.human_plural, cmtool.directories_path
- Cmtool::Menu.items.each do |menu_item|
- if menu_item.group?
li.dropdown class=(menu_item.controller_names.include?(controller_name) ? 'active' : '')
a.dropdown-toggle href="#" data-toggle="dropdown"
span = menu_item.title
b.caret
ul.child-menu.dropdown-menu
- menu_item.items.compact.each do |child_item|
- if child_item.divider?
li.divider
- else
li[ class=(controller_name == child_item.controller_name ? 'active' : '') ] = link_to child_item.title, child_item.path
- elsif false && menu_item.resource_link?
li[ class=(menu_item.controller_name == controller_name ? 'active' : '')]= link_to menu_item.title, menu_item.path
.btn-group.pull-right
a.btn.dropdown-toggle[data-toggle="dropdown" href="#"]
i.icon-user
@@ -78,6 +79,6 @@ html lang="en"
= yield :sidebar
footer
p © KPN 2012
p © Cmtool 2012
= yield :footer
#hidden-html.hide= yield :hidden_html
+27
View File
@@ -0,0 +1,27 @@
Cmtool::Menu.register do
group label: :site do
title t('cmtool.menu.site.title')
resource_link Page, scope: Cmtool
resource_link Cmtool::Keyword
end
group label: :publications do
title t('cmtool.menu.publications.title')
resource_link Cmtool::News
resource_link Cmtool::Faq
resource_link Cmtool::Quote
end
group label: :forms do
title t('cmtool.menu.forms.title')
resource_link Cmtool::ContactForm
resource_link Cmtool::NewsletterSubscription
end
group label: :files do
title t('cmtool.menu.files.title')
resource_link Cmtool::Image
resource_link Cmtool::Directory
end
resource_link User, label: :users, scope: Cmtool
end
Cmtool::Menu.register do
end
+7 -1
View File
@@ -7,8 +7,14 @@ en:
are_you_sure_with_name: 'Are you sure you want to delete %{model} %{name}?'
empty_result: No %{models} found
menu:
site:
title: Site
forms:
title: Form
title: Forms
publications:
title: Publications
files:
title: Files
action:
index:
title: List %{models}
+1
View File
@@ -2,6 +2,7 @@ require "cmtool/engine"
require 'cmtool/includes/user'
require 'cmtool/includes/page'
require 'cmtool/includes/pages_controller'
require 'cmtool/menu'
module Cmtool
end
+185
View File
@@ -0,0 +1,185 @@
module Cmtool
module Menu
def self.register(&block)
@register ||= Register.new
@register.instance_eval(&block)
@registrations ||= []
@registrations << block
end
def self.items
@register.items
end
def self.method_missing(*args, &blk)
@register.send(*args, &blk)
end
# Reset the complete menu
def self.reset!
@register = Register.new
@registrations = []
end
# Getter for the registrations
def self.registrations
@registrations ||= []
end
##
# Base class for elements in the menu. All elements like Groups/ResourceLinks should
# inherit from this class
##
class ElementBase
def initialize(*args)
@options = args.extract_options!
end
def controller_names
[]
end
def controller_name
''
end
def options
@options ||= {}
end
def method_missing(*args)
return true if self.class.name.sub(/.*::/, '').underscore.concat("?") == args.first.to_s
return false if args.first.to_s.last == '?'
@register.send(*args)
end
end
##
# Just a simple class that identifies itself as a divider
##
class Divider < ElementBase
end
##
# A group element, works as a new kind of menu, but then within another one
##
class Group < ElementBase
def initialize(options = {}, &block)
block ||= Proc.new{}
@register = Register.new
@options = options
@block = block
@register.instance_eval &block
end
def title
@register.title.respond_to?(:call) ? @register.title.call : @register.title
end
def controller_names
resource_links.map(&:controller_name)
end
def group?
true
end
end
##
# Resource link, indicates a link to standard resource. The first argument should
##
class ResourceLink < ElementBase
attr_reader :resource
def initialize(resource, options = {})
@resource, @options = resource, options
end
def resource_link?
true
end
def controller_name
@resource.name.underscore.split('/').last.pluralize
end
def title
@resource.model_name.human_plural
end
def path
engine.routes.url_helpers.url_for(controller: nested_controller_name, action: 'index', only_path: true)
end
def engine
base = @options[:scope].presence
base ||= @resource.name.split('::').first if @resource.name.index('::')
return Rails.application unless base
return base if base.is_a?(Rails::Engine)
if e = "#{base}::Engine".safe_constantize
return e
end
return Rails.application
end
def nested_controller_name
if @options[:scope].present?
"#{@options[:scope]}::#{@resource.name}".underscore.pluralize
else
@resource.name.underscore.pluralize
end
end
end
##
# Register class on which the register blocks are executed. Should hold all possible DSL logic
##
class Register
attr_reader :items
def initialize
@items = []
end
def t(*args)
-> { I18n.t(*args) }
end
def group(options = {}, &block)
@items << Group.new(options, &block)
end
def title(*args)
return @title if args.empty?
@title = args.first
end
def resource_link(resource, options = {})
@items << ResourceLink.new(resource, options)
end
def resource_links
@items.select{|i| i.is_a?(ResourceLink)}
end
def method_missing(*args)
@items.send(*args).to_a
end
def before(label, &block)
@before = []
@before << items.shift while items.first && items.first.options[:label] != label
@after = @items
@items = []
instance_eval(&block)
@items = @before + @items + @after
end
def after(label, &block)
@before = []
@before << items.shift while items.first && items.first.options[:label] != label
@before << items.shift if items.any?
@after = @items
@items = []
instance_eval(&block)
@items = @before + @items + @after
end
def append_to(label, &block)
item = items.find{|i| i.options[:label] == label}
if item
register = item.instance_variable_get('@register')
if register
register.instance_variable_get('@items') << Cmtool::Menu::Divider.new
register.instance_eval(&block)
end
else
instance_eval(&block)
end
end
end
end
end
+64
View File
@@ -0,0 +1,64 @@
require 'spec_helper'
describe Cmtool::Menu do
before :all do
@base_block = Cmtool::Menu.registrations.first
end
before :each do
Cmtool::Menu.reset!
Cmtool::Menu.register &@base_block
end
describe Cmtool::Menu::ElementBase do
it "should return false on specific element inquiry" do
base_element = Cmtool::Menu::ElementBase.new
element_names = Cmtool::Menu::ElementBase.subclasses.map{|e| e.name.sub(/.*::/, '').underscore }
for element_name in element_names
base_element.send("#{element_name}?").should be_false
end
end
end
describe Cmtool::Menu::Group do
it "should identify itself as such" do
Cmtool::Menu::Group.new.group?.should be_true
end
it "should not identify as resource link" do
Cmtool::Menu::Group.new.resource_link?.should be_false
end
end
describe Cmtool::Menu::ResourceLink do
it "should identify itself as such" do
Cmtool::Menu::ResourceLink.new(User).resource_link?.should be_true
end
end
describe :items do
it "should return an array" do
Cmtool::Menu.items.should be_a Array
end
it "should return an array of 5" do
Cmtool::Menu.items.size.should == 5
end
end
describe 'New register block' do
before :each do
Cmtool::Menu.register do
before :users do
resource_link Page, scope: Cmtool
end
after :publications do
resource_link Cmtool::Image
end
append_to :publications do
resource_link Cmtool::Directory
end
end
end
it "should have pages as second last items argument" do
second_last = Cmtool::Menu.items[-2]
second_last.should be_a Cmtool::Menu::ResourceLink
second_last.resource.should == Page
end
end
end
-1
View File
@@ -61,4 +61,3 @@ module Dummy
config.assets.version = '1.0'
end
end