push_type_core 0.2.1 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/push_type/pushtype-favicon.png +0 -0
  3. data/app/assets/images/push_type/pushtype-logo.svg +23 -0
  4. data/app/controllers/concerns/push_type/application_controller_methods.rb +58 -2
  5. data/app/controllers/front_end_controller.rb +25 -8
  6. data/app/fields/push_type/date_field.rb +1 -0
  7. data/app/models/push_type/node.rb +11 -2
  8. data/app/views/push_type/setup.html.erb +129 -0
  9. data/config/locales/en.yml +9 -0
  10. data/lib/generators/push_type/field/USAGE +9 -0
  11. data/lib/generators/push_type/field/field_generator.rb +9 -0
  12. data/lib/generators/push_type/field/templates/field.rb +15 -0
  13. data/lib/generators/push_type/node/USAGE +2 -1
  14. data/lib/generators/push_type/node/node_generator.rb +7 -0
  15. data/lib/generators/push_type/node/templates/node.rb +3 -1
  16. data/lib/generators/push_type/node/templates/template.html.erb +8 -1
  17. data/lib/push_type/core/engine.rb +12 -2
  18. data/lib/push_type/core.rb +5 -0
  19. data/lib/push_type/menu_builder/dsl/menu.rb +32 -0
  20. data/lib/push_type/menu_builder/dsl/menu_item.rb +45 -0
  21. data/lib/push_type/menu_builder/helpers.rb +11 -0
  22. data/lib/push_type/menu_builder/menu.rb +57 -0
  23. data/lib/push_type/menu_builder/menu_item.rb +39 -0
  24. data/lib/push_type/menu_builder/menu_renderer.rb +47 -0
  25. data/lib/push_type/menu_builder.rb +17 -0
  26. data/lib/push_type/version.rb +1 -1
  27. data/test/controllers/front_end_controller_test.rb +16 -7
  28. data/test/dummy/app/models/page.rb +1 -1
  29. data/test/dummy/app/views/nodes/page.html.erb +3 -1
  30. data/test/dummy/config/initializers/push_type.rb +1 -1
  31. data/test/dummy/config/secrets.yml +2 -2
  32. data/test/dummy/db/schema.rb +1 -1
  33. data/test/dummy/log/test.log +2032 -67930
  34. data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  35. data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  36. data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  37. data/test/dummy/tmp/generators/app/models/home_page.rb +3 -1
  38. data/test/dummy/tmp/generators/app/views/nodes/home_page.html.erb +11 -1
  39. data/test/lib/generators/push_type/field_generator_test.rb +16 -0
  40. data/test/lib/generators/push_type/node_generator_test.rb +5 -1
  41. data/test/lib/push_type/menu_builder/menu_dsl_test.rb +25 -0
  42. data/test/lib/push_type/menu_builder/menu_item_dsl_test.rb +35 -0
  43. data/test/lib/push_type/menu_builder/menu_item_test.rb +40 -0
  44. data/test/lib/push_type/menu_builder/menu_renderer_test.rb +26 -0
  45. data/test/lib/push_type/menu_builder/menu_test.rb +62 -0
  46. data/test/lib/push_type/menu_builder_test.rb +20 -0
  47. data/test/models/concerns/push_type/nestable_test.rb +9 -4
  48. data/test/models/concerns/push_type/templatable_test.rb +9 -5
  49. data/test/models/push_type/node_test.rb +16 -0
  50. metadata +38 -10
  51. /data/test/dummy/db/migrate/{20150209204334_create_push_type_users.push_type.rb → 20150222152443_create_push_type_users.push_type.rb} +0 -0
  52. /data/test/dummy/db/migrate/{20150209204335_create_push_type_nodes.push_type.rb → 20150222152444_create_push_type_nodes.push_type.rb} +0 -0
  53. /data/test/dummy/db/migrate/{20150209204336_create_push_type_node_hierarchies.push_type.rb → 20150222152445_create_push_type_node_hierarchies.push_type.rb} +0 -0
  54. /data/test/dummy/db/migrate/{20150209204337_create_push_type_assets.push_type.rb → 20150222152446_create_push_type_assets.push_type.rb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4248b67982fe778388b3418614a95043834315ce
4
- data.tar.gz: 5d64098c0f00b7d3aad9a7dabd151e4eff907abc
3
+ metadata.gz: dab8a05da824c4e462036cf439211ea2079fdc97
4
+ data.tar.gz: d6958fe4edec3285d579900e18acc6baea311023
5
5
  SHA512:
6
- metadata.gz: e953d4035fca92bd4f5deeaf4b7cb7f0374071c49f34c423fae5b6c8cc373e595c896c88aa58ea084d69f4083fbea71de6d85f284518b1ddfc9cb34ea17a5877
7
- data.tar.gz: 54c2ef9df08874ee1f59fac6682e1158e4db7d868b1f9de4a34d3699c52c96b842e1d61eb9885fd5a8389eb650754646080e992babf2cbb8038594abe5cd5bd6
6
+ metadata.gz: 77f428a7948531c3d22ce138d2264828b8e503f81b63e076ab2b8b91431d971e1456ab7ea9bb6181a92c4995448513145576055adb99e8fba6771f6cf77c597e
7
+ data.tar.gz: eee7db02e35987fa1413cf660ad4af16e75e0a403d4ecc818f8a5b88afca3c3ff8ebe76a22e85829e1adb292be28648d41e9bc270350049fbbcfd3b3c90b2bde
@@ -0,0 +1,23 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="140px" height="26px" viewBox="0 0 140 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3
+ <!-- Generator: Sketch 3.2.2 (9983) - http://www.bohemiancoding.com/sketch -->
4
+ <title>PushType logo</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
8
+ <g id="A4" sketch:type="MSArtboardGroup" transform="translate(-137.000000, -385.000000)">
9
+ <g id="Imported-Layers" sketch:type="MSLayerGroup" transform="translate(137.000000, 385.000000)">
10
+ <path d="M39.6533945,12.62235 L38.2122936,14.08095 C37.9284404,14.36825 37.5790826,14.52295 37.1642202,14.52295 L31.6624771,14.52295 L31.6624771,20.3346 L29.0422936,20.3346 L29.0422936,5.5952 L37.1642202,5.5952 C37.5790826,5.5952 37.9284404,5.7499 38.2122936,6.03785 L39.6533945,7.4958 C39.9584404,7.8052 40.1119266,8.1588 40.1119266,8.6008 L40.1119266,11.518 C40.1119266,11.95935 39.9584404,12.31295 39.6533945,12.62235 L39.6533945,12.62235 Z M37.4917431,9.0428 C37.4917431,8.9102 37.4480734,8.8218 37.3607339,8.7334 L36.880367,8.2472 C36.7930275,8.1588 36.7056881,8.1146 36.5746789,8.1146 L31.6624771,8.1146 L31.6624771,12.00355 L36.5746789,12.00355 C36.7056881,12.00355 36.7930275,11.95935 36.880367,11.8716 L37.3607339,11.3854 C37.4480734,11.29635 37.4917431,11.2086 37.4917431,11.076 L37.4917431,9.0428 L37.4917431,9.0428 Z" id="Fill-1" fill="#212D3B" sketch:type="MSShapeGroup"></path>
11
+ <path d="M53.7407339,18.05895 L51.9509174,19.8705 C51.6445872,20.1799 51.2733945,20.3346 50.8591743,20.3346 L46.470367,20.3346 C46.0555046,20.3346 45.6843119,20.1799 45.3792661,19.8705 L43.5888073,18.05895 C43.2831193,17.74955 43.1302752,17.3732 43.1302752,16.9533 L43.1302752,5.5952 L45.7498165,5.5952 L45.7498165,16.51195 C45.7498165,16.62245 45.7934862,16.73295 45.8808257,16.82135 L46.7323853,17.68325 C46.8197248,17.771 46.9070642,17.81585 47.0380734,17.81585 L50.2908257,17.81585 C50.4224771,17.81585 50.5098165,17.771 50.597156,17.68325 L51.4480734,16.82135 C51.536055,16.73295 51.5790826,16.62245 51.5790826,16.51195 L51.5790826,5.5952 L54.1992661,5.5952 L54.1992661,16.9533 C54.1992661,17.3732 54.046422,17.74955 53.7407339,18.05895" id="Fill-2" fill="#212D3B" sketch:type="MSShapeGroup"></path>
12
+ <path d="M69.3590826,18.05895 L67.5686239,19.8705 C67.2629358,20.1799 66.8917431,20.3346 66.4775229,20.3346 L60.3855963,20.3346 C59.9707339,20.3346 59.6001835,20.1799 59.2944954,19.8705 L57.4385321,17.99265 L59.1853211,16.20255 L60.6482569,17.68325 C60.7349541,17.771 60.8229358,17.81585 60.9533028,17.81585 L65.9091743,17.81585 C66.0408257,17.81585 66.1275229,17.771 66.2148624,17.68325 L67.0670642,16.82135 C67.1537615,16.73295 67.1974312,16.62245 67.1974312,16.51195 L67.1974312,15.09755 C67.1974312,14.87655 67.0015596,14.67765 66.7825688,14.65555 L58.9451376,13.59475 C58.093578,13.48425 57.4385321,12.71075 57.4385321,11.8716 L57.4385321,8.9765 C57.4385321,8.5566 57.5913761,8.1809 57.8970642,7.8715 L59.6868807,6.0593 C59.993211,5.7499 60.3644037,5.5952 60.7786239,5.5952 L66.8699083,5.5952 C67.2854128,5.5952 67.6566055,5.7499 67.9616514,6.0593 L69.8176147,7.9378 L68.0708257,9.7279 L66.6078899,8.2472 C66.5211927,8.1588 66.433211,8.1146 66.302844,8.1146 L61.3463303,8.1146 C61.2153211,8.1146 61.1279817,8.1588 61.0406422,8.2472 L60.1890826,9.1091 C60.1017431,9.1975 60.0587156,9.308 60.0587156,9.4185 L60.0587156,10.8329 C60.0587156,11.05325 60.2333945,11.2528 60.4511009,11.2749 L68.3110092,12.33505 C69.1625688,12.4462 69.8176147,13.21905 69.8176147,14.05885 L69.8176147,16.9533 C69.8176147,17.3732 69.6647706,17.74955 69.3590826,18.05895" id="Fill-3" fill="#212D3B" sketch:type="MSShapeGroup"></path>
13
+ <path d="M81.6521101,20.3346 L81.6521101,14.21355 L75.822844,14.21355 L75.822844,20.3346 L73.2026606,20.3346 L73.2026606,5.5952 L75.822844,5.5952 L75.822844,11.6948 L81.6521101,11.6948 L81.6521101,5.5952 L84.2722936,5.5952 L84.2722936,20.3346 L81.6521101,20.3346" id="Fill-4" fill="#212D3B" sketch:type="MSShapeGroup"></path>
14
+ <path d="M94.0183486,6.9654 L94.0183486,20.3346 L92.6652294,20.3346 L92.6652294,6.9654 L88.1454128,6.9654 L88.1454128,5.5952 L98.5381651,5.5952 L98.5381651,6.9654 L94.0183486,6.9654" id="Fill-5" fill="#3BB5EF" sketch:type="MSShapeGroup"></path>
15
+ <path d="M107.839817,13.81575 L107.839817,20.3346 L106.486697,20.3346 L106.486697,13.81575 L101.24633,5.5952 L102.840275,5.5952 L107.184771,12.37925 L111.507431,5.5952 L113.057706,5.5952 L107.839817,13.81575" id="Fill-6" fill="#3BB5EF" sketch:type="MSShapeGroup"></path>
16
+ <path d="M126.592752,12.13615 L125.479174,13.26325 C125.173486,13.57265 124.824128,13.70525 124.409908,13.70525 L118.012936,13.70525 L118.012936,20.3346 L116.658532,20.3346 L116.658532,5.5952 L124.409908,5.5952 C124.824128,5.5952 125.173486,5.7499 125.457982,6.03785 L126.592752,7.1864 C126.899083,7.4958 127.051284,7.8494 127.051284,8.2914 L127.051284,11.0318 C127.051284,11.4517 126.899083,11.82675 126.592752,12.13615 L126.592752,12.13615 Z M125.697523,8.3577 C125.697523,8.2251 125.653853,8.1367 125.566514,8.0483 L124.628257,7.098 C124.540917,7.0096 124.452936,6.9654 124.322569,6.9654 L118.012936,6.9654 L118.012936,12.33505 L124.300734,12.33505 C124.409908,12.33505 124.519083,12.2915 124.60578,12.20245 L125.566514,11.2307 C125.653853,11.1423 125.697523,11.05325 125.697523,10.9213 L125.697523,8.3577 L125.697523,8.3577 Z" id="Fill-7" fill="#3BB5EF" sketch:type="MSShapeGroup"></path>
17
+ <path d="M130.947523,20.3346 L130.947523,5.5952 L139.985872,5.5952 L139.985872,6.9654 L132.301284,6.9654 L132.301284,12.26875 L139.985872,12.26875 L139.985872,13.63895 L132.301284,13.63895 L132.301284,18.9644 L139.985872,18.9644 L139.985872,20.3346 L130.947523,20.3346" id="Fill-8" fill="#3BB5EF" sketch:type="MSShapeGroup"></path>
18
+ <path d="M22.3222936,18.7161 C22.3222936,19.1217 22.0384404,19.61895 21.6910092,19.82175 L11.8222936,25.5892 C11.4748624,25.79135 10.9077982,25.79135 10.560367,25.5892 L0.690366972,19.82175 C0.34293578,19.61895 0.0597247706,19.1217 0.0597247706,18.7161 L0.0597247706,7.1812 C0.0597247706,6.7756 0.34293578,6.279 0.690366972,6.0762 L10.560367,0.30615 C10.9077982,0.104 11.4748624,0.104 11.8222936,0.30615 L21.6910092,6.0762 C22.0384404,6.279 22.3222936,6.7756 22.3222936,7.1812 L22.3222936,18.7161" id="Fill-9" fill="#3BB5EF" sketch:type="MSShapeGroup"></path>
19
+ <path d="M12.7155963,17.3901 L13.0418349,19.07165 L14.8631193,19.07165 L11.190367,4.31405 L7.51889908,19.0723 L9.34018349,19.07165 L9.66770642,17.3849 L12.7155963,17.3901" id="Fill-10" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
20
+ </g>
21
+ </g>
22
+ </g>
23
+ </svg>
@@ -2,6 +2,10 @@ module PushType
2
2
  module ApplicationControllerMethods
3
3
  extend ActiveSupport::Concern
4
4
 
5
+ included do
6
+ class_attribute :before_load_filters, :before_node_filters, :after_node_filters
7
+ end
8
+
5
9
  protected
6
10
 
7
11
  def permalink_path
@@ -10,8 +14,60 @@ module PushType
10
14
 
11
15
  private
12
16
 
13
- def node_hook(method)
14
- send(method) if self.class.method_defined?(method.to_sym)
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)
51
+ end
52
+
53
+ 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
65
+
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
70
+ end
15
71
  end
