ramenu 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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