push_type_core 0.3.3 → 0.4.0.beta.3

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/push_type/application_controller_methods.rb +15 -50
  3. data/app/controllers/concerns/push_type/filterable.rb +69 -0
  4. data/app/controllers/front_end_controller.rb +1 -33
  5. data/app/controllers/nodes_front_end_controller.rb +21 -0
  6. data/app/controllers/taxonomies_front_end_controller.rb +25 -0
  7. data/app/models/concerns/push_type/nestable.rb +1 -1
  8. data/app/models/concerns/push_type/publishable.rb +3 -3
  9. data/app/models/concerns/push_type/templatable.rb +1 -1
  10. data/app/models/concerns/push_type/unexposable.rb +22 -4
  11. data/app/models/push_type/taxonomy.rb +39 -0
  12. data/db/migrate/20141117170533_create_push_type_users.rb +1 -1
  13. data/db/migrate/20141117204630_create_push_type_nodes.rb +1 -1
  14. data/db/migrate/20141117210644_create_push_type_node_hierarchies.rb +2 -2
  15. data/db/migrate/20141127151930_create_push_type_assets.rb +1 -1
  16. data/db/migrate/20150310115933_create_push_type_taxonomies.rb +18 -0
  17. data/db/migrate/20150310123230_create_push_type_taxonomy_hierarchies.rb +16 -0
  18. data/lib/generators/push_type/install/templates/push_type.rb +2 -0
  19. data/lib/generators/push_type/node/node_generator.rb +1 -1
  20. data/lib/generators/push_type/taxonomy/USAGE +8 -0
  21. data/lib/generators/push_type/taxonomy/taxonomy_generator.rb +13 -0
  22. data/lib/generators/push_type/taxonomy/templates/taxonomy.html.erb +3 -0
  23. data/lib/generators/push_type/taxonomy/templates/taxonomy.rb +6 -0
  24. data/lib/push_type/config.rb +3 -0
  25. data/lib/push_type/core.rb +11 -11
  26. data/lib/push_type/rails/routes.rb +7 -1
  27. data/lib/push_type/tag_list_query.rb +1 -1
  28. data/lib/push_type/testing/common_rake.rb +2 -0
  29. data/lib/push_type/testing/factories.rb +10 -0
  30. data/lib/push_type/testing/setup.rb +3 -0
  31. data/lib/push_type/version.rb +1 -1
  32. data/test/controllers/{front_end_controller_test.rb → nodes_front_end_controller_test.rb} +8 -7
  33. data/test/controllers/taxonomies_front_end_controller_test.rb +58 -0
  34. data/test/dummy/app/models/category.rb +6 -0
  35. data/test/dummy/app/views/taxonomies/category.html.erb +3 -0
  36. data/test/dummy/config/initializers/push_type.rb +3 -1
  37. data/test/dummy/config/secrets.yml +2 -2
  38. data/test/dummy/db/migrate/{20150310192149_create_push_type_users.push_type.rb → 20150406131539_create_push_type_users.push_type.rb} +1 -1
  39. data/test/dummy/db/migrate/{20150310192150_create_push_type_nodes.push_type.rb → 20150406131540_create_push_type_nodes.push_type.rb} +1 -1
  40. data/test/dummy/db/migrate/{20150310192151_create_push_type_node_hierarchies.push_type.rb → 20150406131541_create_push_type_node_hierarchies.push_type.rb} +2 -2
  41. data/test/dummy/db/migrate/{20150310192152_create_push_type_assets.push_type.rb → 20150406131542_create_push_type_assets.push_type.rb} +1 -1
  42. data/test/dummy/db/migrate/20150406131543_create_push_type_taxonomies.push_type.rb +19 -0
  43. data/test/dummy/db/migrate/20150406131544_create_push_type_taxonomy_hierarchies.push_type.rb +17 -0
  44. data/test/dummy/db/schema.rb +29 -9
  45. data/test/dummy/log/test.log +2963 -2021
  46. data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  47. data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  48. data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  49. data/test/dummy/tmp/generators/app/presenters/page_presenter.rb +12 -0
  50. data/test/lib/generators/push_type/taxonomy_generator_test.rb +17 -0
  51. data/test/lib/push_type/core_test.rb +64 -39
  52. data/test/models/concerns/push_type/templatable_test.rb +3 -3
  53. data/test/models/concerns/push_type/unexposable_test.rb +30 -10
  54. data/test/models/push_type/taxonomy_test.rb +35 -0
  55. metadata +41 -19
  56. data/test/dummy/tmp/generators/config/initializers/push_type.rb +0 -36
  57. data/test/dummy/tmp/generators/config/routes.rb +0 -59
  58. /data/lib/generators/push_type/node/templates/{template.html.erb → node.html.erb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cadc2e0370adc5c49557963ec33d7dd1f8bc46de
4
- data.tar.gz: 77f3676187d5d731f1c5ceea31cfd6229f612210
3
+ metadata.gz: 197268baf4847b3e83ceffd40d9f70878c081b43
4
+ data.tar.gz: c3390f38682d7cb78f24357532e2275ec15dd913
5
5
  SHA512:
6
- metadata.gz: 017d0d10aec5e3a869b57f4bdcaccc88f6f9f4515498299ec3bf3e29611dfae9fd1144c935dd15a22bd3abccc9b5a814738461bdbc17f8eb35c27da6b6d32709
7
- data.tar.gz: 3336662a36f969e8014287cf5c064463e7c6a7a0ee3daca79eaf6d632bd12198addf34163e8859e7bff362407bb04c090cbd3e44532c98b0f208315c67e4e68f
6
+ metadata.gz: 5eba96db43bd908242d406c54b485773fa8167f8c27b2c7dc931499dd0cb74a742e67fcb006472016c12217cd02c4219997e7c20cd898a0597a471fbb20785a4
7
+ data.tar.gz: 5b9e5da50f1e94d9fa4e252ee54d5cd10a619d0b3f678e5f46b7737fb0db4eae6fdf7c6e1124c848058551e97cc8f19c6dd721a2d11c7ca84a292703b0584de0
@@ -2,8 +2,13 @@ module PushType
2
2
  module ApplicationControllerMethods
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ FILTERS = [
6
+ :before_node_load_filters, :before_node_action_filters, :after_node_action_filters,
7
+ :before_taxonomy_load_filters, :before_taxonomy_action_filters, :after_taxonomy_action_filters
8
+ ]
9
+
5
10
  included do
6
- class_attribute :before_load_filters, :before_node_filters, :after_node_filters
11
+ class_attribute *FILTERS
7
12
  end
8
13
 
9
14
  protected
@@ -14,59 +19,19 @@ module PushType
14
19
 
15
20
  private
16
21
 
17
- def before_load_filters
18
- self.class.before_load_filters
19
- end
20
-
21
- def before_node_filters
22
- self.class.before_node_filters
23
- end
24
-
25
- def after_node_filters
26
- self.class.after_node_filters
27
- end
28
-
29
- def run_node_hook(*args)
30
- methods_or_proc, opts = case args.last
31
- when Proc then args.first.is_a?(Hash) ? [ args.last, args.first ] : [ args.last, {} ]
32
- when Hash then [ args[0..-2], args.last ]
33
- else [ args, {} ]
34
- end
35
-
36
- unless node_type_not_in_option(opts[:only]) || node_type_in_option(opts[:except])
37
- if methods_or_proc.respond_to?(:call)
38
- instance_exec(&methods_or_proc)
39
- else
40
- Array(methods_or_proc).each { |m| send(m) }
41
- end
42
- end
43
- end
44
-
45
- def node_type_in_option(types)
46
- types && @node && Array(types).include?(@node.type.underscore.to_sym)
47
- end
48
-
49
- def node_type_not_in_option(types)
50
- types && @node && !Array(types).include?(@node.type.underscore.to_sym)
22
+ FILTERS.each do |filter|
23
+ define_method(filter) { self.class.send(filter) }
51
24
  end
52
25
 
53
26
  module ClassMethods
54
- def before_node_load(*args, &block)
55
- args.push block if block_given?
56
- self.before_load_filters ||= []
57
- self.before_load_filters.push << args
58
- end
59
-
60
- def before_node_action(*args, &block)
61
- args.push block if block_given?
62
- self.before_node_filters ||= []
63
- self.before_node_filters << args
64
- end
27
+ FILTERS.each do |filter|
28
+ method_name = filter.to_s.gsub(/_filters$/, '')
65
29
 
66
- def after_node_action(*args, &block)
67
- args.push block if block_given?
68
- self.after_node_filters ||= []
69
- self.after_node_filters << args
30
+ define_method method_name do |*args, &block|
31
+ args.push block if block
32
+ filters = ( self.send(filter) || [] ) << args
33
+ self.send "#{ filter }=", filters
34
+ end
70
35
  end
71
36
  end
72
37
 
@@ -0,0 +1,69 @@
1
+ module PushType
2
+ module Filterable
3
+ extend ActiveSupport::Concern
4
+
5
+ private
6
+
7
+ def filter_scope
8
+ self.class.filter_scope
9
+ end
10
+
11
+ def filter_obj
12
+ instance_variable_get "@#{ filter_scope }"
13
+ end
14
+
15
+ def filter_obj_type
16
+ filter_obj.type.underscore.to_sym
17
+ end
18
+
19
+ def before_load_filters
20
+ filters = self.send("before_#{ filter_scope }_load_filters")
21
+ filters.each { |f| run_node_hook(*f) } unless filters.blank?
22
+ end
23
+
24
+ def around_action_filters
25
+ before_filters = self.send("before_#{ filter_scope }_action_filters")
26
+ before_filters.each { |f| run_node_hook(*f) } unless before_filters.blank?
27
+ yield
28
+ after_filters = self.send("after_#{ filter_scope }_action_filters")
29
+ after_filters.each { |f| run_node_hook(*f) } unless after_filters.blank?
30
+ end
31
+
32
+ def run_node_hook(*args)
33
+ methods_or_proc, opts = case args.last
34
+ when Proc then args.first.is_a?(Hash) ? [ args.last, args.first ] : [ args.last, {} ]
35
+ when Hash then [ args[0..-2], args.last ]
36
+ else [ args, {} ]
37
+ end
38
+
39
+ unless filter_obj_not_in(opts[:only]) || filter_obj_in(opts[:except])
40
+ if methods_or_proc.respond_to?(:call)
41
+ instance_exec(&methods_or_proc)
42
+ else
43
+ Array(methods_or_proc).each { |m| send(m) }
44
+ end
45
+ end
46
+ end
47
+
48
+ def filter_obj_in(types)
49
+ types && filter_obj && Array(types).include?(filter_obj_type)
50
+ end
51
+
52
+ def filter_obj_not_in(types)
53
+ types && filter_obj && !Array(types).include?(filter_obj_type)
54
+ end
55
+
56
+ module ClassMethods
57
+
58
+ attr_reader :filter_scope
59
+
60
+ def hooks_for(sym, opts)
61
+ @filter_scope = sym
62
+ prepend_before_action :before_load_filters, opts
63
+ around_action :around_action_filters, opts
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
@@ -1,23 +1,9 @@
1
1
  class FrontEndController < ApplicationController
2
2
 
3
- before_action :before_load, :load_node, :before_node, only: :node
4
- after_action :after_node, only: :node
5
-
6
- def node
7
- render *@node.template_args
8
- end
3
+ include PushType::Filterable
9
4
 
10
5
  private
11
6
 
12
- def load_node
13
- @node = PushType::Node.published.find_by_path permalink_path
14
- if @node
15
- instance_variable_set "@#{ @node.type.underscore }", @node.present!(view_context)
16
- else
17
- raise_404
18
- end
19
- end
20
-
21
7
  def root_path?
22
8
  request.fullpath == '/'
23
9
  end
@@ -30,22 +16,4 @@ class FrontEndController < ApplicationController
30
16
  end
31
17
  end
32
18
 
33
- def before_load
34
- unless before_load_filters.blank?
35
- before_load_filters.each { |f| run_node_hook(*f) }
36
- end
37
- end
38
-
39
- def before_node
40
- unless before_node_filters.blank?
41
- before_node_filters.each { |f| run_node_hook(*f) }
42
- end
43
- end
44
-
45
- def after_node
46
- unless after_node_filters.blank?
47
- after_node_filters.each { |f| run_node_hook(*f) }
48
- end
49
- end
50
-
51
19
  end
@@ -0,0 +1,21 @@
1
+ class NodesFrontEndController < FrontEndController
2
+
3
+ before_action :load_node, only: :show
4
+ hooks_for :node, only: :show
5
+
6
+ def show
7
+ render *@node.template_args
8
+ end
9
+
10
+ private
11
+
12
+ def load_node
13
+ @node = PushType::Node.exposed.published.find_by_path permalink_path
14
+ if @node
15
+ instance_variable_set "@#{ @node.type.underscore }", @node.present!(view_context)
16
+ else
17
+ raise_404
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,25 @@
1
+ class TaxonomiesFrontEndController < FrontEndController
2
+
3
+ before_action :load_taxonomy, only: :show
4
+ hooks_for :taxonomy, only: :show
5
+
6
+ def show
7
+ render *@taxonomy.template_args
8
+ end
9
+
10
+ private
11
+
12
+ def load_taxonomy
13
+ @taxonomy = taxonomy_class.find_by_path(permalink_path)
14
+ if @taxonomy
15
+ instance_variable_set "@#{ @taxonomy.type.underscore }", @taxonomy
16
+ else
17
+ raise_404
18
+ end
19
+ end
20
+
21
+ def taxonomy_class
22
+ PushType::Taxonomy.descendants(exposed: true).find { |t| t.base_slug == params[:taxonomy] } or raise_404
23
+ end
24
+
25
+ end
@@ -29,7 +29,7 @@ module PushType
29
29
 
30
30
  def child_nodes
31
31
  types = @child_nodes || PushType.config.root_nodes
32
- PushType.node_types_from_list(types)
32
+ PushType.subclasses_from_list(:node, types)
33
33
  end
34
34
 
35
35
  def has_child_nodes(*args)
@@ -6,9 +6,9 @@ module PushType
6
6
  enum status: [ :draft, :published ]
7
7
 
8
8
  scope :published, -> {
9
- not_trash.exposed.
10
- where(['push_type_nodes.status = ? AND push_type_nodes.published_at <= ?', self.statuses[:published], Time.zone.now]).
11
- where(['push_type_nodes.published_to IS NULL OR push_type_nodes.published_to > ?', Time.zone.now])
9
+ not_trash
10
+ .where(['push_type_nodes.status = ? AND push_type_nodes.published_at <= ?', self.statuses[:published], Time.zone.now])
11
+ .where(['push_type_nodes.published_to IS NULL OR push_type_nodes.published_to > ?', Time.zone.now])
12
12
  }
13
13
 
14
14
  after_initialize :set_default_status
@@ -26,7 +26,7 @@ module PushType
26
26
  end
27
27
 
28
28
  def template_opts
29
- { path: 'nodes' }.merge(@template_opts || {})
29
+ { path: _ct.base_class.name.demodulize.pluralize.underscore }.merge(@template_opts || {})
30
30
  end
31
31
 
32
32
  end
@@ -4,8 +4,7 @@ module PushType
4
4
 
5
5
  included do
6
6
  scope :exposed, -> {
7
- node_types = PushType.unexposed_nodes
8
- node_types.present? ? where(['push_type_nodes.type NOT IN (?)', node_types]) : all
7
+ unexposed_classes.present? ? where.not(type: unexposed_classes) : all
9
8
  }
10
9
  end
11
10
 
@@ -15,12 +14,31 @@ module PushType
15
14
 
16
15
  module ClassMethods
17
16
 
17
+ def descendants(opts = {})
18
+ if opts.has_key? :exposed
19
+ super().select { |d| !opts[:exposed] == PushType.send(unexposure_method).include?(d.name.underscore) }
20
+ else
21
+ super()
22
+ end
23
+ end
24
+
25
+ def unexposed_classes
26
+ _ct.base_class.descendants(exposed: false)
27
+ end
28
+
29
+ def unexposure_method
30
+ case _ct.base_class.name.demodulize
31
+ when 'Node' then :unexposed_nodes
32
+ when 'Taxonomy' then :unexposed_taxonomies
33
+ end
34
+ end
35
+
18
36
  def unexpose!
19
- PushType.config.unexposed_nodes.push(self.name.underscore.to_sym).uniq!
37
+ PushType.config.send(unexposure_method).push(self.name.underscore.to_sym).uniq!
20
38
  end
21
39
 
22
40
  def exposed?
23
- !PushType.unexposed_nodes.include?(self.name)
41
+ !unexposed_classes.include?(self)
24
42
  end
25
43
 
26
44
  end
@@ -0,0 +1,39 @@
1
+ module PushType
2
+ class Taxonomy < ActiveRecord::Base
3
+
4
+ include PushType::Templatable
5
+ include PushType::Unexposable
6
+
7
+ acts_as_tree name_column: 'slug', order: 'sort_order', dependent: :destroy
8
+
9
+ validates :title, presence: true, uniqueness: { scope: :parent_id }
10
+ validates :slug, presence: true, uniqueness: { scope: :parent_id }
11
+
12
+ class << self
13
+ def title
14
+ @title ||= name.underscore.humanize.pluralize
15
+ end
16
+
17
+ def base_slug(*args)
18
+ if args.present?
19
+ @base_slug = args.first
20
+ else
21
+ ( @base_slug || name ).to_s.underscore
22
+ end
23
+ end
24
+ end
25
+
26
+ def base_slug
27
+ self.class.base_slug
28
+ end
29
+
30
+ def permalink
31
+ @permalink ||= self_and_ancestors.map(&:slug).push(base_slug).reverse.join('/')
32
+ end
33
+
34
+ def exposed?
35
+ self.class.exposed?
36
+ end
37
+
38
+ end
39
+ end
@@ -6,7 +6,7 @@ class CreatePushTypeUsers < ActiveRecord::Migration
6
6
  t.string :email
7
7
  t.jsonb :field_store
8
8
 
9
- t.timestamps
9
+ t.timestamps null: false
10
10
  end
11
11
  end
12
12
  end
@@ -17,7 +17,7 @@ class CreatePushTypeNodes < ActiveRecord::Migration
17
17
  t.uuid :creator_id
18
18
  t.uuid :updater_id
19
19
 
20
- t.timestamps
20
+ t.timestamps null: false
21
21
  t.datetime :deleted_at
22
22
  end
23
23
  end
@@ -8,9 +8,9 @@ class CreatePushTypeNodeHierarchies < ActiveRecord::Migration
8
8
 
9
9
  add_index :push_type_node_hierarchies, [:ancestor_id, :descendant_id, :generations],
10
10
  unique: true,
11
- name: "anc_desc_idx"
11
+ name: "node_anc_desc_idx"
12
12
 
13
13
  add_index :push_type_node_hierarchies, [:descendant_id],
14
- name: "desc_idx"
14
+ name: "node_desc_idx"
15
15
  end
16
16
  end
@@ -11,7 +11,7 @@ class CreatePushTypeAssets < ActiveRecord::Migration
11
11
 
12
12
  t.uuid :uploader_id
13
13
 
14
- t.timestamps
14
+ t.timestamps null: false
15
15
  t.datetime :deleted_at
16
16
  end
17
17
  end
@@ -0,0 +1,18 @@
1
+ class CreatePushTypeTaxonomies < ActiveRecord::Migration
2
+ def change
3
+ enable_extension 'uuid-ossp' unless extension_enabled?('uuid-ossp')
4
+ create_table :push_type_taxonomies, id: :uuid, default: 'uuid_generate_v4()' do |t|
5
+ t.string :type
6
+ t.string :title
7
+ t.string :slug
8
+
9
+ t.uuid :parent_id
10
+ t.integer :sort_order
11
+
12
+ t.timestamps null: false
13
+ end
14
+
15
+ # Also add a tags array to Assets
16
+ add_column :push_type_assets, :tags, :string, array: true
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ class CreatePushTypeTaxonomyHierarchies < ActiveRecord::Migration
2
+ def change
3
+ create_table :push_type_taxonomy_hierarchies, id: false do |t|
4
+ t.uuid :ancestor_id, null: false
5
+ t.uuid :descendant_id, null: false
6
+ t.integer :generations, null: false
7
+ end
8
+
9
+ add_index :push_type_taxonomy_hierarchies, [:ancestor_id, :descendant_id, :generations],
10
+ unique: true,
11
+ name: "taxonomy_anc_desc_idx"
12
+
13
+ add_index :push_type_taxonomy_hierarchies, [:descendant_id],
14
+ name: "taxonomy_desc_idx"
15
+ end
16
+ end
@@ -6,6 +6,8 @@ PushType.setup do |config|
6
6
 
7
7
  config.home_slug = 'home'
8
8
 
9
+ config.unexposed_taxonomies = []
10
+
9
11
  config.media_styles = {
10
12
  large: '1024x1024>',
11
13
  medium: '512x512>',
@@ -5,7 +5,7 @@ module PushType
5
5
 
6
6
  def create_model
7
7
  template 'node.rb', "app/models/#{ file_name }.rb"
8
- template 'template.html.erb', "app/views/nodes/#{ file_name }.html.erb"
8
+ template 'node.html.erb', "app/views/nodes/#{ file_name }.html.erb"
9
9
  end
10
10
 
11
11
  hook_for :test_framework, as: :model
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Generates a model that inherits from PushType::Taxonomy
3
+
4
+ Example:
5
+ rails generate push_type:taxonomy category
6
+
7
+ This will create:
8
+ app/models/category.rb
@@ -0,0 +1,13 @@
1
+ module PushType
2
+ class TaxonomyGenerator < Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def create_field
6
+ template 'taxonomy.rb', "app/models/#{ file_name }.rb"
7
+ template 'taxonomy.html.erb', "app/views/taxonomies/#{ file_name }.html.erb"
8
+ end
9
+
10
+ hook_for :test_framework, as: :model
11
+
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ <h1><%%= @taxonomy.title %></h1>
2
+ <p>This is a generated <%= class_name %> template.</p>
3
+ <p>Find me at: app/views/taxonomies/<%= file_name %>.html.erb</p>
@@ -0,0 +1,6 @@
1
+ class <%= class_name %> < PushType::Taxonomy
2
+
3
+ # Set base slug
4
+ # base_slug :<%= file_name %>
5
+
6
+ end
@@ -10,6 +10,9 @@ module PushType
10
10
  mattr_accessor :home_slug
11
11
  @@home_slug = 'home'
12
12
 
13
+ mattr_accessor :unexposed_taxonomies
14
+ @@unexposed_taxonomies = []
15
+
13
16
  mattr_accessor :media_styles
14
17
  @@media_styles = {
15
18
  large: '1024x1024>',
@@ -18,26 +18,26 @@ module PushType
18
18
  end
19
19
 
20
20
  def root_nodes
21
- node_types_from_list(config.root_nodes)
21
+ subclasses_from_list(:node, config.root_nodes)
22
22
  end
23
23
 
24
24
  def unexposed_nodes
25
- node_types_from_list(config.unexposed_nodes).map(&:camelcase)
25
+ subclasses_from_list(:node, config.unexposed_nodes)
26
26
  end
27
27
 
28
- def node_types_from_list(types = nil)
28
+ def unexposed_taxonomies
29
+ subclasses_from_list(:taxonomy, config.unexposed_taxonomies)
30
+ end
31
+
32
+ def subclasses_from_list(scope, types = nil)
29
33
  return [] unless types
34
+ descendants = "push_type/#{ scope }".camelcase.constantize.descendants.map { |c| c.name.underscore }
30
35
  types_array = Array.wrap(types)
36
+
31
37
  if types_array.include? :all
32
- PushType::Node.descendants.map(&:name).map(&:underscore)
38
+ descendants
33
39
  else
34
- types_array.map(&:to_s).select do |kind|
35
- begin
36
- kind.camelcase.constantize.ancestors.include? PushType::Node
37
- rescue NameError
38
- false
39
- end
40
- end
40
+ descendants & types_array.map(&:to_s)
41
41
  end.sort
42
42
  end
43
43
 
@@ -6,7 +6,8 @@ module ActionDispatch::Routing
6
6
  path: '/push_type',
7
7
  home: PushType.config.home_slug,
8
8
  actions: {
9
- node: 'front_end#node'
9
+ node: 'nodes_front_end#show',
10
+ taxonomy: 'taxonomies_front_end#show',
10
11
  }
11
12
  }.deep_merge!(options)
12
13
 
@@ -20,6 +21,11 @@ module ActionDispatch::Routing
20
21
  asset.media params[:style]
21
22
  }, as: 'media'
22
23
 
24
+ # Taxonomies
25
+ get ":taxonomy/*permalink" => opts[:actions][:taxonomy], as: 'taxonomy', constraints: ->(params, req) {
26
+ PushType::Taxonomy.descendants(exposed: true).map(&:base_slug).include? params[:taxonomy]
27
+ }
28
+
23
29
  # A catch-all root for the nodes
24
30
  get '*permalink' => opts[:actions][:node], as: 'node'
25
31
  root to: opts[:actions][:node], permalink: opts[:home]
@@ -12,7 +12,7 @@ module PushType
12
12
  end
13
13
 
14
14
  def node_types
15
- PushType.node_types_from_list(@opts[:type]).map { |n| "'#{ n.camelcase }'" }
15
+ PushType.subclasses_from_list(:node, @opts[:type]).map { |n| "'#{ n.camelcase }'" }
16
16
  end
17
17
 
18
18
  private
@@ -1,6 +1,7 @@
1
1
  require 'generators/push_type/dummy/dummy_generator'
2
2
  require 'generators/push_type/install/install_generator'
3
3
  require 'generators/push_type/node/node_generator'
4
+ require 'generators/push_type/taxonomy/taxonomy_generator'
4
5
 
5
6
  namespace :common do
6
7
 
@@ -16,6 +17,7 @@ namespace :common do
16
17
  system 'bundle exec rake db:drop db:create'
17
18
  PushType::InstallGenerator.start ['--quiet']
18
19
  PushType::NodeGenerator.start ['page', '--quiet']
20
+ PushType::TaxonomyGenerator.start ['category', '--quiet']
19
21
  end
20
22
  end
21
23
 
@@ -1,6 +1,11 @@
1
1
  require 'factory_girl_rails'
2
2
 
3
3
  FactoryGirl.define do
4
+
5
+ sequence :title do |n|
6
+ "Foo Bar #{n}"
7
+ end
8
+
4
9
  sequence :slug do |n|
5
10
  "foo-bar-#{n}"
6
11
  end
@@ -37,5 +42,10 @@ FactoryGirl.define do
37
42
  file { Rack::Test::UploadedFile.new(PushType::Core::Engine.root.join('test', 'files/document.pdf')) }
38
43
  end
39
44
  end
45
+
46
+ factory :taxonomy, class: 'PushType::Taxonomy' do
47
+ title { generate :title }
48
+ slug { generate :slug }
49
+ end
40
50
 
41
51
  end
@@ -12,6 +12,9 @@ DatabaseCleaner.clean_with :truncation
12
12
  Dragonfly.app.use_datastore :memory
13
13
 
14
14
  class ActiveSupport::TestCase
15
+ # Due to test weirdness / dodgy code need to reference some classes
16
+ Page && Category
17
+
15
18
  before :each do
16
19
  DatabaseCleaner.start
17
20
  PushType.config.root_nodes = :all
@@ -1,3 +1,3 @@
1
1
  module PushType
2
- VERSION = '0.3.3'
2
+ VERSION = '0.4.0.beta.3'
3
3
  end