16
72
 
17
73
  end
@@ -11,24 +11,41 @@ class FrontEndController < ApplicationController
11
11
 
12
12
  def load_node
13
13
  @node = PushType::Node.published.find_by_path permalink_path
14
- raise ActiveRecord::RecordNotFound unless @node
15
- instance_variable_set "@#{ @node.type.underscore }", @node
14
+ if @node
15
+ instance_variable_set "@#{ @node.type.underscore }", @node
16
+ else
17
+ raise_404
18
+ end
16
19
  end
17
20
 
18
- def before_load
19
- node_hook(:before_node_load)
21
+ def root_path?
22
+ request.fullpath == '/'
23
+ end
24
+
25
+ def raise_404
26
+ if root_path?
27
+ render template: 'push_type/setup', layout: false, status: 404
28
+ else
29
+ raise ActiveRecord::RecordNotFound
30
+ end
20
31
  end
21
32
 
22
- def node_types_array
23
- ['node', @node.type.underscore]
33
+ def before_load
34
+ unless before_load_filters.blank?
35
+ before_load_filters.each { |f| run_node_hook(*f) }
36
+ end
24
37
  end
25
38
 
26
39
  def before_node
27
- node_types_array.each { |kind| node_hook(:"before_#{ kind }_action") }
40
+ unless before_node_filters.blank?
41
+ before_node_filters.each { |f| run_node_hook(*f) }
42
+ end
28
43
  end
