From 63b337a4cae2f4d3996a8b322503c118b8d7d6d1 Mon Sep 17 00:00:00 2001 From: Adam Cooke Date: Mon, 11 Nov 2013 21:12:32 +0000 Subject: [PATCH] add a navigation manager. closes #59 --- CHANGELOG.md | 4 + app/helpers/shoppe/application_helper.rb | 4 + .../layouts/shoppe/application.html.haml | 23 +++--- config/locales/en.yml | 10 +++ lib/shoppe/default_navigation.rb | 19 +++++ lib/shoppe/engine.rb | 6 +- lib/shoppe/navigation_manager.rb | 79 +++++++++++++++++++ 7 files changed, 134 insertions(+), 11 deletions(-) create mode 100644 lib/shoppe/default_navigation.rb create mode 100644 lib/shoppe/navigation_manager.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 98e372b0..71cf4ab8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ This document outlines key changes which are introduced in each version. The ful * Add an admin-side order form for adding new orders and editing existing orders +* Adds `Shoppe::NavigationManager` which is used for managing sets of navigation within + the Shoppe interface. This allows module developers to add their own when appropriate + without needing to hack it into the view. + ## v0.0.19 * Only check that a delivery service is suitable if one has actually been selected. Ensures that diff --git a/app/helpers/shoppe/application_helper.rb b/app/helpers/shoppe/application_helper.rb index ea15cd51..bf564816 100644 --- a/app/helpers/shoppe/application_helper.rb +++ b/app/helpers/shoppe/application_helper.rb @@ -1,5 +1,9 @@ module Shoppe module ApplicationHelper + + def navigation_manager_link(item) + link_to item.description, item.url, item.link_options.merge(:class => item.active?(self) ? 'active' : 'inactive') + end def status_tag(status) content_tag :span, status, :class => "status-tag #{status}" diff --git a/app/views/layouts/shoppe/application.html.haml b/app/views/layouts/shoppe/application.html.haml index 2040837d..08578e51 100644 --- a/app/views/layouts/shoppe/application.html.haml +++ b/app/views/layouts/shoppe/application.html.haml @@ -16,16 +16,19 @@ %p.logged Logged in as #{current_user.full_name} %ul - %li - %span.pending= Shoppe::Order.pending.count - = link_to "Orders", [:orders], :class => @active_nav == :orders ? 'active' : '' - %li= link_to "Products", [:products], :class => @active_nav == :products ? 'active' : '' - %li= link_to "Product Categories", :product_categories, :class => @active_nav == :product_categories ? 'active' : '' - %li= link_to "Delivery Services", [:delivery_services], :class => @active_nav == :delivery_services ? 'active' : '' - %li= link_to "Tax Rates", :tax_rates, :class => @active_nav == :tax_rates ? 'active' : '' - %li= link_to "Users", [:users], :class => @active_nav == :users ? 'active' : '' - %li= link_to "Countries", :countries, :class => @active_nav == :countries ? 'active' : '' - %li= link_to "Settings", :settings, :class => @active_nav == :settings ? 'active' : '' + - for item in Shoppe::NavigationManager.find(:admin_primary).items + %li= navigation_manager_link item + + -#%li + -# %span.pending= Shoppe::Order.pending.count + -# = link_to "Orders", [:orders], :class => @active_nav == :orders ? 'active' : '' + -#%li= link_to "Products", [:products], :class => @active_nav == :products ? 'active' : '' + -#%li= link_to "Product Categories", :product_categories, :class => @active_nav == :product_categories ? 'active' : '' + -#%li= link_to "Delivery Services", [:delivery_services], :class => @active_nav == :delivery_services ? 'active' : '' + -#%li= link_to "Tax Rates", :tax_rates, :class => @active_nav == :tax_rates ? 'active' : '' + -#%li= link_to "Users", [:users], :class => @active_nav == :users ? 'active' : '' + -#%li= link_to "Countries", :countries, :class => @active_nav == :countries ? 'active' : '' + -#%li= link_to "Settings", :settings, :class => @active_nav == :settings ? 'active' : '' %li= link_to "Logout", [:logout], :method => :delete %header.main diff --git a/config/locales/en.yml b/config/locales/en.yml index e312308f..6b74d4d2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,6 +1,16 @@ en: shoppe: + navigation: + admin_primary: + orders: Orders + products: Products + product_categories: Product Categories + delivery_services: Delivery Services + tax_rates: Tax Rates + users: Users + countries: Countries + settings: types: diff --git a/lib/shoppe/default_navigation.rb b/lib/shoppe/default_navigation.rb new file mode 100644 index 00000000..7a5fad2b --- /dev/null +++ b/lib/shoppe/default_navigation.rb @@ -0,0 +1,19 @@ +require 'shoppe/navigation_manager' + +# This file defines all the default navigation managers used in Shoppe. Of course, +# modules can make changes to these by removing them or adding their own. This +# file is loaded on application initialization so if you make changes, you'll need +# to restart the webserver. + +# +# This is the default navigation manager for the admin interface. +# +Shoppe::NavigationManager.build(:admin_primary) do + add_item :orders + add_item :products + add_item :product_categories + add_item :delivery_services + add_item :tax_rates + add_item :users + add_item :countries +end diff --git a/lib/shoppe/engine.rb b/lib/shoppe/engine.rb index 52043986..892217ba 100644 --- a/lib/shoppe/engine.rb +++ b/lib/shoppe/engine.rb @@ -28,13 +28,16 @@ class Engine < ::Rails::Engine config.paths["db/migrate"].expanded.each do |expanded_path| app.config.paths["db/migrate"] << expanded_path end - end + end # Load view helpers for the base application ActiveSupport.on_load(:action_view) do require 'shoppe/view_helpers' ActionView::Base.send :include, Shoppe::ViewHelpers end + + # Load default navigation + require 'shoppe/default_navigation' end generators do @@ -43,3 +46,4 @@ class Engine < ::Rails::Engine end end + diff --git a/lib/shoppe/navigation_manager.rb b/lib/shoppe/navigation_manager.rb new file mode 100644 index 00000000..897a0f18 --- /dev/null +++ b/lib/shoppe/navigation_manager.rb @@ -0,0 +1,79 @@ +module Shoppe + class NavigationManager + + def self.managers + @managers ||= [] + end + + def self.create(identifier) + managers << self.new(identifier.to_s) + end + + def self.build(identifier, &block) + manager = self.new(identifier.to_s) + manager.instance_eval(&block) if block_given? + managers << manager + end + + def self.find(identifier) + managers.select { |m| m.identifier == identifier.to_s }.first + end + + def self.render(identifier) + find(identifier).try(:to_html) + end + + attr_reader :identifier + + def initialize(identifier) + @identifier = identifier + end + + def items + @items ||= [] + end + + def add_item(identifier, options = {}, &block) + item = NavigationItem.new + item.manager = self + item.identifier = identifier.to_s + item.url = options[:url] if options[:url] + item.link_options = options[:link_options] if options[:link_options] + item.active_if = block if block_given? + items << item + end + + def remove_item(identifier) + items.remote_if { |i| i.identifier.to_s == identifier.to_s } + end + + class NavigationItem + attr_accessor :manager + attr_accessor :identifier + attr_accessor :url + attr_accessor :link_options + attr_accessor :active_if + + def description + I18n.translate("shoppe.navigation.#{manager.identifier}.#{identifier}") + end + + def url + @url || Shoppe::Engine.routes.url_helpers.send("#{identifier}_path") + end + + def active?(request) + if active_if.is_a?(Proc) + active_if.call(request) == true + elsif active_nav_var = request.instance_variable_get('@active_nav') + active_nav_var.to_s == identifier + end + end + + def link_options + @link_options ||= {} + end + end + + end +end