piggybak_taxonomy 0.0.2
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.
- data/LICENSE +20 -0
- data/README.md +16 -0
- data/Rakefile +40 -0
- data/app/controllers/piggybak_taxonomy/navigation_controller.rb +25 -0
- data/app/helpers/piggybak_taxonomy_helper.rb +32 -0
- data/app/models/piggybak_taxonomy/navigation_node.rb +43 -0
- data/app/models/piggybak_taxonomy/sellable_taxonomy.rb +23 -0
- data/app/views/piggybak_taxonomy/navigation/_breadcrumb.html.erb +14 -0
- data/app/views/piggybak_taxonomy/navigation/_pagination.html.erb +1 -0
- data/app/views/piggybak_taxonomy/navigation/_sellable.html.erb +3 -0
- data/app/views/piggybak_taxonomy/navigation/show.html.erb +11 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20121109164759_create_piggybak_taxonomy_navigation_nodes.rb +13 -0
- data/db/migrate/20121109164810_sellable_taxonomy.rb +9 -0
- data/lib/piggybak_taxonomy.rb +4 -0
- data/lib/piggybak_taxonomy/engine.rb +48 -0
- data/lib/piggybak_taxonomy/sellable_decorator.rb +10 -0
- data/lib/piggybak_taxonomy/version.rb +3 -0
- data/lib/tasks/piggybak_taxonomy_tasks.rake +4 -0
- metadata +118 -0
data/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,16 @@
|
|
1
|
+
PiggybakTaxonomy Gem (Engine)
|
2
|
+
========
|
3
|
+
|
4
|
+
Taxonomy support for Piggybak.
|
5
|
+
|
6
|
+
|
7
|
+
TODO
|
8
|
+
========
|
9
|
+
|
10
|
+
* Add configuration for per page default, forcing unique assignment
|
11
|
+
|
12
|
+
|
13
|
+
Copyright
|
14
|
+
========
|
15
|
+
|
16
|
+
Copyright (c) 2011 End Point & Steph Skardal. See LICENSE for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
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 = 'PiggybakTaxonomy'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module PiggybakTaxonomy
|
2
|
+
class NavigationController < ApplicationController
|
3
|
+
def show
|
4
|
+
paths = params[:path].split('/')
|
5
|
+
nodes = recursive_path(paths, [])
|
6
|
+
if nodes.empty?
|
7
|
+
redirect_to main_app.root_url, :status => 301
|
8
|
+
elsif nodes.size != params[:path].split('/').size
|
9
|
+
redirect_to piggybak_taxonomy_url(:path => nodes.last.nav_path), :status => 301
|
10
|
+
end
|
11
|
+
@node = nodes.last
|
12
|
+
end
|
13
|
+
|
14
|
+
def recursive_path(paths, nodes)
|
15
|
+
return nodes if paths.empty?
|
16
|
+
first = paths.shift
|
17
|
+
node = NavigationNode.find_by_slug(first)
|
18
|
+
if node && (nodes.empty? || node.parent == nodes.last) && !(nodes.empty? && !node.parent.nil?)
|
19
|
+
nodes << node
|
20
|
+
nodes = recursive_path(paths, nodes)
|
21
|
+
end
|
22
|
+
return nodes
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module PiggybakTaxonomyHelper
|
2
|
+
def taxonomy_breadcrumb(object)
|
3
|
+
if object.piggybak_sellable.navigation_nodes.any?
|
4
|
+
render "piggybak_taxonomy/navigation/breadcrumb",
|
5
|
+
:final_node => object.piggybak_sellable.navigation_nodes.first,
|
6
|
+
:link_last => true
|
7
|
+
else
|
8
|
+
#do nothing
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def render_navigation(wrapper_ul = true, nested_uls = true)
|
13
|
+
b = wrapper_ul ? "<ul>" : ""
|
14
|
+
::PiggybakTaxonomy::NavigationNode.all.select { |node| node.is_root? }.each do |node|
|
15
|
+
b << navigation_tree(node, nested_uls)
|
16
|
+
end
|
17
|
+
b << "</ul>" if wrapper_ul
|
18
|
+
b.html_safe
|
19
|
+
end
|
20
|
+
def navigation_tree(node, nested_uls)
|
21
|
+
result = "<li class=\"depth#{node.depth}\">" + link_to(node.title, piggybak_taxonomy.piggybak_taxonomy_url(:path => node.nav_path))
|
22
|
+
if node.children.any?
|
23
|
+
result << '<ul>' if nested_uls
|
24
|
+
node.children.each do |child|
|
25
|
+
result << navigation_tree(child, nested_uls)
|
26
|
+
end
|
27
|
+
result << '</ul>' if nested_uls
|
28
|
+
end
|
29
|
+
result << '</li>'
|
30
|
+
result
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module PiggybakTaxonomy
|
2
|
+
class NavigationNode < ActiveRecord::Base
|
3
|
+
self.table_name = "navigation_nodes"
|
4
|
+
|
5
|
+
has_many :sellable_taxonomies, :class_name => "::PiggybakTaxonomy::SellableTaxonomy"
|
6
|
+
has_many :sellables, :through => :sellable_taxonomies, :class_name => "::Piggybak::Sellable"
|
7
|
+
accepts_nested_attributes_for :sellable_taxonomies, :allow_destroy => true
|
8
|
+
attr_accessible :title, :slug, :position, :sellable_taxonomies_attributes #sellables_ids, :sellables
|
9
|
+
|
10
|
+
validates_presence_of :title
|
11
|
+
validates_presence_of :slug
|
12
|
+
|
13
|
+
validates_format_of :slug, :with => /^[a-z_]+$/
|
14
|
+
|
15
|
+
has_ancestry
|
16
|
+
|
17
|
+
validate :slug_not_page
|
18
|
+
def slug_not_page
|
19
|
+
if self.slug == "page"
|
20
|
+
self.errors.add(:slug, "invalid. 'page' is a reserved navigation indicator.")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def nav_path
|
25
|
+
"#{self.path.collect { |n| n.slug }.join('/')}"
|
26
|
+
end
|
27
|
+
def full_path
|
28
|
+
"/n/#{self.nav_path}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def recursive_sellables
|
32
|
+
results = self.sellables
|
33
|
+
self.children.each do |child|
|
34
|
+
results << child.recursive_sellables
|
35
|
+
end
|
36
|
+
results.flatten.uniq
|
37
|
+
end
|
38
|
+
# TODO: Add configuration for setting per page
|
39
|
+
def paginated_sellables(page, per = 10)
|
40
|
+
Kaminari.paginate_array(self.recursive_sellables).page(page).per(per)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module PiggybakTaxonomy
|
2
|
+
class SellableTaxonomy < ActiveRecord::Base
|
3
|
+
self.table_name = "sellable_taxonomies"
|
4
|
+
|
5
|
+
belongs_to :navigation_node, :class_name => "::PiggybakTaxonomy::NavigationNode"
|
6
|
+
belongs_to :sellable, :class_name => "::Piggybak::Sellable"
|
7
|
+
default_scope order('sort ASC')
|
8
|
+
|
9
|
+
validates_presence_of :sellable, :sort
|
10
|
+
|
11
|
+
def admin_label
|
12
|
+
"#{self.sellable.description.gsub('"', '"')} (#{self.sort})"
|
13
|
+
end
|
14
|
+
|
15
|
+
# TODO: Add as configuration
|
16
|
+
# validate :single_assignment
|
17
|
+
# def single_assignment
|
18
|
+
# if self.new_record? && !self.sellable.navigation_nodes.empty?
|
19
|
+
# self.errors.add(:sellable_id, "is already assigned to navigation node #{self.sellable.navigation_nodes.first.title}")
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<div id="taxonomy_breadcrumb">
|
2
|
+
<%= link_to "Home", main_app.root_url %> >
|
3
|
+
<% final_node.path.each do |node| -%>
|
4
|
+
<% if node == final_node -%>
|
5
|
+
<% if link_last -%>
|
6
|
+
<%= link_to node.title, piggybak_taxonomy.piggybak_taxonomy_url(:path => node.nav_path) %>
|
7
|
+
<% else -%>
|
8
|
+
<b><%= node.title %></b>
|
9
|
+
<% end -%>
|
10
|
+
<% else -%>
|
11
|
+
<%= link_to node.title, piggybak_taxonomy.piggybak_taxonomy_url(:path => node.nav_path) %> >
|
12
|
+
<% end -%>
|
13
|
+
<% end -%>
|
14
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= paginate @node.paginated_sellables(params[:page]) %>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= render :partial => "breadcrumb", :locals => { :final_node => @node, :link_last => false } %>
|
2
|
+
|
3
|
+
<%= render :partial => "pagination", :locals => { :node => @nodes } %>
|
4
|
+
|
5
|
+
<% if @node.recursive_sellables.any? -%>
|
6
|
+
<%= render :partial => "sellable", :collection => @node.paginated_sellables(params[:page]) %>
|
7
|
+
<% else -%>
|
8
|
+
There are no products.
|
9
|
+
<% end -%>
|
10
|
+
|
11
|
+
<%= render :partial => "pagination", :locals => { :node => @nodes } %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreatePiggybakTaxonomyNavigationNodes < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :navigation_nodes do |t|
|
4
|
+
t.string :title
|
5
|
+
t.string :slug
|
6
|
+
t.string :position
|
7
|
+
t.string :ancestry
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
add_index :navigation_nodes, :ancestry
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "ancestry"
|
2
|
+
require "rails_admin_nestable"
|
3
|
+
require "piggybak_taxonomy/sellable_decorator"
|
4
|
+
|
5
|
+
module PiggybakTaxonomy
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
isolate_namespace PiggybakTaxonomy
|
8
|
+
|
9
|
+
config.to_prepare do
|
10
|
+
Piggybak::Sellable.send(:include, ::PiggybakTaxonomy::SellableDecorator)
|
11
|
+
ApplicationController.class_eval do
|
12
|
+
helper :piggybak_taxonomy
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
initializer "piggybak_taxonomy.rails_admin_config" do |app|
|
17
|
+
RailsAdmin.config do |config|
|
18
|
+
config.model PiggybakTaxonomy::SellableTaxonomy do
|
19
|
+
label "Sellables"
|
20
|
+
edit do
|
21
|
+
field :sellable
|
22
|
+
field :sort
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
config.model PiggybakTaxonomy::NavigationNode do
|
27
|
+
navigation_label "Extensions"
|
28
|
+
label "Navigation Node"
|
29
|
+
|
30
|
+
nestable_tree({ position_field: :position, max_depth: 3 })
|
31
|
+
list do
|
32
|
+
field :title
|
33
|
+
field :slug
|
34
|
+
field :full_path
|
35
|
+
end
|
36
|
+
edit do
|
37
|
+
field :title
|
38
|
+
field :slug
|
39
|
+
field :sellable_taxonomies do
|
40
|
+
active true
|
41
|
+
label "Sellables"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module PiggybakTaxonomy
|
2
|
+
module SellableDecorator
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
has_many :sellable_taxonomies, :class_name => "::PiggybakTaxonomy::SellableTaxonomy"
|
7
|
+
has_many :navigation_nodes, :through => :sellable_taxonomies, :class_name => "::PiggybakTaxonomy::NavigationNode"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: piggybak_taxonomy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Steph Skardal
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.8
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.2.8
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: ancestry
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: piggybak_rails_admin_nestable
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
description: Piggybak Taxonomy - navigation support for Piggybak.
|
63
|
+
email:
|
64
|
+
- steph@endpoint.com
|
65
|
+
executables: []
|
66
|
+
extensions: []
|
67
|
+
extra_rdoc_files: []
|
68
|
+
files:
|
69
|
+
- app/controllers/piggybak_taxonomy/navigation_controller.rb
|
70
|
+
- app/models/piggybak_taxonomy/sellable_taxonomy.rb
|
71
|
+
- app/models/piggybak_taxonomy/navigation_node.rb
|
72
|
+
- app/helpers/piggybak_taxonomy_helper.rb
|
73
|
+
- app/views/piggybak_taxonomy/navigation/_pagination.html.erb
|
74
|
+
- app/views/piggybak_taxonomy/navigation/show.html.erb
|
75
|
+
- app/views/piggybak_taxonomy/navigation/_breadcrumb.html.erb
|
76
|
+
- app/views/piggybak_taxonomy/navigation/_sellable.html.erb
|
77
|
+
- config/routes.rb
|
78
|
+
- db/migrate/20121109164759_create_piggybak_taxonomy_navigation_nodes.rb
|
79
|
+
- db/migrate/20121109164810_sellable_taxonomy.rb
|
80
|
+
- lib/piggybak_taxonomy.rb
|
81
|
+
- lib/piggybak_taxonomy/sellable_decorator.rb
|
82
|
+
- lib/piggybak_taxonomy/engine.rb
|
83
|
+
- lib/piggybak_taxonomy/version.rb
|
84
|
+
- lib/tasks/piggybak_taxonomy_tasks.rake
|
85
|
+
- LICENSE
|
86
|
+
- Rakefile
|
87
|
+
- README.md
|
88
|
+
homepage: http://www.piggybak.org/
|
89
|
+
licenses: []
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
hash: -4607573029973200621
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
hash: -4607573029973200621
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 1.8.23
|
115
|
+
signing_key:
|
116
|
+
specification_version: 3
|
117
|
+
summary: Piggybak Taxonomy - navigation support for Piggybak.
|
118
|
+
test_files: []
|