29
44
 
30
45
  def after_node
31
- node_types_array.each { |kind| node_hook(:"after_#{ kind }_action") }
46
+ unless after_node_filters.blank?
47
+ after_node_filters.each { |f| run_node_hook(*f) }
48
+ end
32
49
  end
33
50
 
34
51
  end
@@ -5,6 +5,7 @@ module PushType
5
5
  end
6
6
 
7
7
  def from_json(val)
8
+ return unless val
8
9
  val.to_date
9
10
  end
10
11
  end
@@ -11,14 +11,23 @@ module PushType
11
11
  belongs_to :creator, class_name: 'PushType::User'
12
12
  belongs_to :updater, class_name: 'PushType::User'
13
13
 
14
- acts_as_tree name_column: 'slug', order: 'sort_order'
14
+ acts_as_tree name_column: 'slug', order: 'sort_order', dependent: :destroy
15
15
 
16
16
  validates :title, presence: true
17
17
  validates :slug, presence: true, uniqueness: { scope: :parent_id }
18
18
 
19
19
  def permalink
20
20
  @permalink ||= self_and_ancestors.map(&:slug).reverse.join('/')
21
- end
21
+ end
22
+
23
+ def orphan?
24
+ parent && parent.trashed?
25
+ end
26
+
27
+ def trash!
28
+ super
29
+ self.descendants.update_all deleted_at: Time.zone.now
30
+ end
22
31
 
