adva-categories 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ class Admin::CategoriesController < Admin::BaseController
2
+ belongs_to :site
3
+ belongs_to :section
4
+ end
@@ -0,0 +1,9 @@
1
+ require_dependency 'base_controller'
2
+
3
+ BaseController.class_eval do
4
+ include do
5
+ def collection
6
+ params[:category_id] ? super.categorized(params[:category_id]) : super
7
+ end
8
+ end
9
+ end
@@ -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,5 @@
1
+ class Categorization < ActiveRecord::Base
2
+ belongs_to :category
3
+ accepts_nested_attributes_for :category
4
+ end
5
+
@@ -0,0 +1,8 @@
1
+ class Category < ActiveRecord::Base
2
+ acts_as_nested_set :scope => :section_id
3
+ has_slug :scope => :section_id
4
+
5
+ belongs_to :section
6
+
7
+ validates_presence_of :section, :name
8
+ end
@@ -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,17 @@
1
+ class Admin::Categories::Form < Adva::View::Form
2
+ include do
3
+ def fields
4
+ fieldset do
5
+ form.input :name
6
+ end
7
+ end
8
+
9
+ def sidebar
10
+ tab :options do
11
+ form.input :slug
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+
@@ -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,9 @@
1
+ class Admin::Categories::Edit < Adva::View::Form
2
+ include do
3
+ def to_html
4
+ h2 :'.title'
5
+ render :partial => 'form'
6
+ end
7
+ end
8
+ end
9
+
@@ -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,10 @@
1
+ class Admin::Categories::New < Adva::View::Form
2
+ include do
3
+ def to_html
4
+ h2 :'.title'
5
+ render :partial => 'form'
6
+ end
7
+ end
8
+ end
9
+
10
+
@@ -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
@@ -0,0 +1,4 @@
1
+ Adva::Registry.set :redirect, {
2
+ 'admin/categories#create' => lambda { |c| c.edit_url },
3
+ 'admin/categories#update' => lambda { |c| c.edit_url }
4
+ }
data/config/routes.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'adva/routing_filters/categories'
2
+
3
+ Rails.application.routes.draw do
4
+ filter :categories
5
+
6
+ namespace :admin do
7
+ resources :sites do
8
+ resources :sections do
9
+ resources :categories
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require 'adva'
2
+
3
+ module Adva
4
+ class Categories < ::Rails::Engine
5
+ include Adva::Engine
6
+
7
+ initializer 'adva-categories.configure_routing_filters' do
8
+ RoutingFilter::SectionRoot.anchors << 'categories'
9
+ end
10
+ end
11
+ end
@@ -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,4 @@
1
+ Factory.define :category do |f|
2
+ f.section { Section.first || Factory(:section) }
3
+ f.name 'Category'
4
+ end
@@ -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
+