tkh_menus 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/CHANGELOG.md +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +79 -0
  4. data/Rakefile +38 -0
  5. data/app/controllers/menus_controller.rb +44 -0
  6. data/app/models/menu.rb +47 -0
  7. data/app/views/menus/_form.html.erb +13 -0
  8. data/app/views/menus/edit.html.erb +2 -0
  9. data/app/views/menus/index.html.erb +28 -0
  10. data/app/views/menus/new.html.erb +2 -0
  11. data/app/views/shared/_context_menu.html.erb +21 -0
  12. data/app/views/shared/_menu_for_navbar.html.erb +43 -0
  13. data/app/views/shared/_menus.html.erb +2 -0
  14. data/config/routes.rb +5 -0
  15. data/lib/generators/tkh_menus/create_or_update_locales/create_or_update_locales_generator.rb +14 -0
  16. data/lib/generators/tkh_menus/create_or_update_locales/templates/de.yml +26 -0
  17. data/lib/generators/tkh_menus/create_or_update_locales/templates/en.yml +26 -0
  18. data/lib/generators/tkh_menus/create_or_update_locales/templates/es.yml +26 -0
  19. data/lib/generators/tkh_menus/create_or_update_locales/templates/fr.yml +25 -0
  20. data/lib/generators/tkh_menus/create_or_update_migrations/create_or_update_migrations_generator.rb +24 -0
  21. data/lib/generators/tkh_menus/create_or_update_migrations/templates/create_menus.rb +17 -0
  22. data/lib/tasks/tkh_menus_tasks.rake +13 -0
  23. data/lib/tkh_menus/version.rb +3 -0
  24. data/lib/tkh_menus.rb +9 -0
  25. data/test/dummy/README.rdoc +261 -0
  26. data/test/dummy/Rakefile +7 -0
  27. data/test/dummy/app/assets/javascripts/application.js +15 -0
  28. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  29. data/test/dummy/app/controllers/application_controller.rb +3 -0
  30. data/test/dummy/app/helpers/application_helper.rb +2 -0
  31. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  32. data/test/dummy/config/application.rb +59 -0
  33. data/test/dummy/config/boot.rb +10 -0
  34. data/test/dummy/config/database.yml +25 -0
  35. data/test/dummy/config/environment.rb +5 -0
  36. data/test/dummy/config/environments/development.rb +37 -0
  37. data/test/dummy/config/environments/production.rb +67 -0
  38. data/test/dummy/config/environments/test.rb +37 -0
  39. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/test/dummy/config/initializers/inflections.rb +15 -0
  41. data/test/dummy/config/initializers/mime_types.rb +5 -0
  42. data/test/dummy/config/initializers/secret_token.rb +7 -0
  43. data/test/dummy/config/initializers/session_store.rb +8 -0
  44. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  45. data/test/dummy/config/locales/en.yml +5 -0
  46. data/test/dummy/config/routes.rb +58 -0
  47. data/test/dummy/config.ru +4 -0
  48. data/test/dummy/public/404.html +26 -0
  49. data/test/dummy/public/422.html +26 -0
  50. data/test/dummy/public/500.html +25 -0
  51. data/test/dummy/public/favicon.ico +0 -0
  52. data/test/dummy/script/rails +6 -0
  53. data/test/test_helper.rb +15 -0
  54. data/test/tkh_menus_test.rb +7 -0
  55. metadata +215 -0
