adva-categories 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/app/controllers/admin/categories_controller.rb +4 -0
- data/app/controllers/base_controller_slice.rb +9 -0
- data/app/helpers/url_helper_slice.rb +16 -0
- data/app/models/categorization.rb +5 -0
- data/app/models/category.rb +8 -0
- data/app/models/content_slice.rb +15 -0
- data/app/views/admin/categories/_form.html.rb +17 -0
- data/app/views/admin/categories/_menu.html.rb +19 -0
- data/app/views/admin/categories/edit.html.rb +9 -0
- data/app/views/admin/categories/index.html.rb +19 -0
- data/app/views/admin/categories/new.html.rb +10 -0
- data/config/locales/en.yml +30 -0
- data/config/redirects.rb +4 -0
- data/config/routes.rb +13 -0
- data/lib/adva/categories.rb +11 -0
- data/lib/adva/routing_filters/categories.rb +81 -0
- data/lib/adva-categories.rb +1 -0
- data/lib/testing/factories.rb +4 -0
- data/lib/testing/paths.rb +15 -0
- data/lib/testing/step_definitions.rb +21 -0
- metadata +100 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
require_dependency 'url_helper'
|
2
|
+
|
3
|
+
UrlHelper.module_eval do
|
4
|
+
include do
|
5
|
+
def public_url_for(resources, options = {})
|
6
|
+
reject = lambda { |resource| resource.is_a?(Category) }
|
7
|
+
rejected = resources.select(&reject)
|
8
|
+
rejected.map! { |resource| [resource.class.name.foreign_key, resource.id] }
|
9
|
+
|
10
|
+
resources.reject!(&reject)
|
11
|
+
options.merge!(Hash[*rejected.flatten])
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_dependency 'category'
|
2
|
+
require_dependency 'content'
|
3
|
+
|
4
|
+
Category.has_many_polymorphs :categorizables, :through => :categorizations, :foreign_key => 'category_id', :from => [:contents]
|
5
|
+
|
6
|
+
Content.class_eval do
|
7
|
+
has_many :categories, :through => :categorizations, :as => :categorizable
|
8
|
+
accepts_nested_attributes_for :categorizations, :allow_destroy => true
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def categorized(category_id)
|
12
|
+
includes(:categorizations).where(:categorizations => { :category_id => category_id })
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Admin::Categories::Menu < Adva::View::Menu::Admin::Actions
|
2
|
+
include do
|
3
|
+
def main
|
4
|
+
label("#{parent_resource.class.name}:")
|
5
|
+
item(:'admin.categories.menu.categories', index_path)
|
6
|
+
item(:'admin.categories.menu.edit', edit_parent_path)
|
7
|
+
end
|
8
|
+
|
9
|
+
def right
|
10
|
+
item(:'.new', new_path)
|
11
|
+
if resource.try(:persisted?)
|
12
|
+
item(:'.destroy', resource_path, :method => :delete, :confirm => t(:'.confirm_destroy', :model_name => resource.class.model_name.human))
|
13
|
+
else
|
14
|
+
item(:'.reorder', show_parent_path, :class => 'reorder', :'data-resource_type' => parent_resource.class.name.underscore, :'data-sortable_type' => 'categories')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class Admin::Categories::Index < Minimal::Template
|
2
|
+
include do
|
3
|
+
def to_html
|
4
|
+
table_for collection do |t|
|
5
|
+
t.column :category, :actions
|
6
|
+
|
7
|
+
t.row do |r, category|
|
8
|
+
r.options[:id] = dom_id(category)
|
9
|
+
r.cell capture { link_to_edit(category.name, category) }
|
10
|
+
r.cell links_to_actions([:edit, :destroy], category)
|
11
|
+
end
|
12
|
+
|
13
|
+
t.empty :p, :class => 'categories list empty' do
|
14
|
+
self.t(:'.empty', :link => capture { link_to(:'.create_item', new_path(:category)) }).html_safe
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
en:
|
2
|
+
categories:
|
3
|
+
columns:
|
4
|
+
category: Category
|
5
|
+
actions: ""
|
6
|
+
admin:
|
7
|
+
categories:
|
8
|
+
menu:
|
9
|
+
categories: Categories
|
10
|
+
products: Products
|
11
|
+
new: New Category
|
12
|
+
edit: Settings
|
13
|
+
destroy: Delete
|
14
|
+
reorder: Reorder
|
15
|
+
confirm_destroy: Do you really want to delete this category?
|
16
|
+
columns:
|
17
|
+
category: Category
|
18
|
+
actions:
|
19
|
+
index:
|
20
|
+
create_item: Create Category
|
21
|
+
edit: Edit
|
22
|
+
destroy: Delete
|
23
|
+
confirm_destroy: Do you really want to delete this category?
|
24
|
+
empty: "There are no categories. %{link}"
|
25
|
+
new:
|
26
|
+
title: Create a Category
|
27
|
+
edit:
|
28
|
+
title: Edit Category
|
29
|
+
tabs:
|
30
|
+
categories: Categories
|
data/config/redirects.rb
ADDED
data/config/routes.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'routing_filter'
|
2
|
+
|
3
|
+
module RoutingFilter
|
4
|
+
class Categories < Filter
|
5
|
+
cattr_accessor :default_port
|
6
|
+
self.default_port = '80'
|
7
|
+
|
8
|
+
cattr_accessor :exclude
|
9
|
+
self.exclude = %r(^/admin)
|
10
|
+
|
11
|
+
def around_recognize(path, env, &block)
|
12
|
+
# p "#{self.class.name}: #{path}"
|
13
|
+
unless excluded?(path)
|
14
|
+
category_id = extract_category_id(env, path)
|
15
|
+
yield.tap do |params|
|
16
|
+
params[:category_id] = category_id if category_id
|
17
|
+
end
|
18
|
+
else
|
19
|
+
yield
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def around_generate(params, &block)
|
24
|
+
category_id = params.delete('category_id') || params.delete(:category_id)
|
25
|
+
yield.tap do |path|
|
26
|
+
# p "#{self.class.name}: #{path}"
|
27
|
+
insert_category_path(path, category_id) if !excluded?(path) && category_id
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def excluded?(path)
|
34
|
+
path =~ exclude
|
35
|
+
end
|
36
|
+
|
37
|
+
def extract_category_id(env, path)
|
38
|
+
if section = section_for(env, path) and path =~ recognition_pattern(section)
|
39
|
+
if category = section.categories.where(:path => $2).first
|
40
|
+
path.gsub!("#{$1}#{$2}", '')
|
41
|
+
path.replace('/') if path.blank?
|
42
|
+
category.id.to_s
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def recognition_pattern(section)
|
48
|
+
paths = section.categories.map(&:path).reject(&:blank?)
|
49
|
+
paths = paths.sort { |a, b| b.size <=> a.size }.join('|')
|
50
|
+
paths.empty? ? %r(^$) : %r(^.*(/categories/)(#{paths})(?=/|\.|\?|$))
|
51
|
+
end
|
52
|
+
|
53
|
+
def insert_category_path(path, category_id)
|
54
|
+
category = Category.find(category_id)
|
55
|
+
if path =~ section_pattern
|
56
|
+
path.sub!("/#{$1}/#{$2}", "/#{$1}/#{$2}/categories/#{category.path}")
|
57
|
+
elsif category.section.root?
|
58
|
+
path.sub!(%r(^/), "/categories/#{category.path}")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def section_pattern
|
63
|
+
types = Section.types.map { |type| type.downcase.pluralize }.join('|')
|
64
|
+
%r(/(sections|#{types})/(\d+)(?=/|\.|\?|$))
|
65
|
+
end
|
66
|
+
|
67
|
+
def section_for(env, path)
|
68
|
+
if path =~ section_pattern
|
69
|
+
Section.find($2)
|
70
|
+
elsif path =~ %r(^/categories/\w+) && site = Site.by_host(host(env))
|
71
|
+
site.sections.root
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def host(env)
|
76
|
+
host, port = env.values_at('SERVER_NAME', 'SERVER_PORT')
|
77
|
+
port == default_port ? host : [host, port].compact.join(':')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'adva/categories'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Adva::Categories::Paths
|
2
|
+
def path_to(page)
|
3
|
+
case page
|
4
|
+
when /^the admin "([^"]*)" section categories page$/
|
5
|
+
site = Site.first
|
6
|
+
section = Section.where(:name => $1).first || raise("could not find section named #{$1}")
|
7
|
+
polymorphic_path([:admin, site, section, :categories])
|
8
|
+
else
|
9
|
+
super
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
World(Adva::Categories::Paths)
|
15
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
When /^I drag the category "([^"]*)" below the category "([^"]*)"$/ do |category, target|
|
2
|
+
category = Category.find_by_name(category)
|
3
|
+
target = Category.find_by_name(target)
|
4
|
+
section = Section.first
|
5
|
+
put(admin_site_section_path(section.site, section), {
|
6
|
+
:section => { :categories_attributes => [{ :id => category.id, :left_id => target.id }] },
|
7
|
+
:return_to => @request.url
|
8
|
+
})
|
9
|
+
follow_redirect!
|
10
|
+
end
|
11
|
+
|
12
|
+
Then /^the ([\w]+) (name|title)d "([^"]+)" should be categorized as "([^"]+)"$/ do |model, attribute, value, category|
|
13
|
+
record = model.classify.constantize.where(attribute => value).first
|
14
|
+
assert record.categories.map(&:name).include?(category), "expected #{record.inspect} to be categorized as #{category}"
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^the ([\w]+) (name|title)d "([^"]+)" should not be categorized as "([^"]+)"$/ do |model, attribute, value, category|
|
18
|
+
record = model.classify.constantize.where(attribute => value).first
|
19
|
+
assert !record.categories.map(&:name).include?(category), "expected #{record.inspect} not to be categorized as #{category}"
|
20
|
+
end
|
21
|
+
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: adva-categories
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ingo Weiss
|
14
|
+
- Sven Fuchs
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2010-10-29 00:00:00 +02:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: adva-core
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 0
|
33
|
+
version: "0"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: "[description]"
|
37
|
+
email: nobody@adva-cms.org
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
44
|
+
files:
|
45
|
+
- app/controllers/admin/categories_controller.rb
|
46
|
+
- app/controllers/base_controller_slice.rb
|
47
|
+
- app/helpers/url_helper_slice.rb
|
48
|
+
- app/views/admin/categories/index.html.rb
|
49
|
+
- app/views/admin/categories/edit.html.rb
|
50
|
+
- app/views/admin/categories/new.html.rb
|
51
|
+
- app/views/admin/categories/_form.html.rb
|
52
|
+
- app/views/admin/categories/_menu.html.rb
|
53
|
+
- app/models/content_slice.rb
|
54
|
+
- app/models/category.rb
|
55
|
+
- app/models/categorization.rb
|
56
|
+
- config/redirects.rb
|
57
|
+
- config/routes.rb
|
58
|
+
- config/locales/en.yml
|
59
|
+
- lib/adva-categories.rb
|
60
|
+
- lib/adva/categories.rb
|
61
|
+
- lib/adva/routing_filters/categories.rb
|
62
|
+
- lib/testing/factories.rb
|
63
|
+
- lib/testing/paths.rb
|
64
|
+
- lib/testing/step_definitions.rb
|
65
|
+
has_rdoc: true
|
66
|
+
homepage: http://github.com/svenfuchs/adva-cms2
|
67
|
+
licenses: []
|
68
|
+
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 3
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
requirements: []
|
93
|
+
|
94
|
+
rubyforge_project: "[none]"
|
95
|
+
rubygems_version: 1.3.7
|
96
|
+
signing_key:
|
97
|
+
specification_version: 3
|
98
|
+
summary: "[summary]"
|
99
|
+
test_files: []
|
100
|
+
|