|
1 | 1 | module Ramaze
|
2 | 2 | module Helper
|
3 |
| - |
| 3 | + ## |
4 | 4 | # 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: |
6 | 17 | #
|
7 |
| - # * layout all actions |
8 |
| - # * layout a whitelist of actions |
9 |
| - # * layout all but a blacklist of actions |
| 18 | + # set_layout 'default' |
10 | 19 | #
|
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: |
14 | 21 | #
|
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] |
17 | 23 | #
|
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: |
19 | 27 | #
|
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] |
28 | 29 | #
|
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(). |
34 | 34 | #
|
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 |
37 | 43 | #
|
38 |
| - # def not_laid_out1; end |
39 |
| - # def not_laid_out2; end |
40 |
| - # end |
41 | 44 | 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 | + # |
42 | 54 | def self.included(into)
|
43 | 55 | into.extend SingletonMethods
|
44 | 56 | end
|
45 | 57 |
|
46 | 58 | 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 ||= {} |
64 | 85 |
|
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 |
68 | 94 | end
|
69 |
| - end |
70 |
| - end |
71 | 95 |
|
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 |
87 | 99 |
|
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 |
91 | 109 | end
|
92 | 110 | end
|
93 | 111 | 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 | + |
94 | 120 | end
|
95 | 121 | end
|
| 122 | + |
96 | 123 | end
|
97 | 124 | end
|
0 commit comments