buoys 0.1.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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +106 -0
  4. data/Rakefile +34 -0
  5. data/lib/buoys.rb +22 -0
  6. data/lib/buoys/buoy.rb +44 -0
  7. data/lib/buoys/config.rb +9 -0
  8. data/lib/buoys/helper.rb +31 -0
  9. data/lib/buoys/link.rb +51 -0
  10. data/lib/buoys/loader.rb +35 -0
  11. data/lib/buoys/renderer.rb +36 -0
  12. data/lib/buoys/version.rb +3 -0
  13. data/lib/generators/buoys/install_generator.rb +13 -0
  14. data/lib/generators/buoys/templates/_buoys.html.erb +14 -0
  15. data/lib/generators/buoys/templates/breadcrumbs.rb +38 -0
  16. data/lib/generators/buoys/templates/buoys.en.yml +4 -0
  17. data/lib/tasks/buoy_tasks.rake +4 -0
  18. data/test/buoys_buoy_test.rb +30 -0
  19. data/test/buoys_helper_test.rb +42 -0
  20. data/test/buoys_loader_test.rb +22 -0
  21. data/test/buoys_test.rb +7 -0
  22. data/test/dummy/README.rdoc +28 -0
  23. data/test/dummy/Rakefile +6 -0
  24. data/test/dummy/app/assets/javascripts/application.js +13 -0
  25. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  26. data/test/dummy/app/controllers/application_controller.rb +5 -0
  27. data/test/dummy/app/helpers/application_helper.rb +2 -0
  28. data/test/dummy/app/views/breadcrumbs/_buoys.erb +21 -0
  29. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  30. data/test/dummy/bin/bundle +3 -0
  31. data/test/dummy/bin/rails +4 -0
  32. data/test/dummy/bin/rake +4 -0
  33. data/test/dummy/bin/setup +29 -0
  34. data/test/dummy/config.ru +4 -0
  35. data/test/dummy/config/application.rb +26 -0
  36. data/test/dummy/config/boot.rb +5 -0
  37. data/test/dummy/config/buoys/breadcrumb.rb +13 -0
  38. data/test/dummy/config/buoys/buoys.rb +12 -0
  39. data/test/dummy/config/database.yml +25 -0
  40. data/test/dummy/config/environment.rb +5 -0
  41. data/test/dummy/config/environments/development.rb +41 -0
  42. data/test/dummy/config/environments/production.rb +79 -0
  43. data/test/dummy/config/environments/test.rb +42 -0
  44. data/test/dummy/config/initializers/assets.rb +11 -0
  45. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  46. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  47. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  48. data/test/dummy/config/initializers/inflections.rb +16 -0
  49. data/test/dummy/config/initializers/mime_types.rb +4 -0
  50. data/test/dummy/config/initializers/session_store.rb +3 -0
  51. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  52. data/test/dummy/config/locales/en.yml +27 -0
  53. data/test/dummy/config/routes.rb +4 -0
  54. data/test/dummy/config/secrets.yml +22 -0
  55. data/test/dummy/db/schema.rb +16 -0
  56. data/test/dummy/db/test.sqlite3 +0 -0
  57. data/test/dummy/log/test.log +719 -0
  58. data/test/dummy/public/404.html +67 -0
  59. data/test/dummy/public/422.html +67 -0
  60. data/test/dummy/public/500.html +66 -0
  61. data/test/dummy/public/favicon.ico +0 -0
  62. data/test/test_helper.rb +20 -0
  63. metadata +192 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d580b9e0f703c5a420c2c5e5ae42ef85df820a14
