Permalink
Browse files

Merge pull request #7 from 58bits/session

Session Based BreadcrumbStack
  • Loading branch information...
2 parents 6e40c63 + 52ab85c commit de75f347c0df340b68e13c1ef88412b632318285 Simon COURTOIS committed May 18, 2012
View
3 .rspec
@@ -0,0 +1,3 @@
+--colour
+--drb
+--format documentation
View
@@ -1,13 +1,29 @@
require 'ariane/version'
require 'ariane/crumb'
+require 'ariane/levelcrumb'
require 'ariane/breadcrumb'
+require 'ariane/breadcrumb_stack'
require 'ariane/render'
require 'ariane/rails' if defined?(Rails)
module Ariane
class << self
attr_accessor :request
+
+
+ # Public: Provides a configuration option that instructs Ariane
+ # to use the session based BreadcrumbStack
+ #
+ #
+ # Examples
+ #
+ # Ariane.configure do |config|
+ # config.dynamic_breadcrumb = true
+ # end
+ #
+ # Returns a Boolean value indicating the current setting.
+ attr_accessor :dynamic_breadcrumb
# Public: Provides a simple way to access Ariane configuration.
#
@@ -32,7 +48,6 @@ def configure
# Returns nothing.
def request_env=(environment)
@request_env = environment
- @request_env[:breadcrumb] ||= Breadcrumb.new
end
# Internal: Gets the request environment.
@@ -42,6 +57,25 @@ def request_env
@request_env if defined?(@request_env)
end
+
+ # Internal: Sets the session
+ #
+ # If the :breadcrumb key is not present in the session, it will be set
+ # to a new instance of Breadcrumb.
+ #
+ # Returns nothing.
+ def session=(session)
+ @session = session
+ end
+
+ # Internal: Gets the user session hash
+ #
+ # Returns the session object
+ def session
+ @session if defined?(@session)
+ end
+
+
# Internal: Gets the request id.
#
# Returns the current request id.
@@ -62,14 +96,22 @@ def request=(request_id)
#
# Returns a Breadcrumb.
def breadcrumb
- @request_env[:breadcrumb]
+ if @dynamic_breadcrumb
+ @session[:breadcrumb] ||= BreadcrumbStack.new
+ else
+ @request_env[:breadcrumb] ||= Breadcrumb.new
+ end
end
# Internal: Sets the Breadcrumb.
#
# Returns nothing.
def breadcrumb=(breadcrumb)
- @request_env[:breadcrumb] = breadcrumb
+ if @dynamic_breadcrumb
+ @session[:breadcrumb] = breadcrumb
+ else
+ @request_env[:breadcrumb] = breadcrumb
+ end
end
# Public: Returns the default renderer used by Ariane.
@@ -105,5 +147,31 @@ def default_renderer
def default_renderer=(renderer)
@default_renderer = renderer.is_a?(Class) ? renderer.new : renderer
end
+
+ # Public: Returns session stack setting
+ #
+ # If true the session based breadcrumb is used, otherwise the static breadcrumb will be used.
+ #
+ # Returns the current or default option.
+ def dynamic_breadcrumb
+ defined?(@dynamic_breadcrumb) ? @dynamic_breadcrumb : false
+ end
+
+ # Public: Returns session stack setting
+ #
+ # If true the session based breadcrumb is used, otherwise the static breadcrumb will be used.
+ #
+ # use_session - The Boolean option value
+ #
+ # Examples
+ #
+ # Ariane.configure do |config|
+ # config.dynamic_breadcrumb = true
+ # end
+ #
+ # Returns the current option
+ def dynamic_breadcrumb=(use_session)
+ @dynamic_breadcrumb = use_session
+ end
end
end
@@ -0,0 +1,39 @@
+require 'ariane/crumb'
+
+module Ariane
+ # Internal: The BreadcrumbStack class is used to interact with the crumbs list.
+ #
+ # Examples
+ #
+ # ariane.add 'Home', root_path, 1
+ #
+ # ariane.render
+ class BreadcrumbStack < Ariane::Breadcrumb
+
+ # Public: Add a Crumb to the crumbs list.
+ #
+ # args - Any arguments that can be passed to Crumb#initialize.
+ #
+ # Yields the new Crumb before it is added to the list.
+ #
+ # Examples
+ #
+ # ariane.add 'Home', root_path, 1
+ # ariane.add 'Other', other_path, 2
+ # ariane.add 'Foo', root_path, 2, :foo => :bar
+ #
+ # Returns nothing.
+ def add(*args)
+ new_crumb = LevelCrumb.new(*args)
+ yield new_crumb if block_given?
+
+ crumbs.pop while crumbs.any? && crumbs.last.level >= new_crumb.level
+
+ crumbs << new_crumb
+ end
+
+ def clear
+ crumbs.clear
+ end
+ end
+end
View
@@ -6,7 +6,7 @@ class Crumb
# Public: Gets/Sets the String data of the crumb.
# Public: Gets/Sets the String text of the crumb.
# Public: Gets/Sets the String url of the crumb.
- attr_accessor :data, :text, :url
+ attr_accessor :text, :url, :data
# Internal: Initialize a Crumb.
#
View
@@ -0,0 +1,20 @@
+
+module Ariane
+ # Internal: Stores the data related to a single level-based crumb.
+ class LevelCrumb < Ariane::Crumb
+ # Public: Gets/Sets the Integer level of the crumb.
+ attr_accessor :level
+
+ # Internal: Initialize a Crumb.
+ #
+ # text - A String representing the text of the crumb (default: '').
+ # url - A String representing the url of the crumb (default: nil).
+ # level - An Integer value representing the level of the crumb (default: 1).
+ # data - A Hash used to store any data that can be used by renderers
+ # (default: {}).
+ def initialize(text='', url=nil, level=1, data={})
+ super text, url, data
+ @level = level
+ end
+ end
+end
@@ -1,14 +1,61 @@
module Ariane
# Adds the ariane helper to controllers.
module ControllerHelper
+
+ # Internal: Sets a hash of cumb levels
+ #
+ # levels - Hash of crumb levels for actions
+ #
+ # Sets a hash of crumb levels for actions that require custom levels
+ #
+ # Returns nothing.
+ def set_crumb_levels(levels)
+ @crumb_levels = levels
+ end
+
+ # Internal: Sets the Ariane environment
+ #
+ # Sets the Ariane per request environment as well assigns the session hash.
+ #
+ # Returns Ariane.breadcrumb
def ariane
if !Ariane.request_env || Ariane.request != request.object_id
Ariane.request = request.object_id
Ariane.request_env = request.env
- Ariane.breadcrumb = Breadcrumb.new
+ Ariane.session = session if Ariane.dynamic_breadcrumb
end
- Ariane.request_env[:breadcrumb]
+ Ariane.breadcrumb
+ end
+
+ # Public: Controller helper method for auto creation of breadcrums.
+ #
+ # Automatically sets the breadcrumb based on controller and action names.
+ #
+ # Returns nothing
+ def auto_set_breadcrumb
+ ariane.add("Home", root_path, 1) if ariane.crumbs.empty?
+
+ if self.action_name == "index"
+ name = controller_name.titleize
+ level = get_level || 2
+ else
+ name = "#{action_name.titleize} #{controller_name.singularize.titleize}"
+ level = get_level || 3
+ end
+
+ ariane.add(name, request.fullpath, level)
+ end
+
+
+ private
+
+ # Private: Helper method to retrieve a crumb level from the @crumb_levels hash
+ # if it exists.
+ #
+ # Returns level
+ def get_level
+ @crumb_levels[self.action_name.to_sym] || @crumb_levels[:default] if @crumb_levels
end
end
end
@@ -0,0 +1,103 @@
+require 'ariane'
+
+module Ariane
+ describe BreadcrumbStack do
+ subject { BreadcrumbStack.new }
+
+ before :each do
+ subject.clear
+ end
+
+ describe "#crumbs" do
+ it "has a crumbs method that returns an Enumerable" do
+ subject.crumbs.is_a?(Enumerable).should be_true
+ end
+
+ it "set the crumbs to an empty Enumerable by default" do
+ crumbs = subject.crumbs
+ crumbs.respond_to?(:count).should be_true
+ crumbs.count.should be(0)
+ end
+ end
+
+ describe "#add" do
+ it "creates a new crumb and pushes it to crumbs" do
+ subject.add 'text', 'url', 1, :foo => :bar
+ subject.crumbs.count.should be(1)
+ subject.crumbs.last.text.should == 'text'
+ subject.crumbs.last.url.should == 'url'
+ subject.crumbs.last.data.should == { :foo => :bar }
+ end
+
+ it "yields passing the new crumb if a block is given" do
+ subject.add 'text' do |crumb|
+ crumb.url = 'url'
+ end
+ subject.crumbs.last.url.should == 'url'
+ end
+
+ it "places a new crumb on the stack if the level is higher than the last" do
+ subject.add "home", "/", 1
+ subject.add "things", "/things", 2
+ subject.crumbs.count.should be(2)
+ subject.crumbs.last.text.should == 'things'
+ subject.crumbs.last.url.should == '/things'
+ end
+
+ it "replaces the last crumb on the stack if the new crumb level is equal to the last" do
+ subject.add "home", "/", 1
+ subject.add "twos", "/twos", 2
+ subject.add "threes", "/threes", 3
+
+ subject.crumbs.count.should be(3)
+ subject.crumbs.last.text.should == 'threes'
+ subject.crumbs.last.url.should == '/threes'
+ subject.crumbs.last.level.should == 3
+
+ subject.add "new_threes", "/new_threes", 3
+
+ subject.crumbs.count.should be(3)
+ subject.crumbs.last.text.should == 'new_threes'
+ subject.crumbs.last.url.should == '/new_threes'
+ subject.crumbs.last.level.should == 3
+ end
+
+ it "removes the last crumb on the stack if the new crumb level is less than the last" do
+ subject.add "home", "/", 1
+ subject.add "twos", "/twos", 2
+ subject.add "threes", "/threes", 3
+
+ subject.crumbs.count.should be(3)
+ subject.crumbs.last.text.should == 'threes'
+ subject.crumbs.last.url.should == '/threes'
+ subject.crumbs.last.level.should == 3
+
+ subject.add "new_twos", "/new_twos", 2
+
+ subject.crumbs.count.should be(2)
+ subject.crumbs.last.text.should == 'new_twos'
+ subject.crumbs.last.url.should == '/new_twos'
+ subject.crumbs.last.level.should == 2
+ end
+
+ it "removes all crumbs on the stack until the crumb level is less than or equal to the new level" do
+ subject.add "home", "/", 1
+ subject.add "twos", "/twos", 2
+ subject.add "threes", "/threes", 3
+ subject.add "fours", "/fours", 4
+
+ subject.crumbs.count.should be(4)
+ subject.crumbs.last.text.should == 'fours'
+ subject.crumbs.last.url.should == '/fours'
+ subject.crumbs.last.level.should == 4
+
+ subject.add "new_one", "/new_one", 1
+
+ subject.crumbs.count.should be(1)
+ subject.crumbs.last.text.should == 'new_one'
+ subject.crumbs.last.url.should == '/new_one'
+ subject.crumbs.last.level.should == 1
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit de75f34

Please sign in to comment.