23
32
  end
24
33
  end
@@ -0,0 +1,129 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>PushType :: Setup</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <%= stylesheet_link_tag '//fonts.googleapis.com/css?family=Lato:300,400', '//fonts.googleapis.com/css?family=Inconsolata', media: 'all' %>
8
+ <style type="text/css">
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ }
13
+ body {
14
+ background-color: #FAFAFA;
15
+ font-family: 'Lato', sans-serif;
16
+ font-size: 62.5%;
17
+ font-weight: 300;
18
+ color: #222;
19
+ text-rendering: optimizeLegibility;
20
+ }
21
+ h1 {
22
+ margin-bottom: 1.5rem;
23
+ font-size: 2.8em;
24
+ font-weight: 300;
25
+ text-align: center;
26
+ }
27
+ p, ol {
28
+ margin-bottom: 1.5em;
29
+ font-size: 1.6em;
30
+ line-height: 1.5em;
31
+ }
32
+ p {
33
+ text-align: center;
34
+ }
35
+ ol {
36
+ margin-left: 24px;
37
+ font-weight: 400;
38
+ color: #999;
39
+ }
40
+ li {
41
+ margin-bottom: 1em;
42
+ }
43
+ pre {
44
+ padding: 0 15px;
45
+ font-family: 'Inconsolata', monospace;
46
+ font-size: 1em;
47
+ line-height: 2em;
48
+ font-weight: normal;
49
+ background-color: #323232;
50
+ color: #fff;
51
+ border-radius: 4px;
52
+ }
53
+ pre:before {
54
+ content: '> ';
55
+ color: #d76e2d;
56
+ }
57
+ a {
58
+ color: #3BB5EF;
59
+ text-decoration: none;
60
+ }
61
+ a:hover {
62
+ color: #3D78A3;
63
+ text-decoration: underline;
64
+ }
65
+ .wrap {
66
+ max-width: 520px;
67
+ margin: 6rem auto 2rem;
68
+ padding: 0 20px;
69
+ }
70
+ .logo {
71
+ max-width: 240px;
72
+ margin: 0 auto 2rem;
73
+ }
74
+ .logo img {
75
+ display: block;
76
+ width: 100%;
77
+ }
78
+ .panel {
79
+ background-color: #fff;
80
+ padding: 3rem 2rem 1.5rem;
81
+ border: 1px solid #EFEFEF;
82
+ }
83
+ .label {
84
+ display: block;
85
+ margin-bottom: 6px;
86
+ font-weight: 300;
87
+ color: #222;
88
+ }
89
+ .label.text {
90
+ margin-bottom:0;
91
+ }
92
+
93
+ </style>
94
+ <%= favicon_link_tag 'push_type/pushtype-favicon.png' %>
95
+ </head>
96
+ <body>
97
+
98
+ <div class="wrap">
99
+ <div class="logo">
100
+ <%= image_tag('push_type/pushtype-logo.svg', alt: 'PushType') %>
101
+ </div>
102
+ <div class="panel">
103
+ <h1>You've installed PushType. Hurrah!</h1>
104
+ <p>Get started in a few very easy steps&hellip;</p>
105
+
106
+ <ol>
107
+ <li>
108
+ <span class="label">Create your first Node type:</span>
109
+ <pre>rails g push_type:node page body:wysiwyg</pre>
110
+ </li>
111
+ <% if PushType.const_defined?(:Auth) %>
112
+ <li>
113
+ <span class="label">Create a user to log in with:</span>
114
+ <pre>rake push_type:create_user</pre>
115
+ </li>
116
+ <% end %>
117
+ <li>
118
+ <span class="label text">And log in:</span>
119
+ <div><%= link_to push_type.root_url, push_type.root_path %></div>
120
+ </li>
121
+ </ol>
122
+
123
+ </div>
124
+ </div>
125
+
126
+
127
+
128
+ </body>
129
+ </html>
@@ -0,0 +1,9 @@
1
+ en:
2
+ time:
3
+ formats:
4
+ short: "%-d %b %Y, %H:%M"
5
+ long: "%-d %B %Y, %H:%M"
6
+ date:
7
+ formats:
8
+ short: "%-d %b %Y"
9
+ long: "%-d %B %Y"
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Generates a class that inherits from PushType::FieldType
3
+ Allows for complex custom field types.
4
+
5
+ Example:
6
+ rails generate push_type:field rich_text
7
+
8
+ This will create:
9
+ app/fields/rich_text.rb
@@ -0,0 +1,9 @@
1
+ module PushType
2
+ class FieldGenerator < Rails::Generators::NamedBase
3
+ source_root File.expand_path('../templates', __FILE__)
4
+
5
+ def create_field
6
+ template 'field.rb', "app/fields/#{ file_name }_field.rb"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ class <%= class_name %>Field < PushType::FieldType
2
+
3
+ # Override built-in methods to extend functionality
4
+ # See PushType::FieldType Rdoc for methods to Override
5
+
6
+ # Example:
7
+ # def form_helper
8
+ # :date_field
9
+ # end
10
+
11
+ # def from_json(val)
12
+ # val.to_date
13
+ # end
14
+
15
+ end
@@ -2,7 +2,8 @@ Description:
2
2
  Generates a model that inherits from PushType::Node
