taxis 0.0.1
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/.gitignore +7 -0
- data/Gemfile +5 -0
- data/LICENSE +20 -0
- data/README.md +42 -0
- data/Rakefile +2 -0
- data/app/controllers/admin/base_controller.rb +25 -0
- data/app/controllers/admin/taxonomies_controller.rb +58 -0
- data/app/controllers/admin/taxons_controller.rb +94 -0
- data/app/controllers/application_controller.rb +3 -0
- data/app/models/taxon.rb +62 -0
- data/app/models/taxonomy.rb +24 -0
- data/app/views/admin/taxonomies/_form.html.erb +4 -0
- data/app/views/admin/taxonomies/_js_head.html.erb +9 -0
- data/app/views/admin/taxonomies/_list.html.erb +20 -0
- data/app/views/admin/taxonomies/edit.erb +29 -0
- data/app/views/admin/taxonomies/index.html.erb +7 -0
- data/app/views/admin/taxonomies/new.html.erb +11 -0
- data/app/views/admin/taxons/_form.html.erb +5 -0
- data/app/views/admin/taxons/_taxon_table.html.erb +23 -0
- data/app/views/admin/taxons/edit.html.erb +10 -0
- data/app/views/layouts/admin.html.erb +30 -0
- data/config/routes.rb +16 -0
- data/lib/generators/taxis/install_generator.rb +67 -0
- data/lib/generators/taxis/migration_generator.rb +28 -0
- data/lib/generators/taxis/public/jsTree/jquery.jstree.js +3510 -0
- data/lib/generators/taxis/public/jsTree/themes/apple/bg.jpg +0 -0
- data/lib/generators/taxis/public/jsTree/themes/apple/d.png +0 -0
- data/lib/generators/taxis/public/jsTree/themes/apple/dot_for_ie.gif +0 -0
- data/lib/generators/taxis/public/jsTree/themes/apple/style.css +60 -0
- data/lib/generators/taxis/public/jsTree/themes/apple/throbber.gif +0 -0
- data/lib/generators/taxis/public/taxonomy.js +203 -0
- data/lib/generators/taxis/templates/create_taxonomies.rb +13 -0
- data/lib/generators/taxis/templates/create_taxons.rb +18 -0
- data/lib/taxis.rb +3 -0
- data/lib/taxis/engine.rb +10 -0
- data/lib/taxis/version.rb +3 -0
- data/taxis.gemspec +25 -0
- metadata +114 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (C) 2011 by End Point Corporation
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
|
20
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Taxis
|
|
2
|
+
Taxis is a simple Rails 3 plugin that will give you a taxonomy structure for your rails application. It was written with the intent of providing a category tree for e-commerce solutions. It is in early development right now so please feel free to submit issues and provide any feedback.
|
|
3
|
+
|
|
4
|
+
# Installation
|
|
5
|
+
|
|
6
|
+
gem install taxis
|
|
7
|
+
|
|
8
|
+
rails g taxis:install
|
|
9
|
+
|
|
10
|
+
# Dependencies
|
|
11
|
+
Taxis provides a very simple interface for administrating the taxonomy. This interface uses the jsTree javascript library, which is a plugin for jQuery. As such, the taxis:install generator installs the jquery-rails gem which removes the prototype framework from your application. If this is not desired, use the --skip-jquery option when you run the generator. The gem also depends on:
|
|
12
|
+
|
|
13
|
+
* stringex
|
|
14
|
+
* nested_set
|
|
15
|
+
|
|
16
|
+
# License
|
|
17
|
+
|
|
18
|
+
Copyright (C) 2011 by End Point Corporation
|
|
19
|
+
|
|
20
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
21
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
22
|
+
in the Software without restriction, including without limitation the rights
|
|
23
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
24
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
25
|
+
furnished to do so, subject to the following conditions:
|
|
26
|
+
|
|
27
|
+
The above copyright notice and this permission notice shall be included in
|
|
28
|
+
all copies or substantial portions of the Software.
|
|
29
|
+
|
|
30
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
31
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
32
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
33
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
34
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
35
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
36
|
+
THE SOFTWARE.
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Contributing
|
|
40
|
+
Fork, modify, send me a pull request
|
|
41
|
+
|
|
42
|
+
|
data/Rakefile
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class Admin::BaseController < ApplicationController
|
|
2
|
+
layout 'admin'
|
|
3
|
+
|
|
4
|
+
# For the gem
|
|
5
|
+
unloadable
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
protected
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def tree_children(taxon)
|
|
13
|
+
children = []
|
|
14
|
+
taxon.children.each do |taxon|
|
|
15
|
+
children << {
|
|
16
|
+
:attr => {:id => taxon.id.to_s},
|
|
17
|
+
:data => taxon.name,
|
|
18
|
+
:state => taxon.children.empty? ? "" : "closed"
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
return children
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
class Admin::TaxonomiesController < Admin::BaseController
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def index
|
|
5
|
+
@taxonomies = Taxonomy.all
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def show
|
|
9
|
+
@taxonomy = Taxonomy.find(params[:id])
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def new
|
|
13
|
+
@taxonomy = Taxonomy.new
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create
|
|
17
|
+
@taxonomy = Taxonomy.new(params[:taxonomy])
|
|
18
|
+
if @taxonomy.save
|
|
19
|
+
redirect_to edit_admin_taxonomy_url(@taxonomy), :notice => "Successfully created taxonomy."
|
|
20
|
+
else
|
|
21
|
+
render :action => 'new'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def edit
|
|
26
|
+
@taxonomy = Taxonomy.find(params[:id])
|
|
27
|
+
@tree = root_tree(@taxonomy)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def update
|
|
31
|
+
@taxonomy = Taxonomy.find(params[:id])
|
|
32
|
+
if @taxonomy.update_attributes(params[:taxonomy])
|
|
33
|
+
redirect_to admin_taxonomies_url, :notice => "Successfully updated taxonomy."
|
|
34
|
+
else
|
|
35
|
+
render :action => 'edit'
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def destroy
|
|
40
|
+
@taxonomy = Taxonomy.find(params[:id])
|
|
41
|
+
@taxonomy.destroy
|
|
42
|
+
redirect_to admin_taxonomies_url, :notice => "Successfully destroyed taxonomy."
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def root_tree(taxonomy)
|
|
49
|
+
tree = {
|
|
50
|
+
:attr => {:id => taxonomy.root.id.to_s, :rel => "root"},
|
|
51
|
+
:data => taxonomy.root.name,
|
|
52
|
+
:state => "open",
|
|
53
|
+
:children => tree_children(taxonomy.root)
|
|
54
|
+
}
|
|
55
|
+
return tree
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
class Admin::TaxonsController < Admin::BaseController
|
|
2
|
+
|
|
3
|
+
before_filter :find_taxonomy, :except => [:children]
|
|
4
|
+
|
|
5
|
+
def index
|
|
6
|
+
|
|
7
|
+
if @taxonomy
|
|
8
|
+
@taxons = @taxonomy.children.order(:pos)
|
|
9
|
+
else
|
|
10
|
+
@taxons = Taxon.all
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
respond_to do |format|
|
|
14
|
+
format.html # index.html.erb
|
|
15
|
+
format.json { render :json => @taxons}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def show
|
|
22
|
+
@taxon = Taxon.find(params[:id])
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def new
|
|
26
|
+
@taxon = Taxon.new
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create
|
|
30
|
+
@taxon = Taxon.new(params[:taxon])
|
|
31
|
+
if @taxon.save
|
|
32
|
+
redirect_to edit_admin_taxonomy_url(@taxon.taxonomy), :notice => "Successfully created taxon."
|
|
33
|
+
else
|
|
34
|
+
render :action => 'new'
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def edit
|
|
39
|
+
@taxon = Taxon.find(params[:id])
|
|
40
|
+
@taxonomy = @taxon.taxonomy
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def update
|
|
44
|
+
@taxon = Taxon.find(params[:id])
|
|
45
|
+
if @taxon.update_attributes(params[:taxon])
|
|
46
|
+
|
|
47
|
+
# Move the taxon to the correct position
|
|
48
|
+
if params[:left_of_id] != params[:parent_id]
|
|
49
|
+
@right_taxon = Taxon.find(params[:left_of_id])
|
|
50
|
+
@taxon.move_to_left_of(@right_taxon) if @right_taxon && @taxon.siblings.include?(@right_taxon)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if params[:format] == :json
|
|
54
|
+
render :json => "ok"
|
|
55
|
+
else
|
|
56
|
+
redirect_to edit_admin_taxonomy_url(@taxon.taxonomy), :notice => "Successfully updated taxon."
|
|
57
|
+
end
|
|
58
|
+
else
|
|
59
|
+
render :action => 'edit'
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def destroy
|
|
64
|
+
@taxon = Taxon.find(params[:id])
|
|
65
|
+
@taxon.destroy
|
|
66
|
+
redirect_to edit_admin_taxonomy_url(@taxon.taxonomy), :notice => "Successfully destroyed taxon."
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Action for getting the children of a taxon
|
|
71
|
+
# right now it only responds to json requests
|
|
72
|
+
def children
|
|
73
|
+
@taxon = Taxon.find params[:id]
|
|
74
|
+
@children = @taxon.children
|
|
75
|
+
@tree = tree_children(@taxon)
|
|
76
|
+
respond_to do |format|
|
|
77
|
+
format.html
|
|
78
|
+
format.json { render :json => @tree }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
def find_taxonomy
|
|
87
|
+
if params[:taxonomy_id]
|
|
88
|
+
@taxonomy = Taxonomy.find(params[:taxonomy_id])
|
|
89
|
+
else
|
|
90
|
+
@taxonomy = nil
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end
|
data/app/models/taxon.rb
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
class Taxon < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
acts_as_nested_set :dependent => :destroy
|
|
4
|
+
|
|
5
|
+
acts_as_url :name, :sync_url => true
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
belongs_to :taxonomy
|
|
9
|
+
|
|
10
|
+
before_create :set_path, :set_taxonomy
|
|
11
|
+
after_create :set_root
|
|
12
|
+
before_update :set_path
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# TODO: I don't love this implementation as it doesn't allow for effective navigation up the tree
|
|
16
|
+
# but it does provide a nice url breadcrumb trail
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Creates path based on .to_url method provided by stringx gem
|
|
20
|
+
def set_path
|
|
21
|
+
|
|
22
|
+
if self.root?
|
|
23
|
+
self.path = '/'
|
|
24
|
+
else
|
|
25
|
+
ancestor_path = parent_taxon.path rescue "/"
|
|
26
|
+
sep = ancestor_path == "/" ? "" : "/"
|
|
27
|
+
self.path = ancestor_path + sep + self.url
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
#if parent_id.nil?
|
|
31
|
+
#self.path = self.url if self.path.blank?
|
|
32
|
+
#else
|
|
33
|
+
#parent_taxon = Taxon.find(parent_id)
|
|
34
|
+
#self.path = [parent_taxon.path, (self.path.blank? ? name.to_url : self.path.split("/").last)].join('/')
|
|
35
|
+
#end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def set_taxonomy
|
|
39
|
+
if ! self.root?
|
|
40
|
+
self.root_id = parent_taxon.root_id
|
|
41
|
+
self.taxonomy_id = parent_taxon.taxonomy_id
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def set_root
|
|
46
|
+
self.root_id = self.id if self.root?
|
|
47
|
+
save
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def parent_taxon
|
|
55
|
+
@parent_taxon ||= Taxon.find(self.parent_id)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Taxonomy < ActiveRecord::Base
|
|
2
|
+
has_many :taxons
|
|
3
|
+
has_one :root, :class_name => 'Taxon', :conditions => "parent_id is null"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
after_create :create_root_taxon
|
|
7
|
+
before_destroy :delete_taxons
|
|
8
|
+
|
|
9
|
+
def create_root_taxon
|
|
10
|
+
self.taxons.create(:name => self.name + "__root")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Doing this through a callback because it doesn't
|
|
15
|
+
# rely on the destroy conditions of the taxons and
|
|
16
|
+
# makes deleting much more efficient
|
|
17
|
+
def delete_taxons
|
|
18
|
+
# TODO: More to do here.
|
|
19
|
+
# We probably will want to ensure that any items
|
|
20
|
+
# assigned to the taxons get reassigned or cleaned
|
|
21
|
+
# up appropriately.
|
|
22
|
+
Taxon.destroy_all(:taxonomy_id => self.id)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<% content_for :head do %>
|
|
2
|
+
<%= javascript_tag "var taxonomy_id = #{@taxonomy.id};
|
|
3
|
+
var loading = '#{escape_javascript t('loading')}';
|
|
4
|
+
var new_taxon = '#{escape_javascript t('new_taxon')}';
|
|
5
|
+
var server_error = '#{escape_javascript t('server_error')}';
|
|
6
|
+
var taxonomy_tree_error = '#{escape_javascript t('taxonomy_tree_error')}';"
|
|
7
|
+
%>
|
|
8
|
+
<%= javascript_include_tag 'taxonomy', 'jsTree/jquery.jstree.js' %>
|
|
9
|
+
<% end %>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<table class="index" id='listing_taxonomies'>
|
|
2
|
+
<tr>
|
|
3
|
+
<th><%= "Name" %></th>
|
|
4
|
+
<th> </th>
|
|
5
|
+
</tr>
|
|
6
|
+
<% for taxonomy in @taxonomies %>
|
|
7
|
+
<tr id="<%= dom_id taxonomy %>">
|
|
8
|
+
<td>
|
|
9
|
+
<%= taxonomy.name %>
|
|
10
|
+
</td>
|
|
11
|
+
<td class="actions">
|
|
12
|
+
<%= link_to "Edit", edit_admin_taxonomy_url(taxonomy.id), :class => 'edit' %>
|
|
13
|
+
|
|
14
|
+
<%= link_to "Delete", admin_taxonomy_path(taxonomy), :confirm => 'Are you sure?', :method => :delete %>
|
|
15
|
+
|
|
16
|
+
</td>
|
|
17
|
+
</tr>
|
|
18
|
+
<% end %>
|
|
19
|
+
</table>
|
|
20
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<%= render :partial => "js_head" %>
|
|
2
|
+
|
|
3
|
+
<h1><%= t("taxonomy_edit")%></h1>
|
|
4
|
+
|
|
5
|
+
<p id="ajax_error" class="errorExplanation" style="display:none;"></p>
|
|
6
|
+
|
|
7
|
+
<%= form_for(:taxon, :url => admin_taxonomy_url, :html => { :method => :put }) do |f| %>
|
|
8
|
+
<%= render :partial => 'form', :locals => {:f => f} %>
|
|
9
|
+
<div>
|
|
10
|
+
<label>Taxonomy Tree</label><br />
|
|
11
|
+
<div id="taxonomy_tree" class="tree"></div>
|
|
12
|
+
</div>
|
|
13
|
+
<p id="progress" style="display:none;">
|
|
14
|
+
<%= image_tag('spinner.gif', :alt => "Spinner", :style => "vertical-align:bottom") %>
|
|
15
|
+
<%= t('updating') %>..
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p class="form-buttons">
|
|
19
|
+
<%= f.submit %> <%= link_to "Back to Taxonomies", admin_taxonomies_path %>
|
|
20
|
+
</p>
|
|
21
|
+
<% end %>
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
<% content_for :head do %>
|
|
25
|
+
<script type="text/javascript">
|
|
26
|
+
var initial = <%= raw @tree.to_json %>;
|
|
27
|
+
|
|
28
|
+
</script>
|
|
29
|
+
<% end %>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
<h1><%= t("new_taxonomy") %></h1>
|
|
3
|
+
|
|
4
|
+
<%= form_for(:taxonomy, :url => '/admin/taxonomies') do |f| %>
|
|
5
|
+
|
|
6
|
+
<%= render :partial => "form", :locals => { :f => f } %>
|
|
7
|
+
|
|
8
|
+
<p class="form-buttons">
|
|
9
|
+
<%= f.submit %> or <%= link_to "Cancel", admin_taxonomies_url %>
|
|
10
|
+
</p>
|
|
11
|
+
<% end %>
|