ramenu 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ # Bundler
2
+ .bundle
3
+ pkg/*
4
+ Gemfile.lock
5
+
6
+ # YARD
7
+ .yardoc
8
+ yardoc/
9
+
10
+ # Vim
11
+ .*.swp
12
+
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - rbx-19mode
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+
4
+ ## master
5
+
6
+
7
+ ## Release 3.0.0
8
+
9
+ * Initial version, forked from breadcrumbs_on_rails gem, and adding :
10
+ - multi-level menus (to add alternate menus)
11
+ - multiple menus, to have different menus displayed at one time
12
+ - static menus to create static menus to be defined at one place
13
+ - flags to interact with menus and activate or toggle highlights for example
14
+ - definer method, to define the whole menu in one block
15
+ - documentation in readme file to create new builders and to use all the features
16
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2013 La Fourmi Immo
2
+ Including code Copyright (c) 2009-2012 Simone Carletti
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,372 @@
1
+ # Ramenu - Rails 'A la carte' menu
2
+
3
+ *Ramenu* is a simple Ruby on Rails plugin for creating and managing a menu navigation for a Rails project.
4
+ It provides helpers for creating navigation elements with a flexible interface.
5
+
6
+
7
+ ## Requirements
8
+
9
+ * Rails 3
10
+
11
+ ## Installation
12
+
13
+ [RubyGems](http://rubygems.org) is the preferred way to install *Ramenu* and the best way if you want install a stable version.
14
+
15
+ $ gem install ramenu
16
+
17
+ Specify the Gem dependency in the [Bundler](http://gembundler.com) `Gemfile`.
18
+
19
+ gem "ramenu"
20
+
21
+ Use [Bundler](http://gembundler.com) and the [:git option](http://gembundler.com/v1.0/git.html) if you want to grab the latest version from the Git repository.
22
+
23
+
24
+ ## Basic Usage
25
+
26
+ Creating a navigation menu in your Rails app using **Ramenu** is really straightforward.
27
+ There are two kinds of menus types, statics and volatiles. The first are kept whereas the second ones are only defined in controllers.
28
+ Aside to the menu, you may want to set flags to interact with you menu generator.
29
+
30
+ To define static menus, do it only once by creating an initializer, there will be availlable everywhere in your controllers.
31
+
32
+ # config/initializers/ramenu_config.rb
33
+ Ramenu.configure do |config|
34
+ # define a menu (by default, the :default menu is used)
35
+ config.add_menu :welcome, :root_path #, :menu => :default
36
+
37
+ # define a menu
38
+ config.add_menu :home, :root_path, :menu => :bottom_menu
39
+
40
+ # definer takes as argument the symbol name of the menus/flags to use
41
+ config.definer :main_menu do |d|
42
+ # add_menu method here takes the sames arguments as in a controller (see below)
43
+ d.add_menu :home, :root_path
44
+ d.add_menu :account, :root_path
45
+ d.add_menu :bien, :root_path
46
+ end
47
+
48
+ # definer have an optional argument to pass options.
49
+ # The main option is ':flag_for_menu'.
50
+ # Turn it to 'true' and your definer will associate a flag of the same name for each menu
51
+ # created. The flag is an option set in the menu element, and is later accessible in the
52
+ # builder, use it at your own convenience.
53
+ #
54
+ config.definer :main_menu, :flag_for_menu => true do |d|
55
+ # add_menu method here takes the sames arguments as in a controller (see below)
56
+ d.add_menu :home, :root_path
57
+ d.add_menu :account, :root_path
58
+ d.add_menu :bien, :root_path
59
+
60
+ # flags attributes can be set here
61
+ d.set_flag :home, true
62
+ d.set_flag :bien, false
63
+
64
+ # you can use as may flag as you need.
65
+ # theses options are accessible in your builders (see below)
66
+ d.add_menu :visits, :users_path, :right_icon => :visits_icon_flag
67
+
68
+ # and flag can be set with any value, boolean, or symbols for example
69
+ d.set_flag :visits_icon_flag, :waiting
70
+ end
71
+
72
+ end
73
+
74
+
75
+ In your controller, call `add_menu` to push a new element on the menu stack. `add_menu` requires two arguments: the name of the menu and the target path. See the section "Menus Element" for more details about name and target class types.
76
+ The third, optional argument is a Hash of options to customize the menu.
77
+
78
+ You can use the same definer as in the configuration, by calling `definer`, except that it will create a volatile block by default.
79
+ During the rendering, volatile menus/flags will merge with statics ones or override them if they have the same name.
80
+ Doing that, you can define default flags in the configuration, and change their values in the controllers.
81
+
82
+ class MyController
83
+
84
+ add_menu "home", :root_path
85
+ add_menu "my", :my_path
86
+
87
+ # you may specify the menus you want to use instead of the default one
88
+ add_menu "my", :my_path, :menu => :bottom_menu
89
+
90
+ # to add sub-menu (alternate menus for the same level)
91
+ add_menu :users, :users_path do |mm|
92
+ # add submenu using a symbol for translation (see translation below)
93
+ mm.add_menu :accounts, :accounts_path
94
+ # or a string
95
+ mm.add_menu "Profiles", :profiles_path
96
+ end
97
+
98
+ # to add a menu for current view
99
+ add_menu_for_current "My profile"
100
+
101
+ # definer takes as argument the symbol name of the menu/flags to use
102
+ definer :main_menu do |d|
103
+ d.add_menu :home, :root_path
104
+ d.add_menu :bien, :root_path
105
+ end
106
+
107
+ # definer in the controller takes the same optional argument as in the configuration, to pass options.
108
+ definer :main_menu, :flag_for_menu => true do |d|
109
+ d.add_menu :folder, :folders_path
110
+
111
+ # volatile flags override statics ones
112
+ d.set_flag :visits_icon_flag, :valid
113
+ end
114
+
115
+
116
+ def index
117
+ # ...
118
+
119
+ add_menu "index", index_path
120
+ end
121
+
122
+ def create
123
+ # definer in the controller takes the same optional argument as in the configuration, to pass options.
124
+ # By default, volatile blocks are defined in the controller. You may use the <tt>static</tt> option to create static block.
125
+ definer :main_menu, :flag_for_menu => true, :static => true do |d|
126
+ d.add_menu :account, :account_path
127
+
128
+ # flags attributes can be set here
129
+ d.set_flag :home, true
130
+ d.set_flag :bien, false
131
+
132
+ # you can use as may flag as you need.
133
+ # theses options are accessible in your builders (see below)
134
+ d.add_menu :cart, :cart_path, :right_icon => :cart_icon_flag
135
+
136
+ # and flag can be set with any value, boolean, or symbols for example
137
+ d.set_flag :cart_icon_flag, :waiting
138
+ end
139
+ end
140
+
141
+ end
142
+
143
+ In your view, you can render the menu menu with the `render_menus` helper.
144
+
145
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
146
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
147
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
148
+ <head>
149
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
150
+ <title>untitled</title>
151
+ </head>
152
+
153
+ <body>
154
+ <%= render_ramenu %>
155
+ </body>
156
+ </html>
157
+
158
+ `render_ramenu` understands a limited set of options. For example, you can pass change the default separator with the `:separator` option, or the default menu to use with the `:menu` option.
159
+
160
+ <body>
161
+ <%= render_ramenu :separator => ' / ', :menu => :side_menu_menu %>
162
+ </body>
163
+
164
+ More complex customizations require a custom Builder, see custom builder below.
165
+
166
+ ### Menus Element
167
+
168
+ A menu is composed by a number of `Element` objects. Each object contains two attributes: the name of the menu and the target path.
169
+
170
+ When you call `add_menu`, the method automatically creates a new `Element` object for you and append it to the menus stack. `Element` name and path can be one of the following Ruby types:
171
+
172
+ * Symbol
173
+ * Proc
174
+ * String
175
+
176
+ #### Symbol
177
+
178
+ If the value is a Symbol, it can be used for two different things.
179
+ At first, the library try to call the corresponding method in the same context and sets the `Element` attribute to the returned value.
180
+ Then, if no method are found with that name, the library search for a key in the translation. (see below for translation keys examples)
181
+
182
+ class MyController
183
+
184
+ # The Name is set to the value returned by
185
+ # the :root_name method.
186
+ add_menu :function_name, "/"
187
+ add_menu :translate_me, "/"
188
+
189
+ protected
190
+
191
+ def function_name
192
+ "the name"
193
+ end
194
+
195
+ end
196
+
197
+ #### Proc
198
+
199
+ If the value is a Proc, the library calls the proc passing the current view context as argument and sets the `Element` attribute to the returned value. This is useful if you want to postpone the execution to get access to some special methods/variables created in your controller action.
200
+
201
+ class MyController
202
+
203
+ # The Name is set to the value returned by
204
+ # the :root_name method.
205
+ add_menu Proc.new { |c| c.my_helper_method },
206
+ "/"
207
+
208
+ end
209
+
210
+ #### String
211
+
212
+ If the value is a String, the library sets the `Element` attribute to the string value.
213
+
214
+ class MyController
215
+
216
+ # The Name is set to the value returned by
217
+ # the :root_name method.
218
+ add_menu "homepage", "/"
219
+
220
+ end
221
+
222
+
223
+ ### Restricting menu scope
224
+
225
+ The `add_menu` method understands all options you are used to pass to a Rails controller filter.
226
+ In fact, behind the scenes this method uses a `before_filter` to store the tab in the `@ramenu_menus` variable.
227
+
228
+ Taking advantage of Rails filter options, you can restrict a tab to a selected group of actions in the same controller.
229
+
230
+ class PostsController < ApplicationController
231
+ add_menu "admin", :admin_path
232
+ add_menu "posts", :posts_path, :only => %w(index show)
233
+ end
234
+
235
+ class ApplicationController < ActionController::Base
236
+ add_menu "admin", :admin_path, :if => :admin_controller?
237
+
238
+ def admin_controller?
239
+ self.class.name =~ /^Admin(::|Controller)/
240
+ end
241
+ end
242
+
243
+ ### Internationalization and Localization
244
+
245
+ Ramenu is compatible with the standard Rails internationalization framework.
246
+
247
+ For our previous example, if you want to localize your menu, define a new menus node in your .yml file with all the keys for your elements.
248
+ The convention is 'ramenu.menus' followed by your menus symbol (:default by default) then by the menu hierachy.
249
+
250
+ add_menu :users, :users_path do |mm|
251
+ # add submenu using a symbol for translation (see translation below)
252
+ mm.add_child :accounts, :accounts_path
253
+ end
254
+
255
+ The menu itself is translated here by 'ramenu.menus.default.users.root', and the sub-menu is 'ramenu.menus.default.users.accounts'.
256
+
257
+ # config/locales/en.yml
258
+ en:
259
+ ramenu:
260
+ menus:
261
+ default:
262
+ translate_me: "Translated"
263
+ users:
264
+ root: "Menu title"
265
+ accounts: "Accounts sub menu"
266
+
267
+
268
+ In your controller, you can also use the `I18n.t` method directly as it returns a string.
269
+
270
+ class PostsController < ApplicationController
271
+ add_menu I18n.t("events.new_year"), :events_path
272
+ add_menu I18n.t("events.holidays"), :events_path, :only => %w(holidays)
273
+ end
274
+
275
+ class ApplicationController < ActionController::Base
276
+ add_menu I18n.t("homepage"), :root_path
277
+ end
278
+
279
+ ### Custom builder
280
+
281
+ If you need a specific menu, you'll need to define a custom builder.
282
+ To create such builder, add a file like the following.
283
+ In your builder, you can use `flag_for(element, [:name_of_the_flag])`, without its optional argument you'll get the flag named ':flag'
284
+
285
+ # /lib/ramenu/menus/html_builder.rb
286
+ module Ramenu
287
+ module Menus
288
+ # The HtmlBuilder is an html5 menu builder.
289
+ # It provides a simple way to render menu navigation as html5 tags.
290
+ # It may be used to display breadcrumbs-like menu or site menu, it is just a question of css.
291
+ #
292
+ # To use this custom Builder pass the option :builder => BuilderClass to the `render_ramenu` helper method.
293
+ #
294
+ class HtmlBuilder < Builder
295
+
296
+ def render
297
+ # creating nav id=breadcrumb
298
+ @context.content_tag(:nav, :id => @options[:id], :role => @options[:role]) do
299
+ render_elements(@elements)
300
+ end
301
+ end
302
+
303
+ def render_elements(elements)
304
+ content = nil
305
+ elements.each do |element|
306
+ if content.nil?
307
+ content = render_element(element)
308
+ else
309
+ content << render_element(element)
310
+ end
311
+ end
312
+ @context.content_tag(:ul, content)
313
+ end
314
+
315
+ def render_element(element)
316
+ name = compute_name(element)
317
+ path = compute_path(element)
318
+
319
+ content = @context.link_to(path, :title => name) do
320
+ @context.content_tag(:span, "#{name}", :class => 'label')
321
+ end
322
+
323
+ # rendering sub-elements
324
+ if element.childs.length > 0
325
+ content = content + render_elements(element.childs)
326
+ end
327
+
328
+ class_arr = []
329
+ class_arr << 'activ' if flag_for(element) == true
330
+ class_arr << 'highlight' if element.childs.length > 0
331
+ @context.content_tag(:li, content, :class => class_arr.compact.join(' '))
332
+ end
333
+ end
334
+ end
335
+ end
336
+
337
+
338
+ And do not forget to add /lib to rails autoload_paths by adding the following line.
339
+
340
+ # config/application.rb
341
+ module MyNiceRailsApplication
342
+ class Application < Rails::Application
343
+
344
+ ...
345
+
346
+ # Custom directories with classes and modules you want to be autoloadable.
347
+ # config.autoload_paths += %W(#{config.root}/extras)
348
+ config.autoload_paths += %W( #{config.root}/lib )
349
+
350
+ ...
351
+
352
+ end
353
+ end
354
+
355
+ Use your new builder by adding the builder option to the renderer.
356
+
357
+ <%= render_ramenu(:builder => Ramenu::Menus::HtmlBuilder) %>
358
+
359
+ ## Resources
360
+
361
+ * [Homepage](https://github.com/lafourmi/ramenu)
362
+ * [Documentation](https://github.com/lafourmi/ramenu)
363
+ * [API](http://rubydoc.info/gems/ramenu)
364
+ * [Repository](https://github.com/lafourmi/ramenu)
365
+ * [Issue Tracker](http://github.com/lafourmi/ramenu/issues)
366
+
367
+
368
+ ## License
369
+
370
+ *Ramenu* is Copyright (c) 2013 La Fourmi Immo.
371
+ This is Free Software distributed under the MIT license and include code from Simone Carletti Copyright (c) 2009-2012.
372
+ Some ideas (I18n, Configuration) comes from [stijnster/alacarte](https://github.com/stijnster/alacarte).
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'lib/ramenu'
7
+ t.libs << 'test' # to find test_helper
8
+ #t.test_files = FileList['test/lib/calendrier/*_test.rb']
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ #t.verbose = !!ENV["VERBOSE"]
11
+ t.verbose = true
12
+ end
13
+ task :default => :test