3
3
 
4
4
  Example:
5
- rails generate push_type:node page
5
+ rails generate push_type:node page body:text
6
6
 
7
7
  This will create:
8
8
  app/models/page.rb
9
+ app/views/nodes/page.html.erb
@@ -1,6 +1,7 @@
1
1
  module PushType
2
2
  class NodeGenerator < Rails::Generators::NamedBase
3
3
  source_root File.expand_path('../templates', __FILE__)
4
+ argument :attributes, type: :array, default: [], banner: "field:type field:type"
4
5
 
5
6
  def create_model
6
7
  template 'node.rb', "app/models/#{ file_name }.rb"
@@ -8,5 +9,11 @@ module PushType
8
9
  end
9
10
 
10
11
  hook_for :test_framework, as: :model
12
+
13
+ protected
14
+
15
+ def attribute_as_field(att)
16
+ "field :#{ att.name }, :#{ att.type }"
17
+ end
11
18
  end
12
19
  end
@@ -4,7 +4,9 @@ class <%= class_name %> < PushType::Node
4
4
  # has_child_nodes :all
5
5
 
6
6
  # Set custom fields
7
- # field :description
8
7
  # field :body, :text, validates: { presence: true }
8
+ <% attributes.each do |att| -%>
9
+ <%= attribute_as_field(att) %>
10
+ <% end -%>
9
11
 
