Skip to content

Commit 0d15a29

Browse files
author
YorickPeterse
committed
Modified the helper Ramaze::Helper::Layout so that it allows you to call set_layout multiple times as well as setting layouts for multiple methods. A good example is the following:
set_layout 'my_layout' => [:index, :edit] set_layout 'default' => [:add] Please note that Ramaze::Helper::Layout#set_layout_except is deprecated and will issue a warning, you should use set_layout instead.
1 parent 4a8c10e commit 0d15a29

File tree

3 files changed

+113
-84
lines changed

3 files changed

+113
-84
lines changed

lib/ramaze/helper/layout.rb

Lines changed: 96 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,124 @@
11
module Ramaze
22
module Helper
3-
3+
##
44
# Provides wrapper methods for a higher-level approach than the core layout
5-
# method. These are useful for simpler layout needs, particularly:
5+
# method. The layout() method that comes with Innate/Ramaze is fairly basic as it only
6+
# allows you to specify a single layout to always use or a block giving you some extra
7+
# flexibility. The latter however is still a bit of a pain when dealing with many
8+
# custom layouts in a single controller. Meet the Layout helper. This helper provides
9+
# a single method (since April 2011, it used to provide more) called "set_layout".
10+
# This method allows you to specify a number of layouts and the methods for which
11+
# these layouts should be used.
12+
#
13+
# == Examples
14+
#
15+
# The most basic example is simply setting a layout as you would do with the layout()
16+
# method:
617
#
7-
# * layout all actions
8-
# * layout a whitelist of actions
9-
# * layout all but a blacklist of actions
18+
# set_layout 'default'
1019
#
11-
# As with the core layout method, the layout rules apply only to the
12-
# controller on which they are applied. Furthermore, multiple layout
13-
# definitions are not combined; only the last definition will be used.
20+
# This of course is very boring, time to add some more spices to our code:
1421
#
15-
# This helper is one of the default helpers, so no explicit helper call
16-
# is necessary before using it in your controllers.
22+
# set_layout 'default' => [:index]
1723
#
18-
# Usage:
24+
# Woah! What just happened? It's quite easy actually, we merely defined that the
25+
# layout called "default" should be used for the index method *only*. Pretty sweet
26+
# huh? It gets even better:
1927
#
20-
# class MainController < Controller
21-
# # Apply the default layout (e.g. ./layout/default.xhtml) to all
22-
# # three actions.
23-
# set_layout 'default'
24-
# def action1; end
25-
# def action2; end
26-
# def action3; end
27-
# end
28+
# set_layout 'default' => [:index, :edit], 'alternative' => [:add, :process]
2829
#
29-
# class MainController < Controller
30-
# # These two layout definitions accomplish the same thing. The
31-
# # first uses a whitelist, the second uses a blacklist.
32-
# set_layout 'default' => [:laid_out1, :laid_out2]
33-
# set_layout_except 'default' => [:not_laid_out1, :not_laid_out2]
30+
# A few things changed. First of all there are now two key/value groups. Each group
31+
# defines a layout (the key) and a set of methods (the value) for which each layout
32+
# should be used. In this case the layout "default" will be used for index() and edit()
33+
# but the layout "alternative" will be used for add() and process().
3434
#
35-
# def laid_out1; end
36-
# def laid_out2; end
35+
# Last but not least, multiple calls to set_layout will no longer override any
36+
# existing settings *unless* you actually specify the same method with a different
37+
# layout. This is possible because the set_layout method stores all these details in
38+
# an instance variable called "_ramaze_layouts".
39+
#
40+
# @author Yorick Peterse
41+
# @author Michael Fellinger
42+
# @author Pistos
3743
#
38-
# def not_laid_out1; end
39-
# def not_laid_out2; end
40-
# end
4144
module Layout
45+
46+
##
47+
# Extends the class that included this module so that the methods that this helper
48+
# provides can be called outside of instance of class methods.
49+
#
50+
# @param [Object] into The class that included this module.
51+
# @author Michael Fellinger
52+
# @author Pistos
53+
#
4254
def self.included(into)
4355
into.extend SingletonMethods
4456
end
4557