4
+ data.tar.gz: e3dab0c1686a54587cb32b3305bb46c5b84d8e80
5
+ SHA512:
6
+ metadata.gz: b9a93ab81d51ada4bf1fe6fcaab14028ca147bf849e1d4f2c07c6470d2e05e1f5ed881812ffeee2dc6f15343c89812b14ca9b25de0af4876dda605401e38abfb
7
+ data.tar.gz: fe1f9a8aea9f274505df6d2147aea91211d36d96f5929d6b26b0db1e987b53870ddb6c66381eb2a9812b0e83d5a8a81d6cca1dae4d424ba9add2d1f37b997a3a
@@ -0,0 +1,20 @@
1
+ Copyright 2016 muryoimpl
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,106 @@
1
+ # Buoys
2
+
3
+ Buoys is a Ruby on Rails breadcrumb plugin like [gretel](https://github.com/lassebunk/gretel).
4
+
5
+ ## Motivation
6
+
7
+ I like [gretel](https://github.com/lassebunk/gretel) and respect its idea, but I want to create simpler breadcrumb library like [gretel](https://github.com/lassebunk/gretel) using I18n.
8
+
9
+ ## Installation
10
+
11
+ In your Gemfile
12
+
13
+ ```ruby
14
+ gem 'buoys'
15
+ ```
16
+
17
+ And run:
18
+
19
+ ```ruby
20
+ $ bundle install
21
+ ```
22
+
23
+ ## Example
24
+
25
+ Start by generating configuration and example files.
26
+ ```ruby
27
+ $ bin/rails g buoys:install
28
+ create config/locale/buoys.en.yml
29
+ create app/views/breadcrumbs/_buoys.html.erb
30
+ create config/buoys/breadcrumbs.rb
31
+ ```
32
+
33
+ Then, in `config/buoys/breadcrumbs.rb`
34
+ ```ruby
35
+ buoy :stories do
36
+ link 'Stories', stories_path
37
+ end
38
+
39
+ # 'crumb' is the alias of 'buoy'
40
+ # ex)
41
+ crumb :stories do
42
+ link 'Stories', stories_path
43
+ end
44
+
45
+ # link's first argument, it is used as I18n key and defalt value.
46
+ # The key is searched in the scope of 'buoys.breadcrumbs'.
47
+ # ex)
48
+ buoy :story do |story|
49
+ link :story, story_path(story)
50
+ # same as `link I18n.t('story', scope: 'buoys.breadcrumbs', default: 'story'), story_path(story)`
51
+ end
52
+
53
+ # You can alse override Buoys configuration
54
+ # ex)
55
+ buoy :story_tasks do |story|
56
+ link :story_tasks, story_tasks_path
57
+ pre_buoy :story, story, {link_current: true}
58
+ end
59
+
60
+ # You can use 'pre_buoy' as parent. 'parent' is the alias of re_buoy`
61
+ # ex)
62
+ buoy :story_tasks do |story|
63
+ link :story_tasks, story_tasks_path
64
+ parent :story, story
65
+ end
66
+ ```
67
+
68
+ Then, set the current buoy(breadcrumb) at the top of view file (like `app/views/stories/index.html.erb`).
69
+
70
+ ```ruby
71
+ <% buoy :stories %>
72
+ ```
73
+
74
+ Then, in `app/views/layouts/application.html.erb`.
75
+ ```ruby
76
+ <%= render partial: 'breadcrumbs/buoys' %>
77
+ ```
78
+
79
+ Then, You can build and change breadcrumb `app/views/breadcrumbs/_buoys.html.erb`
80
+
81
+ ```erb
82
+ <% if buoys.any? %>
83
+ <ul>
84
+ <% buoys.each do |link| %>
85
+ <li>
86
+ <%# if 'link.current?' is true, link.options includes {class: 'current'}. %>
87
+ <%= link_to link.url, link.options do %>
88
+ <span><%= link.text %></span>
89
+ <% end %>
90
+ <% if !link.current? %>
91
+ <span> &gt;</span>
92
+ <% end %>
93
+ </li>
94
+ <% end %>
95
+ </ul>
96
+ <% end %>
97
+ ```
98
+
99
+ ## Options
100
+
101
+ | option | description | default |
102
+ | -------------- | ----------- | ------- |
103
+ | :link_current | whether current buoy(breadcrumb) should be linked to | false |
104
+ | :current_class | CSS class for current link. if you set `nil`, it is not set CSS class | 'active' |
105
+
106
+ Copyright (c) 2016 muryoimpl Released under the MIT license
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Buoy'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,22 @@
1
+ require 'buoys/version'
2
+ require 'buoys/config'
3
+ require 'buoys/loader'
4
+ require 'buoys/link'
5
+ require 'buoys/buoy'
6
+ require 'buoys/renderer'
7
+ require 'buoys/helper'
8
+
9
+ module Buoys
10
+ class << self
11
+ def buoy_file_paths
12
+ @buoy_file_paths ||= [
13
+ Rails.root.join('config', 'buoys', '**', '*.rb')
14
+ ]
15
+ end
16
+
17
+ def configure
18
+ yield Buoys::Config
19
+ end
20
+ end
21
+ end
22
+ ActionView::Base.send :include, Buoys::Helper
@@ -0,0 +1,44 @@
1
+ module Buoys
2
+ class Buoy
3
+ attr_reader :previous, :context
4
+ # buoy :account do
5
+ # link 'Account', account_path
6
+ # end
7
+ #
8
+ # buoy :account_edit do |account|
9
+ # link 'Account Show', show_account_path(account)
10
+ # link 'Account Edit', edit_account_path(account)
11
+ # pre_buoy :account
12
+ # end
13
+ def initialize(context, key, *args)
14
+ block = Buoys::Loader.buoys[key]
15
+ raise ArgumentError, "Buoys :#{key} is not found" unless block
16
+
17
+ @key, @context = key, context
18
+ instance_exec *args, &block
19
+ end
20
+
21
+ def link(key, *args)
22
+ options = args.extract_options!
23
+ path = args.shift
24
+ url = path ? context.url_for(path) : path
25
+
26
+ text = I18n.t(key, scope: 'buoys.breadcrumbs', default: key)
27
+
28
+ links << Buoys::Link.new(text, url, options)
29
+ end
30
+
31
+ def links
32
+ @links ||= []
33
+ end
34
+
35
+ def pre_buoy(key, *args)
36
+ @previous = Buoys::Buoy.new(context, key, args)
37
+ end
38
+ alias_method :parent, :pre_buoy
39
+
40
+ def method_missing(method, *args, &block)
41
+ context.send(method, *args, &block)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ module Buoys
2
+ class Config
3
+ class << self
4
+ attr_accessor :current_class
5
+
6
+ attr_accessor :link_current
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,31 @@
1
+ module Buoys
2
+ module Helper
3
+ # Declare the breadcrumb which want to render in view.
4
+ #
5
+ # <%= buoy :help, true %>
6
+ def buoy(key, *args)
7
+ @_buoys_renderer = Buoys::Renderer.new(self, key, *args)
8
+ end
9
+ alias_method :breadcrumb, :buoy
10
+
11
+ # <% buoys.tap do |links| %>
12
+ # <% if links.any? %>
13
+ # <ul>
14
+ # <% links.each do |link| %>
15
+ # <li class="<%= link.class %>">
16
+ # <%= link_to link.text, link.url %>
17
+ # </li>
18
+ # <% end %>
19
+ # </ul>
20
+ # <% end %>
21
+ # <% end %>
22
+ def buoys
23
+ buoys_renderer.render
24
+ end
25
+ alias_method :breadcrumbs, :buoys
26
+
27
+ def buoys_renderer
28
+ @_buoys_renderer ||= Buoys::Renderer.new(self, nil)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,51 @@
1
+ module Buoys
2
+ class Link
3
+ attr_accessor :text, :options, :options_for_config
4
+ attr_reader :current
5
+
6
+ CONFIG = {
7
+ current_class: (Buoys::Config.current_class || 'active'),
8
+ link_current: (Buoys::Config.link_current || false),
9
+ }.with_indifferent_access
10
+
11
+ def initialize(text, url, options)
12
+ @options_for_config, @options = extract_options_and_config(options)
13
+ @text, @_url = text, url
14
+ @current = false
15
+ end
16
+
17
+ def mark_as_current!
18
+ options.merge!(class: config[:current_class])
19
+ @current = true
20
+ end
21
+
22
+ def current?
23
+ !!@current
24
+ end
25
+
26
+ def url
27
+ return '' if current? && !config[:link_current]
28
+
29
+ @_url || ''
30
+ end
31
+
32
+ def url=(str)
33
+ @_url = str
34
+ end
35
+
36
+ private
37
+
38
+ def config
39
+ CONFIG.merge(options_for_config)
40
+ end
41
+
42
+ def extract_options_and_config(_options)
43
+ options = _options.with_indifferent_access
44
+ config = (options.keys & CONFIG.keys).each_with_object({}) {|key, hash|
45
+ hash[key] = options.delete(key)
46
+ }
47
+
48
+ [config, options]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,35 @@
1
+ module Buoys
2
+ class Loader
3
+ class << self
4
+ #
5
+ # buoy :account do
6
+ # link 'Account', account_path
7
+ # end
8
+ #
9
+ # buoy :account_edit do |account|
10
+ # link 'Account Edit', edit_account_path(account)
11
+ # pre_buoy :account
12
+ # end
13
+ def buoy(key, &block)
14
+ buoys[key] = block
15
+ end
16
+ alias_method :crumb, :buoy
17
+
18
+ def buoys
19
+ @buoys ||= {}
20
+ end
21
+
22
+ def load_buoys_files
23
+ buoys.clear
24
+
25
+ buoy_files.each do |file|
26
+ instance_eval open(file).read, file
27
+ end
28
+ end
29
+
30
+ def buoy_files
31
+ Dir[*Buoys.buoy_file_paths]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ module Buoys
2
+ class Renderer
3
+ def initialize(context, key, *args)
4
+ @context, @key, @args = context, key, *args
5
+ Buoys::Loader.load_buoys_files if Buoys::Loader.buoys.keys.empty?
6
+ end
7
+
8
+ def render
9
+ return [] unless @key
10
+
11
+ buoy = Buoys::Buoy.new(@context, @key, @args)
12
+ build_links(buoy)
13
+ end
14
+
15
+ private
16
+
17
+ def build_links(buoy)
18
+ links = buoy.links.dup
19
+
20
+ links.unshift *collect_previous_links(buoy)
21
+ links.last.mark_as_current!
22
+
23
+ links
24
+ end
25
+
26
+ def collect_previous_links(buoy)
27
+ links = []
28
+
29
+ while buoy = buoy.previous
30
+ links.unshift *buoy.links
31
+ end
32
+
33
+ links
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Buoys
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,13 @@
1
+ require 'rails/generators'
2
+
3
+ module Buoys
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def create_files
8
+ copy_file 'buoys.en.yml', 'config/locales/buoys.en.yml'
9
+ copy_file '_buoys.html.erb', 'app/views/breadcrumbs/_buoys.html.erb'
10
+ copy_file 'breadcrumbs.rb', 'config/buoys/breadcrumbs.rb'
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ <% if buoys.any? %>
2
+ <ol class="breadcrumb">
3
+ <% buoys.each do |link| %>
4
+ <li>
5
+ <%# if `link.current?` is true, link.options includes {class: 'current'}. %>
6
+ <% if link.current? %>
7
+ <span><%= link.text %></span>
8
+ <% else %>
9
+ <%= link_to link.text, link.url, link.options %>
10
+ <% end %>
11
+ </li>
12
+ <% end %>
13
+ </ol>
14
+ <% end %>
@@ -0,0 +1,38 @@
1
+ buoy :example do
2
+ link :example, 'http://localhost:3000'
3
+ end
4
+
5
+ # buoy :stories do
6
+ # link 'Stories', stories_path
7
+ # end
8
+
9
+ # `crumb` is the alias of `buoy`.
10
+ # ex)
11
+ # crumb :stories do
12
+ # link 'Stories', stories_path
13
+ # end
14
+
15
+ # link's first argument, it is used as I18n key and defalt value.
16
+ # The key is searched in the scope of 'buoys.breadcrumbs'.
17
+ #
18
+ # ex)
19
+ # buoy :story do |story|
20
+ # link :story, story_path(story)
21
+ # # same as `link I18n.t(:story, scope: 'buoys.breadcrumbs', default: story), story_path(story)`
22
+ # end
23
+
24
+ # You can alse override Buoys configuration
25
+ #
26
+ # ex)
27
+ # buoy :story_tasks do |story|
28
+ # link :story_tasks, story_tasks_path
29
+ # pre_buoy :story, story, {link_current: true}
30
+ # end
31
+
32
+ # You can use `pre_buoy` as parent. `parent` is the alias of `pre_buoy`
33
+ #
34
+ # ex)
35
+ # buoy :story_tasks do |story|
36
+ # link :story_tasks, story_tasks_path
37
+ # parent :story, story
38
+ # end