10
12
  end
@@ -1,3 +1,10 @@
1
1
  <h1><%%= @node.title %></h1>
2
2
  <p>This is a generated <%= class_name %> template.</p>
3
- <p>Find me at: app/views/nodes/<%= file_name %>.html.erb</p>
3
+ <p>Find me at: app/views/nodes/<%= file_name %>.html.erb</p>
4
+
5
+ <% attributes.each do |att| -%>
6
+ <div>
7
+ <div><%= att.name.humanize %>:</div>
8
+ <div><%%= @node.<%= att.name %> %></div>
9
+ </div>
10
+ <% end -%>
@@ -14,14 +14,24 @@ module PushType
14
14
 
15
15
  config.to_prepare do
16
16
  Rails.application.eager_load! unless Rails.application.config.cache_classes
17
- ApplicationController.send :include, PushType::ApplicationControllerMethods
18
17
  end
19
18
 
20
19
  initializer 'push_type.dragonfly_config' do
21
20
  PushType.config.dragonfly_secret ||= Rails.application.secrets.secret_key_base
22
21
  PushType.dragonfly_app_setup!
23
22
  end
24
-
23
+
24
+ initializer 'push_type.application_controller' do
25
+ ActiveSupport.on_load(:action_controller) do
26
+ include PushType::ApplicationControllerMethods
27
+ end
28
+ end
29
+
30
+ initializer 'push_type.menu_helpers' do
31
+ ActiveSupport.on_load(:action_view) do
32
+ include PushType::MenuBuilder::Helpers
33
+ end
34
+ end
25
35
  end