4658
module SingletonMethods
47-
# @param [String Hash] Either a layout name, or a single-element Hash
48-
# which maps a layout name to an Array containing a whitelist of
49-
# action names
50-
# @see set_layout_except Innate::Node::layout
51-
# @author Pistos, manveru
52-
# @example Use a layout named 'default' on all actions of the controller:
53-
# set_layout 'default'
54-
# @example Use a layout named 'default' on just the index and admin actions:
55-
# set_layout 'default' => [ :index, :admin ]
56-
def set_layout(hash_or_the_layout)
57-
if hash_or_the_layout.respond_to?(:to_hash)
58-
f = hash_or_the_layout.to_hash.find{|k,v| k && v }
59-
the_layout = f[0]
60-
whitelist = f[1].map{|action| action.to_s }
61-
else
62-
the_layout = hash_or_the_layout
63-
end
59+
##
60+
# The set_layout method allows you to specify a number of methods and their
61+
# layout. This allows you to use layout A for methods 1, 2 and 3 but layout B for
62+
# method 4.
63+
#
64+
# @example
65+
# # The key is the layout, the value an array of methods
66+
# set_layout 'default' => [:method_1], 'alternative' => [:method_2]
67+
#
68+
# # We can combine this method with layout()
69+
# layout 'default'
70+
# set_layout 'alternative' => [:method_1]
71+
#
72+
# # This is also perfectly fine
73+
# set_layout 'default'
74+
#
75+
# @author Yorick Peterse
76+
# @author Michael Fellinger
77+
# @author Pistos
78+
# @param [Hash/String] hash_or_layout Can either be a string or a hash. In case
79+
# it's a string it will directly be used as the layout. When setting a hash this
80+
# hash should have it's keys set to the layouts and it's values to an array of
81+
# methods that use the specific layout. For more information see the examples.
82+
#
83+
def set_layout(hash_or_layout)
84+
@_ramaze_layouts ||= {}
6485

65-
layout do |path, wish|
66-
if whitelist.nil? || whitelist.include?(path.to_s)
67-
the_layout
86+
# Extract the layout to use
87+
if hash_or_layout.respond_to?(:to_hash)
88+
# Invert the method/layout hash and save them so they don't get lost
89+
hash_or_layout.to_hash.each do |layout, methods|
90+
# Dirty but it works
91+
methods.each do |m|
92+
@_ramaze_layouts[m.to_s] = layout.to_s
93+
end
6894
end
69-
end
70-
end
7195

72-
# @param [String Hash] Either a layout name, or a single-element Hash
73-
# which maps a layout name to an Array containing a blacklist of
74-
# action names
75-
# @see set_layout Innate::Node::layout
76-
# @author Pistos, manveru
77-
# @example Use a layout named 'default' on all actions except the user_data action:
78-
# set_layout_except 'default' => [ :user_data ]
79-
def set_layout_except(hash_or_the_layout)
80-
if hash_or_the_layout.respond_to?(:to_hash)
81-
f = hash_or_the_layout.to_hash.find{|k,v| k && v }
82-
the_layout = f[0]
83-
blacklist = f[1].map{|action| action.to_s }
84-
else
85-
the_layout = hash_or_the_layout
86-
end
96+
# Only use the layout for the current method
97+
layout do |path|
98+
path = path.to_s
8799

88-
layout do |path, wish|
89-
if blacklist.nil? || !blacklist.include?(path.to_s)
90-
the_layout
100+
if @_ramaze_layouts.key?(path)
101+
@_ramaze_layouts[path]
102+
end
103+
end
104+
105+
else
106+
# This is pretty easy isn't it?
107+
layout do |path|
108+
hash_or_layout
91109
end
92110
end
93111
end
112+
113+
# People might get confused when all of a sudden set_layout_except is gone. This
114+
# warning should clear things up for them. This method can be removed a release
115+
# after (or later) this modified helper has been introduced.
116+
def set_layout_except(hash_or_layout)
117+
Ramaze.deprecated('set_layout_except', 'set_layout')
118+
end
119+
94120
end
95121
end
122+
96123
end
97124
end

spec/ramaze/helper/layout.rb

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,16 @@ def laid_out2; end
2222
def not_laid_out; end
2323
end
2424

25-
class LayoutHelper < Ramaze::Controller
25+
class LayoutHelperThree < Ramaze::Controller
2626
map '/three'
27-
set_layout_except 'default' => [:not_laid_out1, :not_laid_out2]
27+
set_layout 'default' => [:laid_out1], 'alternative' => [:laid_out2]
28+
set_layout 'default' => [:laid_out3]
2829

2930
def laid_out1; end
3031
def laid_out2; end
31-
32-
def not_laid_out1; end
33-
def not_laid_out2; end
32+
def laid_out3; end
3433
end
3534

36-
3735
describe Ramaze::Helper::Layout do
3836
behaves_like :rack_test
3937

@@ -61,19 +59,18 @@ def not_laid_out2; end
6159
last_response.body.should.not.match /laid out/
6260
end
6361

64-
it 'lays out all actions except a blacklist' do
62+
it 'Define a set of method specific layouts' do
6563
get '/three/laid_out1'
66-
last_response.status.should == 200
64+
last_response.status.should === 200
6765
last_response.body.should.match /laid out/
66+
6867
get '/three/laid_out2'
69-
last_response.status.should == 200
68+
last_response.status.should === 200
69+
last_response.body.should.match /alternative/
70+
71+
get '/three/laid_out3'
72+
last_response.status.should === 200
7073
last_response.body.should.match /laid out/
71-
get '/three/not_laid_out1'
72-
last_response.status.should == 200
73-
last_response.body.should.not.match /laid out/
74-
get '/three/not_laid_out2'
75-
last_response.status.should == 200
76-
last_response.body.should.not.match /laid out/
7774
end
7875

7976
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<em>alternative</em>
2+
3+
<div id="content">
4+
#@content
5+
</div>

0 commit comments

Comments
 (0)