data/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # TKH Menus
2
+
3
+
4
+
5
+ ## 0.0.1
6
+
7
+ * Initial release
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
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.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # TKH Menus
2
+
3
+ This Rails engine dynamically generates menus.
4
+
5
+ Primarily developed for Ten Thousand Hours but we are happy to share if anybody finds it useful. It's meant primarily to be used with other tkh gems and the TKH CMS eco-system but overtime we want it to be used individually as well. The latter implementation will be accelerated if some issues and pull requests come in, denoting some interest out there.
6
+
7
+ It's still embryonic but many improvements to come.
8
+
9
+
10
+ ## Pre-requisites
11
+
12
+ The following things are needed:
13
+
14
+ * Ruby 1.9.2 or later
15
+
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ gem 'tkh_menus', '~> 0.0'
22
+
23
+ Then execute:
24
+
25
+ $ bundle
26
+
27
+ Import migrations and needed files
28
+
29
+ $ rake tkh_menus:install
30
+
31
+ Run the migrations
32
+
33
+ $ rake db:migrate
34
+
35
+ And then of course restart your server!
36
+
37
+ $ rails s
38
+
39
+
40
+ ## Upgrading
41
+
42
+ Update the gem:
43
+
44
+ $ bundle update tkh_menus
45
+
46
+ Update files, migrations, etc. This is only needed with a new minor version number ( second level from left )
47
+
48
+ $ rake tkh_menus:update
49
+
50
+ Run migrations if there are new ones
51
+
52
+ $ rake db:migrate
53
+
54
+ Start your server!
55
+
56
+ $ rails s
57
+
58
+
59
+ ## Usage
60
+
61
+
62
+ The section is located at:
63
+
64
+ /menus
65
+
66
+ ... and it should work out of the box
67
+
68
+
69
+ ## Contributing
70
+
71
+ Pull requests for new features and bug fixes are welcome.
72
+
73
+ 1. Fork it
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Create your failing tests based on the Test Unit framework.
76
+ 4. Create your code which makes the tests pass.
77
+ 5. Commit your changes (`git commit -am 'Added some feature'`)
78
+ 6. Push to the branch (`git push origin my-new-feature`)
79
+ 7. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'TkhMenus'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ require 'rake/testtask'
29
+
30
+ Rake::TestTask.new(:test) do |t|
31
+ t.libs << 'lib'
32
+ t.libs << 'test'
33
+ t.pattern = 'test/**/*_test.rb'
34
+ t.verbose = false
35
+ end
36
+
37
+
38
+ task :default => :test
@@ -0,0 +1,44 @@
1
+ class MenusController < ApplicationController
2
+
3
+ before_filter :authenticate
4
+ before_filter :authenticate_with_admin
5
+
6
+ def index
7
+ @menus = Menu.ordered
8
+ switch_to_admin_layout
9
+ end
10
+
11
+ def new
12
+ @menu = Menu.new
13
+ switch_to_admin_layout
14
+ end
15
+
16
+ def edit
17
+ @menu = Menu.find(params[:id])
18
+ switch_to_admin_layout
19
+ end
20
+
21
+ def create
22
+ @menu = Menu.new(params[:menu])
23
+ if @menu.save
24
+ redirect_to menus_path, notice: t('menus.create.notice')
25
+ else
26
+ render action: "new", warning: t('menus.create.warning'), layout: 'admin'
27
+ end
28
+ end
29
+
30
+ def update
31
+ @menu = Menu.find(params[:id])
32
+ if @menu.update_attributes(params[:menu])
33
+ redirect_to menus_path, notice: t('menus.update.notice')
34
+ else
35
+ render action: "edit", warning: t('menus.update.warning'), layout: 'admin'
36
+ end
37
+ end
38
+
39
+ def destroy
40
+ @menu = Menu.find(params[:id])
41
+ @menu.destroy
42
+ redirect_to menus_url, notice: t('menus.destroy.notice')
43
+ end
44
+ end
@@ -0,0 +1,47 @@
1
+ # this is needed for now to make mass assignment security compatible with the translation of globalize3
2
+ Globalize::ActiveRecord::Translation.class_eval do
3
+ attr_accessible :locale
4
+ end
5
+
6
+ class Menu < ActiveRecord::Base
7
+
8
+ attr_accessible :name, :path, :position, :parent_id
9
+
10
+ validates_presence_of :name, :path
11
+
12
+ translates :name, :path
13
+
14
+ def to_param
15
+ name ? "#{id}-#{name.to_url}" : id
16
+ end
17
+
18
+ scope :ordered, order('position, id')
19
+ # tree scopes
20
+ scope :orphans, where('parent_id IS ?', nil)
21
+ scope :with_parent_id, lambda { |id| where('parent_id = ?', id) }
22
+
23
+ def orphan?
24
+ parent_id == nil
25
+ end
26
+
27
+ def has_children?
28
+ Menu.with_parent_id(id).count >= 1
29
+ end
30
+
31
+ def children
32
+ Menu.with_parent_id(id)
33
+ end
34
+
35
+ def parent
36
+ Menu.find(parent_id)
37
+ end
38
+
39
+ def has_siblings?
40
+ Menu.with_parent_id(parent_id).count >= 1
41
+ end
42
+
43
+ def siblings
44
+ Menu.with_parent_id(parent_id)
45
+ end
46
+
47
+ end
@@ -0,0 +1,13 @@
1
+ <%= simple_form_for @menu, :html => { class: 'form-horizontal' } do |f| %>
2
+ <%= f.error_notification %>
3
+
4
+ <div class="form-inputs">
5
+ <%= f.input :name, hint: 'should be rather short as it will figure in navbar and space there is at a premium' %>
6
+ <%= f.input :path, hint: 'the url the menu is pointing to' %>
7
+ <%= f.input :parent_id, hint: 'for nested menu items' %>
8
+ </div>
9
+
10
+ <div class="form-actions">
11
+ <%= f.button :submit, :class => 'btn btn-primary' %>
12
+ </div>
13
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <%= render 'form' %>
2
+ <%= render 'shared/admin_sidebar' %>
@@ -0,0 +1,28 @@
1
+ <h1>Listing Menus</h1>
2
+
3
+ <table class='table table-striped'>
4
+ <thead>
5
+ <tr>
6
+ <th><%= t( 'activerecord.attributes.menus.name').capitalize %></th>
7
+ <th><%= t( 'activerecord.attributes.menus.path').capitalize %></th>
8
+ <th><%= t( 'activerecord.attributes.menus.parent').capitalize %></th>
9
+ <th>Actions</th>
10
+ </tr>
11
+ </thead>
12
+
13
+ <tbody>
14
+ <% @menus.each do |menu| %>
15
+ <tr>
16
+ <td><%= menu.name %></td>
17
+ <td><%= menu.path %></td>
18
+ <td><%= "#{menu.parent.id} - #{menu.parent.name}" unless menu.orphan? %></td>
19
+ <td><%= link_to t('edit'), edit_menu_path(menu), class: 'btn btn-mini' %>
20
+ <%= link_to t('delete'), menu, method: :delete, data: { confirm: t('are_you_sure') }, class: 'btn btn-mini btn-danger' %></td>
21
+ </tr>
22
+ <% end %>
23
+ </tbody>
24
+ </table>
25
+
26
+ <%= link_to t('menus.create_new').capitalize, new_menu_path, class: 'btn btn-primary' %>
27
+
28
+ <%= render 'shared/admin_sidebar' %>
@@ -0,0 +1,2 @@
1
+ <%= render 'form' %>
2
+ <%= render 'shared/admin_sidebar' %>
@@ -0,0 +1,21 @@
1
+ <% content_for :context_menu do %>
2
+ <% if @page %>
3
+ <% if @page.has_children? %>
4
+ <h2><%= @page.nickname %></h2>
5
+ <ul>
6
+ <% for page in @page.children %>
7
+ <%= content_tag :li, link_to(page.nickname, page) %>
8
+ <% end %>
9
+ </ul>
10
+ <% end %>
11
+
12
+ <% if !@page.orphan? && @page.has_siblings? %>
13
+ <h2><%= link_to @page.parent.nickname, @page.parent %></h2>
14
+ <ul>
15
+ <% for page in @page.siblings %>
16
+ <%= content_tag :li, link_to(page.nickname, page) %>
17
+ <% end %>
18
+ </ul>
19
+ <% end %>
20
+ <% end -%>
21
+ <% end -%>
@@ -0,0 +1,43 @@
1
+ <% content_for :menu_for_navbar do %>
2
+ <% if Page.not_for_blog.published.orphans.count >= 1 %>
3
+ <% Page.not_for_blog.published.orphans.each do |page| %>
4
+ <% if page.has_children? %>
5
+ <li class='dropdown'>
6
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown"><%= page.nickname.downcase %> <b class="caret"></b></a>
7
+ <ul class="dropdown-menu">
8
+ <%= content_tag :li, link_to(page.nickname.downcase, page) %>
9
+ <li class="divider"></li>
10
+ <% page.children.each do |pc| %>
11
+ <%= content_tag :li, link_to(pc.nickname.downcase, pc) %>
12
+ <% end %>
13
+ </ul>
14
+ </li>
15
+ <% else %>
16
+ <%= content_tag :li, link_to(page.nickname.downcase, page) %>
17
+ <% end -%>
18
+ <% end %>
19
+ <% end -%>
20
+
21
+ <% if Page.for_blog.published.count >= 1 %>
22
+ <%= content_tag :li, link_to('blog', blog_path) %>
23
+ <% end -%>
24
+
25
+ <% if Menu.orphans.count >= 1 %>
26
+ <% Menu.orphans.ordered.each do |menu| %>
27
+ <% if menu.has_children? %>
28
+ <li class='dropdown'>
29
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">menu.name.downcase <b class="caret"></b></a>
30
+ <ul class="dropdown-menu">
31
+ <%= content_tag :li, link_to(menu.name.downcase, menu.path) %>
32
+ <li class="divider"></li>
33
+ <% menu.children.each do |mc| %>
34
+ <%= content_tag :li, link_to(mc.name.downcase, mc.path) %>
35
+ <% end %>
36
+ </ul>
37
+ </li>
38
+ <% else %>
39
+ <%= content_tag :li, link_to(menu.name.downcase, menu.path) %>
40
+ <% end -%>
41
+ <% end %>
42
+ <% end -%>
43
+ <% end %>
@@ -0,0 +1,2 @@
1
+ <%= render 'shared/menu_for_navbar' %>
2
+ <%= render 'shared/context_menu' %>
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ Rails.application.routes.draw do
2
+ scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
3
+ resources :menus
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ module TkhMenus
2
+ module Generators
3
+ class CreateOrUpdateLocalesGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+ desc "copying latest version of locale files"
6
+ def copy_locales
7
+ puts 'creating locale files'
8
+ I18n.available_locales.each do |l|
9
+ copy_file "#{l.to_s}.yml", "config/locales/tkh_menus.#{l.to_s}.yml"
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ de:
2
+
3
+ are_you_sure: 'are you sure?'
4
+ delete: 'delete'
5
+ edit: 'edit'
6
+ menus: 'menus'
7
+
8
+
9
+ activerecord:
10
+ attributes:
11
+ menus:
12
+ name: "name"
13
+ path: 'path'
14
+ parent: 'parent menu'
15
+
16
+ menus:
17
+ create_new: 'create new menu'
18
+
19
+ create:
20
+ notice: 'The menu was successfully created.'
21
+ warning: 'There was a problem saving the menu'
22
+ update:
23
+ notice: 'The menu was successfully updated.'
24
+ warning: 'There was a problem saving the menu'
25
+ destroy:
26
+ notice: 'The menu was deleted'
@@ -0,0 +1,26 @@
1
+ en:
2
+
3
+ are_you_sure: 'are you sure?'
4
+ delete: 'delete'
5
+ edit: 'edit'
6
+ menus: 'menus'
7
+
8
+
9
+ activerecord:
10
+ attributes:
11
+ menus:
12
+ name: "name"
13
+ path: 'path'
14
+ parent: 'parent menu'
15
+
16
+ menus:
17
+ create_new: 'create new menu'
18
+
19
+ create:
20
+ notice: 'The menu was successfully created.'
21
+ warning: 'There was a problem saving the menu'
22
+ update:
23
+ notice: 'The menu was successfully updated.'
24
+ warning: 'There was a problem saving the menu'
25
+ destroy:
26
+ notice: 'The menu was deleted'
@@ -0,0 +1,26 @@
1
+ es:
2
+
3
+ are_you_sure: 'are you sure?'
4
+ delete: 'delete'
5
+ edit: 'edit'
6
+ menus: 'menus'
7
+
8
+
9
+ activerecord:
10
+ attributes:
11
+ menus:
12
+ name: "name"
13
+ path: 'path'
14
+ parent: 'parent menu'
15
+
16
+ menus:
17
+ create_new: 'create new menu'
18
+
19
+ create:
20
+ notice: 'The menu was successfully created.'
21
+ warning: 'There was a problem saving the menu'
22
+ update:
23
+ notice: 'The menu was successfully updated.'
24
+ warning: 'There was a problem saving the menu'
25
+ destroy:
26
+ notice: 'The menu was deleted'
@@ -0,0 +1,25 @@
1
+ fr:
2
+
3
+ are_you_sure: 'êtes vous sûr ?'
4
+ delete: 'supprimer'
5
+ edit: 'modifier'
6
+ menus: 'menus'
7
+
8
+ activerecord:
9
+ attributes:
10
+ menus:
11
+ name: "nom"
12
+ path: 'adresse'
13
+ parent: 'menu parent'
14
+
15
+ menus:
16
+ create_new: 'créer un nouveau menu'
17
+
18
+ create:
19
+ notice: 'Le menu a été créé.'
20
+ warning: "Il y'a eu un probleme et le menu n'a pas été sauvegardé"
21
+ update:
22
+ notice: 'Les changements de ce menu ont été sauvegardés'
23
+ warning: "Il y'a eu un probleme et les changements de ce menu n'ont pas été sauvegardés"
24
+ destroy:
25
+ notice: 'Le menu a été supprimé'
@@ -0,0 +1,24 @@
1
+ require 'rails/generators/migration'
2
+
3
+ module TkhMenus
4
+ module Generators
5
+ class CreateOrUpdateMigrationsGenerator < ::Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+ source_root File.expand_path('../templates', __FILE__)
8
+ desc "create or update page migrations"
9
+ def self.next_migration_number(path)
10
+ unless @prev_migration_nr
11
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
12
+ else
13
+ @prev_migration_nr += 1
14
+ end
15
+ @prev_migration_nr.to_s
16
+ end
17
+
18
+ def copy_migrations
19
+ migration_template "create_menus.rb", "db/migrate/create_menus.rb"
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ class CreateMenus < ActiveRecord::Migration
2
+ def up
3
+ create_table :menus do |t|
4
+ t.string :name
5
+ t.string :path
6
+ t.integer :parent_id
7
+ t.integer :position
8
+ t.timestamps
9
+ end
10
+ Menu.create_translation_table! :name => :string, :path => :string
11
+ end
12
+
13
+ def down
14
+ drop_table :menus
15
+ Menu.drop_translation_table!
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ namespace :tkh_menus do
2
+ desc "Create migrations, locale, and other files"
3
+ task :install do
4
+ system 'rails g tkh_menus:create_or_update_migrations'
5
+ system 'rails g tkh_menus:create_or_update_locales -f'
6
+ end
7
+
8
+ desc "Update files. Skip existing migrations and blog layout. Force overwrite locales"
9
+ task :update do
10
+ system 'rails g tkh_menus:create_or_update_migrations -s'
11
+ system 'rails g tkh_menus:create_or_update_locales -f'
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module TkhMenus
2
+ VERSION = "0.0.1"
3
+ end
data/lib/tkh_menus.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "tkh_menus/version"
2
+ require 'simple_form'
3
+ require 'stringex'
4
+ require 'globalize3'
5
+
6
+ module TkhMenus
7
+ class Engine < ::Rails::Engine
8
+ end
9
+ end