26
36
  end
27
37
  end
@@ -50,6 +50,10 @@ module PushType
50
50
  end
51
51
  end
52
52
 
53
+ def menu(key, &block)
54
+ PushType::MenuBuilder.select(key, &block)
55
+ end
56
+
53
57
  end
54
58
 
55
59
  module Core
@@ -60,4 +64,5 @@ require 'push_type/config'
60
64
  require 'push_type/core/engine'
61
65
  require 'push_type/rails/routes'
62
66
  require 'push_type/field_type'
67
+ require 'push_type/menu_builder'
63
68
  require 'push_type/version'
@@ -0,0 +1,32 @@
1
+ module PushType
2
+ module MenuBuilder
3
+ module Dsl
4
+
5
+ class Menu
6
+ class << self
7
+ def build(menu, &block)
8
+ @menu = menu
9
+ instance_exec(&block)
10
+ end
11
+
12
+ def item(key, &block)
13
+ @menu.item(key, &block)
14
+ end
15
+
16
+ def element(sym)
17
+ @menu.element = sym
18
+ end
19
+
20
+ def html_options(hash)
21
+ @menu.html_options.merge!(hash)
22
+ end
23
+
24
+ def active_class(val)
25
+ @menu.active_class = val
26
+ end
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ module PushType
2
+ module MenuBuilder
3
+ module Dsl
4
+
5
+ class MenuItem
6
+ class << self
7
+ def build(item, &block)
8
+ @item = item
9
+ instance_exec(&block)
10
+ @item.validate!
11
+ end
12
+
13
+ def text(val=nil, &block)
14
+ @item.text = block_given? ? block : val
15
+ end
16
+
17
+ def link(val=nil, &block)
18
+ @item.link = block_given? ? block : val
19
+ end
20
+
21
+ def active(val=nil, &block)
22
+ @item.active = block_given? ? block : val
23
+ end
24
+
25
+ def element(val)
26
+ @item.element = val
27
+ end
28
+
29
+ def item_options(hash)
30
+ @item.item_options.merge!(hash)
31
+ end
32
+
33
+ def link_options(hash)
34
+ @item.link_options.merge!(hash)
35
+ end
36
+
37
+ def active_class(val)
38
+ @item.active_class = val
39
+ end
40
+ end
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,11 @@
1
+ module PushType
2
+ module MenuBuilder
3
+ module Helpers
4
+
5
+ def render_menu(key)
6
+ PushType::MenuBuilder::MenuRenderer.new(self).render_menu(key)
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ require 'push_type/menu_builder/dsl/menu'
2
+
3
+ module PushType
4
+ module MenuBuilder
5
+
6
+ class Menu
7
+ attr_reader :items
8
+ attr_accessor :element, :html_options, :active_class
9
+
10
+ def initialize
11
+ @items = []
12
+ @element = :ul
13
+ @html_options = {}
14
+ @active_class = 'active'
15
+ end
16
+
17
+ def build(&block)
18
+ PushType::MenuBuilder::Dsl::Menu.build(self, &block)
19
+ end
20
+
21
+ def item(key, &block)
22
+ itm = find_or_create_item(key)
23
+ @items.push itm unless @items.include?(itm)
24
+ itm.build(&block) if block_given?
25
+ itm
26
+ end
27
+
28
+ def insert_at(index, key, &block)
29
+ itm = find_or_create_item(key)
30
+ @items.insert index, itm
31
+ itm.build(&block) if block_given?
32
+ itm
33
+ end
34
+
35
+ def insert_before(context, key, &block)
36
+ insert_at find_item_index(context), key, &block
37
+ end
38
+
39
+ def insert_after(context, key, &block)
40
+ insert_at find_item_index(context, 1), key, &block
41
+ end
42
+
43
+ private
44
+
45
+ def find_or_create_item(key)
46
+ @items.find { |i| i.key == key.to_sym } || PushType::MenuBuilder::MenuItem.new(key)
47
+ end
48
+
49
+ def find_item_index(key, offset = 0)
50
+ idx = @items.find_index { |i| i.key == key.to_sym }
51
+ idx ? idx + offset : @items.length
52
+ end
53
+
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,39 @@
1
+ require 'push_type/menu_builder/dsl/menu_item'
2
+
3
+ module PushType
4
+ module MenuBuilder
5
+
6
+ class MenuItem
7
+ attr_reader :key
8
+ attr_accessor :text, :link, :active, :element, :item_options, :link_options, :active_class
9
+
10
+ def initialize(key)
11
+ @key = key.to_sym
12
+ @text = key.to_s.humanize
13
+ @active = false
14
+ @element = :li
15
+ @item_options = {}
16
+ @link_options = {}
17
+ end
18
+
19
+ def build(&block)
20
+ PushType::MenuBuilder::Dsl::MenuItem.build(self, &block)
21
+ end
22
+
23
+ def submenu(&block)
24
+ @submenu ||= PushType::MenuBuilder::Menu.new
25
+ @submenu.build(&block) if block_given?
26
+ @submenu
27
+ end
28
+
29
+ def validate!
30
+ [:text, :link].each do |field|
31
+ raise "Missing '#{ field }' in MenuItem '#{ @key }'" unless send(field).present?
32
+ end
33
+ true
34
+ end
35
+
36
+ end
37
+
38
+ end
39
+ end