puffer_pages 0.1.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (197) hide show
  1. data/.gitignore +5 -0
  2. data/.rspec +3 -1
  3. data/.rvmrc +1 -1
  4. data/.travis.yml +13 -5
  5. data/CHANGELOG.md +130 -7
  6. data/Gemfile +10 -1
  7. data/README.md +18 -20
  8. data/Rakefile +1 -1
  9. data/app/assets/javascripts/puffer/codemirror.js +4237 -2223
  10. data/app/assets/javascripts/puffer/codemirror/css.js +359 -18
  11. data/app/assets/javascripts/puffer/codemirror/htmlmixed.js +15 -14
  12. data/app/assets/javascripts/puffer/codemirror/javascript.js +91 -29
  13. data/app/assets/javascripts/puffer/codemirror/liquid.js +185 -0
  14. data/app/assets/javascripts/puffer/codemirror/xml.js +99 -27
  15. data/app/assets/javascripts/puffer/codemirror/yaml.js +95 -0
  16. data/app/assets/javascripts/puffer/liquid.js +28 -12
  17. data/app/assets/javascripts/puffer/matchbrackets.js +63 -0
  18. data/app/assets/javascripts/puffer/multiplex.js +95 -0
  19. data/app/assets/javascripts/puffer/puffer_pages.js +140 -44
  20. data/app/assets/stylesheets/puffer/codemirror.css +203 -67
  21. data/app/assets/stylesheets/puffer/codemirror/ambiance-mobile.css +6 -0
  22. data/app/assets/stylesheets/puffer/codemirror/ambiance.css +76 -0
  23. data/app/assets/stylesheets/puffer/codemirror/blackboard.css +25 -0
  24. data/app/assets/stylesheets/puffer/codemirror/cobalt.css +4 -4
  25. data/app/assets/stylesheets/puffer/codemirror/eclipse.css +1 -1
  26. data/app/assets/stylesheets/puffer/codemirror/elegant.css +2 -2
  27. data/app/assets/stylesheets/puffer/codemirror/erlang-dark.css +21 -0
  28. data/app/assets/stylesheets/puffer/codemirror/lesser-dark.css +44 -0
  29. data/app/assets/stylesheets/puffer/codemirror/monokai.css +4 -4
  30. data/app/assets/stylesheets/puffer/codemirror/neat.css +3 -3
  31. data/app/assets/stylesheets/puffer/codemirror/night.css +4 -4
  32. data/app/assets/stylesheets/puffer/codemirror/rubyblue.css +5 -5
  33. data/app/assets/stylesheets/puffer/codemirror/solarized.css +207 -0
  34. data/app/assets/stylesheets/puffer/codemirror/twilight.css +26 -0
  35. data/app/assets/stylesheets/puffer/codemirror/vibrant-ink.css +27 -0
  36. data/app/assets/stylesheets/puffer/codemirror/xq-dark.css +46 -0
  37. data/app/assets/stylesheets/puffer/puffer_pages.css +64 -35
  38. data/app/components/codemirror/form.html.erb +22 -6
  39. data/app/components/codemirror_component.rb +1 -8
  40. data/app/components/handlers/form.html.erb +8 -0
  41. data/app/components/handlers_component.rb +8 -0
  42. data/app/components/page_parts/_page_part.html.erb +6 -0
  43. data/app/components/page_parts/form.html.erb +8 -27
  44. data/app/components/page_parts_component.rb +1 -3
  45. data/app/components/render/_tree_page.html.erb +3 -2
  46. data/app/controllers/admin/layouts_controller.rb +1 -1
  47. data/app/controllers/admin/origins_controller.rb +3 -0
  48. data/app/controllers/admin/pages_controller.rb +1 -1
  49. data/app/controllers/admin/snippets_controller.rb +1 -1
  50. data/app/controllers/pages_controller.rb +3 -3
  51. data/app/helpers/puffer_pages_helper.rb +3 -3
  52. data/app/models/puffer_pages/layout.rb +2 -7
  53. data/app/models/puffer_pages/origin.rb +2 -0
  54. data/app/models/puffer_pages/page.rb +1 -117
  55. data/app/models/puffer_pages/page_part.rb +2 -22
  56. data/app/models/puffer_pages/snippet.rb +2 -5
  57. data/config/routes.rb +3 -0
  58. data/db/migrate/20120812100913_create_origins.rb +16 -0
  59. data/db/migrate/20120924120226_migrate_to_uuid.rb +126 -0
  60. data/db/migrate/20130110144030_add_handler_to_page_parts.rb +9 -0
  61. data/db/migrate/20130118064524_add_locales_to_pages.rb +9 -0
  62. data/gemfiles/Gemfile.rails-3-1 +7 -0
  63. data/gemfiles/Gemfile.rails-3-2 +7 -0
  64. data/gemfiles/Gemfile.rails-head +7 -0
  65. data/lib/puffer_pages.rb +43 -7
  66. data/lib/puffer_pages/backends.rb +16 -0
  67. data/{app/controllers/puffer_pages → lib/puffer_pages/backends/controllers}/layouts_base.rb +2 -5
  68. data/lib/puffer_pages/backends/controllers/origins_base.rb +43 -0
  69. data/lib/puffer_pages/backends/controllers/pages_base.rb +52 -0
  70. data/{app/controllers/puffer_pages → lib/puffer_pages/backends/controllers}/snippets_base.rb +2 -5
  71. data/lib/puffer_pages/backends/models/layout.rb +34 -0
  72. data/lib/puffer_pages/backends/models/mixins/importable.rb +42 -0
  73. data/lib/puffer_pages/backends/models/mixins/localable.rb +65 -0
  74. data/lib/puffer_pages/backends/models/mixins/renderable.rb +153 -0
  75. data/lib/puffer_pages/backends/models/mixins/translatable.rb +52 -0
  76. data/lib/puffer_pages/backends/models/origin.rb +59 -0
  77. data/lib/puffer_pages/backends/models/page.rb +221 -0
  78. data/lib/puffer_pages/backends/models/page_part.rb +71 -0
  79. data/lib/puffer_pages/backends/models/snippet.rb +34 -0
  80. data/lib/puffer_pages/engine.rb +13 -2
  81. data/lib/puffer_pages/extensions/context.rb +31 -0
  82. data/lib/puffer_pages/extensions/core.rb +1 -8
  83. data/lib/puffer_pages/extensions/pagenator.rb +69 -0
  84. data/lib/puffer_pages/extensions/renderer.rb +31 -0
  85. data/lib/puffer_pages/globalize/migrator.rb +23 -0
  86. data/lib/puffer_pages/handlers.rb +29 -0
  87. data/lib/puffer_pages/handlers/base.rb +21 -0
  88. data/lib/puffer_pages/handlers/yaml.rb +20 -0
  89. data/lib/puffer_pages/helpers.rb +14 -0
  90. data/lib/puffer_pages/liquid/backend.rb +16 -0
  91. data/lib/puffer_pages/liquid/file_system.rb +36 -12
  92. data/lib/puffer_pages/liquid/page_drop.rb +26 -23
  93. data/lib/puffer_pages/liquid/tags/array.rb +39 -0
  94. data/lib/puffer_pages/liquid/tags/{javascripts.rb → assets.rb} +13 -4
  95. data/lib/puffer_pages/liquid/tags/helper.rb +15 -0
  96. data/lib/puffer_pages/liquid/tags/include.rb +32 -0
  97. data/lib/puffer_pages/liquid/tags/javascript.rb +15 -0
  98. data/lib/puffer_pages/liquid/tags/partials.rb +22 -0
  99. data/lib/puffer_pages/liquid/tags/render.rb +28 -0
  100. data/lib/puffer_pages/liquid/tags/scope.rb +31 -0
  101. data/lib/puffer_pages/liquid/tags/super.rb +36 -0
  102. data/lib/puffer_pages/liquid/tags/translate.rb +56 -0
  103. data/lib/puffer_pages/liquid/tags/url.rb +53 -0
  104. data/lib/puffer_pages/liquid/tags/yield.rb +3 -1
  105. data/lib/puffer_pages/log_subscriber.rb +29 -0
  106. data/lib/puffer_pages/migrations.rb +31 -0
  107. data/lib/puffer_pages/renderer.rb +25 -0
  108. data/lib/puffer_pages/rspec/matchers.rb +27 -0
  109. data/lib/puffer_pages/rspec/matchers/render_page.rb +90 -0
  110. data/lib/puffer_pages/version.rb +1 -1
  111. data/puffer_pages.gemspec +18 -18
  112. data/spec/controllers/pages_controller_spec.rb +44 -0
  113. data/spec/controllers/puffer_pages_controller_spec.rb +194 -0
  114. data/spec/data/broken.json +8 -0
  115. data/spec/data/import.json +55 -0
  116. data/spec/data/localized.json +106 -0
  117. data/spec/data/unlocalized.json +82 -0
  118. data/spec/dummy/.rvmrc +1 -0
  119. data/spec/dummy/app/controllers/application_controller.rb +6 -0
  120. data/spec/dummy/app/views/layouts/sample.en.erb +1 -0
  121. data/spec/dummy/app/views/layouts/sample.ru.erb +1 -0
  122. data/spec/dummy/app/views/shared/_first.html.erb +1 -0
  123. data/spec/dummy/config/application.rb +21 -2
  124. data/spec/dummy/config/boot.rb +0 -2
  125. data/spec/dummy/config/database.yml +7 -1
  126. data/spec/dummy/config/environments/development.rb +11 -2
  127. data/spec/dummy/config/environments/pg_test.rb +6 -6
  128. data/spec/dummy/config/environments/production.rb +19 -3
  129. data/spec/dummy/config/environments/test.rb +6 -6
  130. data/spec/dummy/config/initializers/inflections.rb +5 -0
  131. data/spec/dummy/config/initializers/puffer_pages.rb +4 -0
  132. data/spec/dummy/config/initializers/secret_token.rb +1 -1
  133. data/spec/dummy/config/initializers/wrap_parameters.rb +5 -3
  134. data/spec/dummy/config/routes.rb +2 -1
  135. data/spec/dummy/db/migrate/{20090422092419_create_pages.rb → 20130118071511_create_pages.rb} +1 -0
  136. data/spec/dummy/db/migrate/{20090504132337_create_page_parts.rb → 20130118071512_create_page_parts.rb} +1 -0
  137. data/spec/dummy/db/migrate/{20090506102004_create_layouts.rb → 20130118071513_create_layouts.rb} +1 -0
  138. data/spec/dummy/db/migrate/{20090510121824_create_snippets.rb → 20130118071514_create_snippets.rb} +1 -0
  139. data/spec/dummy/db/migrate/20130118071515_create_origins.rb +17 -0
  140. data/spec/dummy/db/migrate/20130118071516_migrate_to_uuid.rb +127 -0
  141. data/spec/dummy/db/migrate/20130118071517_add_handler_to_page_parts.rb +10 -0
  142. data/spec/dummy/db/migrate/20130118071518_add_locales_to_pages.rb +10 -0
  143. data/spec/dummy/db/migrate/20130118071519_add_translations.rb +9 -0
  144. data/spec/dummy/db/schema.rb +65 -17
  145. data/spec/fabricators/articles_fabricator.rb +2 -2
  146. data/spec/fabricators/layouts_fabricator.rb +24 -3
  147. data/spec/fabricators/origin_fabricator.rb +5 -0
  148. data/spec/fabricators/page_parts_fabricator.rb +17 -2
  149. data/spec/fabricators/pages_fabricator.rb +20 -5
  150. data/spec/fabricators/snippets_fabricator.rb +14 -3
  151. data/spec/lib/handlers/base_spec.rb +10 -0
  152. data/spec/lib/handlers/yaml_spec.rb +34 -0
  153. data/spec/lib/handlers_spec.rb +36 -0
  154. data/spec/lib/liquid/backend_spec.rb +20 -0
  155. data/spec/lib/liquid/interpolation_spec.rb +25 -0
  156. data/spec/lib/liquid/tags/include_spec.rb +38 -0
  157. data/spec/lib/liquid/tags/partials_spec.rb +39 -0
  158. data/spec/lib/liquid/tags/scope_spec.rb +18 -0
  159. data/spec/lib/liquid/tags/translate_spec.rb +107 -0
  160. data/spec/lib/liquid/tags_spec.rb +81 -0
  161. data/spec/lib/page_drop_spec.rb +65 -0
  162. data/spec/lib/pagenator_spec.rb +176 -0
  163. data/spec/lib/rspec/matchers/render_page_spec.rb +107 -0
  164. data/spec/models/puffer_pages/layout_spec.rb +15 -0
  165. data/spec/models/puffer_pages/localable_spec.rb +62 -0
  166. data/spec/models/puffer_pages/origin_spec.rb +112 -0
  167. data/spec/models/puffer_pages/page_part_spec.rb +14 -0
  168. data/spec/models/puffer_pages/page_spec.rb +307 -0
  169. data/spec/models/puffer_pages/renderable_spec.rb +84 -0
  170. data/spec/models/puffer_pages/snippet_spec.rb +15 -0
  171. data/spec/requests/origins_requests_spec.rb +37 -0
  172. data/spec/spec_helper.rb +7 -6
  173. metadata +349 -87
  174. data/Gemfile.lock +0 -176
  175. data/app/assets/javascripts/puffer/overlay.js +0 -51
  176. data/app/controllers/puffer_pages/pages_base.rb +0 -38
  177. data/app/models/layout.rb +0 -2
  178. data/app/models/page.rb +0 -2
  179. data/app/models/page_part.rb +0 -2
  180. data/app/models/snippet.rb +0 -2
  181. data/app/views/layouts/puffer_pages_layout.html.erb +0 -2
  182. data/config/puffer_routes.rb +0 -3
  183. data/gemfiles/Gemfile-rails-3.1 +0 -5
  184. data/gemfiles/Gemfile-rails-3.1.lock +0 -173
  185. data/gemfiles/Gemfile-rails-3.2 +0 -5
  186. data/gemfiles/Gemfile-rails-3.2.lock +0 -171
  187. data/lib/puffer_pages/extensions/controller.rb +0 -30
  188. data/lib/puffer_pages/extensions/mapper.rb +0 -23
  189. data/lib/puffer_pages/liquid/tags/page_attribute.rb +0 -39
  190. data/lib/puffer_pages/liquid/tags/stylesheets.rb +0 -38
  191. data/spec/controllers/articles_controller_spec.rb +0 -65
  192. data/spec/dummy/app/controllers/articles_controller.rb +0 -9
  193. data/spec/integration/navigation_spec.rb +0 -9
  194. data/spec/lib/drops_spec.rb +0 -55
  195. data/spec/lib/tags_spec.rb +0 -98
  196. data/spec/models/page_spec.rb +0 -235
  197. data/spec/puffer_pages_spec.rb +0 -7
@@ -0,0 +1,9 @@
1
+ class AddHandlerToPageParts < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :page_parts, :handler, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :page_parts, :handler
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddLocalesToPages < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :pages, :locales, :text
4
+ end
5
+
6
+ def self.down
7
+ remove_column :pages, :locales
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'puffer', github: 'puffer/puffer'
6
+ gem 'activeuuid', github: 'jashmenn/activeuuid'
7
+ gem 'rails', '~> 3.1.0'
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'puffer', github: 'puffer/puffer'
6
+ gem 'activeuuid', github: 'jashmenn/activeuuid'
7
+ gem 'rails', '~> 3.2.0'
@@ -0,0 +1,7 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec path: '../'
4
+
5
+ gem 'puffer', github: 'puffer/puffer'
6
+ gem 'activeuuid', github: 'jashmenn/activeuuid'
7
+ gem 'rails', github: 'rails/rails'
data/lib/puffer_pages.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  module PufferPages
2
+ autoload :SnippetsBase, 'puffer_pages/backends/controllers/snippets_base'
3
+ autoload :LayoutsBase, 'puffer_pages/backends/controllers/layouts_base'
4
+ autoload :PagesBase, 'puffer_pages/backends/controllers/pages_base'
5
+ autoload :OriginsBase, 'puffer_pages/backends/controllers/origins_base'
2
6
 
3
7
  class PufferPagesError < StandardError
4
8
  end
@@ -9,31 +13,63 @@ module PufferPages
9
13
  class LayoutMissed < PufferPagesError
10
14
  end
11
15
 
16
+ class ImportFailed < PufferPagesError
17
+ end
18
+
12
19
  mattr_accessor :primary_page_part_name
13
20
  self.primary_page_part_name = 'body'
14
21
 
15
22
  mattr_accessor :single_section_page_path
16
23
  self.single_section_page_path = false
17
24
 
18
- mattr_accessor :codemirror_buttons
19
- self.codemirror_buttons = [:fullscreen]
25
+ mattr_accessor :localize
26
+ self.localize = false
27
+
28
+ mattr_accessor :access_token
29
+ self.access_token = nil
30
+
31
+ mattr_accessor :export_path
32
+ self.export_path = '/admin/origins/export'
33
+
34
+ mattr_accessor :install_i18n_backend
35
+ self.install_i18n_backend = true
20
36
 
21
37
  def self.setup
22
38
  yield self
23
39
  end
24
40
 
41
+ def self.i18n_backend
42
+ @i18n_backend ||= PufferPages::Liquid::Backend.new
43
+ end
25
44
  end
26
45
 
27
46
  require 'puffer'
28
47
  require 'liquid'
48
+ require 'uuidtools'
49
+ require 'activeuuid'
29
50
  require 'nested_set'
51
+ require 'contextuality'
30
52
 
53
+ require 'puffer_pages/helpers'
31
54
  require 'puffer_pages/engine'
55
+ require 'puffer_pages/backends'
56
+ require 'puffer_pages/handlers'
57
+ require 'puffer_pages/migrations'
58
+ require 'puffer_pages/log_subscriber'
32
59
  require 'puffer_pages/extensions/core'
33
- require 'puffer_pages/extensions/mapper'
34
- require 'puffer_pages/extensions/controller'
60
+ require 'puffer_pages/extensions/context'
61
+ require 'puffer_pages/extensions/renderer'
62
+ require 'puffer_pages/extensions/pagenator'
35
63
 
64
+ require 'puffer_pages/liquid/tags/url'
36
65
  require 'puffer_pages/liquid/tags/yield'
37
- require 'puffer_pages/liquid/tags/stylesheets'
38
- require 'puffer_pages/liquid/tags/javascripts'
39
- require 'puffer_pages/liquid/tags/page_attribute'
66
+ require 'puffer_pages/liquid/tags/array'
67
+ require 'puffer_pages/liquid/tags/assets'
68
+ require 'puffer_pages/liquid/tags/helper'
69
+ require 'puffer_pages/liquid/tags/render'
70
+ require 'puffer_pages/liquid/tags/scope'
71
+ require 'puffer_pages/liquid/tags/super'
72
+ require 'puffer_pages/liquid/tags/include'
73
+ require 'puffer_pages/liquid/tags/partials'
74
+ require 'puffer_pages/liquid/tags/translate'
75
+ require 'puffer_pages/liquid/tags/javascript'
@@ -0,0 +1,16 @@
1
+ module PufferPages
2
+ module Backends
3
+ autoload :Snippet, 'puffer_pages/backends/models/snippet'
4
+ autoload :Layout, 'puffer_pages/backends/models/layout'
5
+ autoload :Page, 'puffer_pages/backends/models/page'
6
+ autoload :PagePart, 'puffer_pages/backends/models/page_part'
7
+ autoload :Origin, 'puffer_pages/backends/models/origin'
8
+
9
+ module Mixins
10
+ autoload :Renderable, 'puffer_pages/backends/models/mixins/renderable'
11
+ autoload :Importable, 'puffer_pages/backends/models/mixins/importable'
12
+ autoload :Translatable, 'puffer_pages/backends/models/mixins/translatable'
13
+ autoload :Localable, 'puffer_pages/backends/models/mixins/localable'
14
+ end
15
+ end
16
+ end
@@ -1,9 +1,7 @@
1
1
  class PufferPages::LayoutsBase < Puffer::Base
2
- unloadable
3
-
4
2
  setup do
5
3
  group :pages
6
- model_name :layout
4
+ model_name :'puffer_pages/layout'
7
5
  end
8
6
 
9
7
  index do
@@ -12,7 +10,6 @@ class PufferPages::LayoutsBase < Puffer::Base
12
10
 
13
11
  form do
14
12
  field :name
15
- field :body, :type => :codemirror
13
+ field :body, type: :codemirror, mode: 'text/x-liquid-html'
16
14
  end
17
-
18
15
  end
@@ -0,0 +1,43 @@
1
+ class PufferPages::OriginsBase < Puffer::Base
2
+ skip_before_filter :require_puffer_user, only: :export
3
+
4
+ member do
5
+ get :import
6
+ end
7
+
8
+ collection do
9
+ get :export, display: false
10
+ end
11
+
12
+ def import
13
+ @record = resource.member
14
+ @record.import!
15
+ redirect_to admin_origins_path
16
+ end
17
+
18
+ def export
19
+ if params[:token] == PufferPages.access_token
20
+ render json: resource.model.export_json
21
+ else
22
+ render nothing: true, status: 401
23
+ end
24
+ end
25
+
26
+ setup do
27
+ group :pages
28
+ model_name :'puffer_pages/origin'
29
+ end
30
+
31
+ index do
32
+ field :name
33
+ field :uri
34
+ field :token
35
+ end
36
+
37
+ form do
38
+ field :name
39
+ field :host
40
+ field :path
41
+ field :token
42
+ end
43
+ end
@@ -0,0 +1,52 @@
1
+ class PufferPages::PagesBase < Puffer::TreeBase
2
+ helper :puffer_pages
3
+
4
+ setup do
5
+ group :pages
6
+ model_name :'puffer_pages/page'
7
+ end
8
+
9
+ tree do
10
+ #field :name, :render => :tree_page
11
+ field :name, render: -> { render :partial => 'tree_page', :object => record }
12
+ end
13
+
14
+ def new
15
+ @record = resource.new_member
16
+ if !@record.inherited_page_part(PufferPages.primary_page_part_name)
17
+ @record.page_parts.build :name => PufferPages.primary_page_part_name
18
+ end
19
+ respond_with @record
20
+ end
21
+
22
+ index do
23
+ field :name
24
+ field :slug
25
+ field :layout_name
26
+ field :status
27
+ end
28
+
29
+ # filter do
30
+ # field :name
31
+ # field :slug
32
+ # field :layout_name
33
+ # field :'page_parts.name'
34
+ # field :'page_parts.body'
35
+ # end
36
+
37
+ form do
38
+ field :parent_id, type: :hidden
39
+ field :name
40
+ field :slug
41
+ field :layout_name, select: :possible_layouts, include_blank: false
42
+ field :status, select: :possible_statuses, include_blank: false
43
+ field :page_parts, type: :page_parts do
44
+ field :handler, type: :handlers, include_blank: false,
45
+ html: { 'data-codemirror-mode-select' => true }
46
+ field :body, type: :codemirror, input_only: true, mode: 'text/x-liquid-html'
47
+ field :name, type: :hidden, html: { data: { acts: 'name' } }
48
+ field :_destroy, type: :hidden, html: { data: { acts: 'destroy' } }
49
+ end
50
+ field :locales, type: :codemirror, mode: 'text/x-yaml'
51
+ end
52
+ end
@@ -1,9 +1,7 @@
1
1
  class PufferPages::SnippetsBase < Puffer::Base
2
- unloadable
3
-
4
2
  setup do
5
3
  group :pages
6
- model_name :snippet
4
+ model_name :'puffer_pages/snippet'
7
5
  end
8
6
 
9
7
  index do
@@ -12,7 +10,6 @@ class PufferPages::SnippetsBase < Puffer::Base
12
10
 
13
11
  form do
14
12
  field :name
15
- field :body, :type => :codemirror
13
+ field :body, type: :codemirror, mode: 'text/x-liquid-html'
16
14
  end
17
-
18
15
  end
@@ -0,0 +1,34 @@
1
+ class PufferPages::Backends::Layout < ActiveRecord::Base
2
+ include ActiveUUID::UUID
3
+ include PufferPages::Backends::Mixins::Renderable
4
+ include PufferPages::Backends::Mixins::Importable
5
+ include PufferPages::Backends::Mixins::Translatable
6
+ self.abstract_class = true
7
+ self.table_name = :layouts
8
+
9
+ attr_protected
10
+
11
+ validates_presence_of :name
12
+ validates_uniqueness_of :name
13
+
14
+ def self.find_layout(name)
15
+ where(:name => name).first
16
+ end
17
+
18
+ def render *args
19
+ _, context = normalize_render_options *args
20
+ render_template body, context, additional_render_options
21
+ end
22
+
23
+ def additional_render_options
24
+ { environment: { processed: self } }
25
+ end
26
+
27
+ def i18n_scope
28
+ [:layouts, name.to_sym]
29
+ end
30
+
31
+ def i18n_defaults
32
+ []
33
+ end
34
+ end
@@ -0,0 +1,42 @@
1
+ module PufferPages
2
+ module Backends
3
+ module Mixins
4
+ module Importable
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ def export_json
9
+ all
10
+ end
11
+
12
+ def import_destroy
13
+ destroy_all
14
+ end
15
+
16
+ def import_json json
17
+ data = json.is_a?(String) ? ActiveSupport::JSON.decode(json) : json.map(&:stringify_keys!)
18
+
19
+ import_destroy
20
+
21
+ data.each do |attributes|
22
+ associations = attributes.keys.each_with_object({}) do |attribute, hsh|
23
+ if scoped.reflect_on_association(attribute.to_sym)
24
+ hsh[attribute] = attributes.delete(attribute)
25
+ end
26
+ end
27
+
28
+ attributes = attributes.with_indifferent_access
29
+ record = scoped.create!(attributes) do |record|
30
+ record.id = attributes[:id] if attributes[:id].present?
31
+ end
32
+
33
+ associations.each do |association, attributes|
34
+ record.send(association).import_json(attributes)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,65 @@
1
+ module PufferPages
2
+ module Backends
3
+ module Mixins
4
+ module Localable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ serialize :locales, Locales
9
+
10
+ validate do
11
+ errors[:locales] = locales.error unless locales.valid?
12
+ end
13
+ end
14
+
15
+ def locales
16
+ value = read_attribute(:locales)
17
+ value.is_a?(Locales) ? value : Locales.new(value)
18
+ end
19
+
20
+ class Locales < ActiveSupport::HashWithIndifferentAccess
21
+ def initialize source
22
+ update (source.presence || {}).stringify_keys
23
+ super()
24
+ end
25
+
26
+ def valid?
27
+ !error
28
+ end
29
+
30
+ def error
31
+ translations
32
+ rescue ::SyntaxError => e
33
+ e.message
34
+ else
35
+ false
36
+ end
37
+
38
+ def translations
39
+ @translations ||= Hash[map do |(locale, yaml)|
40
+ load_arguments = [yaml]
41
+ load_arguments.push "<#{locale}>" if YAML.method(:load).arity == -2
42
+ result = YAML.load yaml
43
+ result = result.presence || {}
44
+ raise ::SyntaxError.new("(<#{locale}>): Locale should be a hash") unless result.is_a?(Hash)
45
+ [locale.to_sym, result.deep_symbolize_keys]
46
+ end]
47
+ end
48
+
49
+ class << self
50
+ def dump value
51
+ value = value.is_a?(Locales) ? value : Locales.new(value)
52
+ value ? YAML.dump(value.to_hash) : nil
53
+ end
54
+
55
+ def load value
56
+ return unless value
57
+ value = YAML.load(value) if value.is_a?(String)
58
+ value.is_a?(Locales) ? value : Locales.new(value)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,153 @@
1
+ module PufferPages
2
+ module Backends
3
+ module Mixins
4
+ module Renderable
5
+ extend ActiveSupport::Concern
6
+
7
+ def template
8
+ @template ||= ::Liquid::Template.parse(self)
9
+ end
10
+
11
+ private
12
+
13
+
14
+ # Method gets some arguments and returns source, context and additional
15
+ # depends on arguments properties
16
+ # Ex.
17
+ # normalize_render_options Object, Liquid::Context, Hash
18
+ # => Object, Liquid::Context, Hash
19
+ #
20
+ # normalize_render_options Liquid::Context, Hash
21
+ # => nil, Liquid::Context, Hash
22
+ #
23
+ # normalize_render_options Object, Hash1, Hash2
24
+ # => Object, Hash1, Hash2
25
+ #
26
+ # normalize_render_options Hash1, Hash2
27
+ # => nil, Hash1, Hash2
28
+ #
29
+ # normalize_render_options Liquid::Context
30
+ # => nil, Liquid::Context, {}
31
+ #
32
+ # normalize_render_options Hash
33
+ # => nil, Hash, {}
34
+ #
35
+ # normalize_render_options Object, Hash
36
+ # => Object, Hash, {}
37
+ #
38
+ # normalize_render_options Object, Liquid::Context
39
+ # => Object, Liquid::Context, {}
40
+ #
41
+ # normalize_render_options
42
+ # => nil, {}, {}
43
+ #
44
+ # normalize_render_options Object, Liquid::Contex, Hash, Hash
45
+ # => raise ArgumentError
46
+ def normalize_render_options *args
47
+ source, context, additional = nil, {}, {}
48
+ context_or_additional = args.extract_options!
49
+ case args.count
50
+ when 0
51
+ context = context_or_additional
52
+ when 1
53
+ case args.first
54
+ when ::Liquid::Context, ::Hash
55
+ context = args.first
56
+ additional = context_or_additional
57
+ else
58
+ source = args.first
59
+ context = context_or_additional
60
+ end
61
+ when 2
62
+ source, context = *args
63
+ additional = context_or_additional
64
+ else
65
+ raise ArgumentError.new("Wrong number of arguments (#{args.count.next} for 0-3)")
66
+ end
67
+
68
+ return source, merge_context(context, additional)
69
+ end
70
+
71
+ def merge_context context, additional
72
+ additional = normalize_context_options(additional)
73
+
74
+ if context.is_a?(::Liquid::Context)
75
+ context.merge additional[:drops]
76
+ context.merge additional[:environment]
77
+ context.registers.merge! additional[:registers]
78
+ else
79
+ context = normalize_context_options(context)
80
+ context[:drops].merge! additional[:drops]
81
+ context[:environment].merge! additional[:environment]
82
+ context[:registers].merge! additional[:registers]
83
+ end
84
+
85
+ context
86
+ end
87
+
88
+ def normalize_context_options options
89
+ detector = [:drops, :environment, :registers]
90
+ if options.is_a?(Hash) && (options.keys - detector == [])
91
+ drops = options[:drops] || {}
92
+ environment = options[:environment] || {}
93
+ registers = options[:registers] || {}
94
+ else
95
+ drops = options
96
+ environment = {}
97
+ registers = {}
98
+ end
99
+ {
100
+ drops: drops.stringify_keys,
101
+ environment: environment.symbolize_keys,
102
+ registers: registers.symbolize_keys
103
+ }
104
+ end
105
+
106
+ def render_template source, context = {}, additional = {}
107
+ template = source.respond_to?(:template) ? source.template : ::Liquid::Template.parse(source)
108
+ context = merge_context(context, additional)
109
+
110
+ if context.is_a?(::Liquid::Context)
111
+ instrument_render! context do
112
+ template.send(render_method, context)
113
+ end
114
+ else
115
+ tracker = PufferPages::Liquid::Tracker.new
116
+ context = merge_context(context, registers: {
117
+ :file_system => PufferPages::Liquid::FileSystem.new,
118
+ :tracker => tracker
119
+ })
120
+
121
+ instrument_render! context do
122
+ tracker.cleanup template.send(render_method,
123
+ context[:drops].merge!(context[:environment]),
124
+ registers: context[:registers])
125
+ end
126
+ end
127
+ end
128
+
129
+ def instrument_render! context, additional = {}, &block
130
+ context = merge_context(context, additional) if additional.present?
131
+
132
+ payload = { subject: self }
133
+ if context.is_a?(::Liquid::Context)
134
+ drops = context.scopes.each_with_object({}) { |scope, hash| hash.merge! scope }
135
+ payload.merge! drops: drops, registers: context.registers
136
+ else
137
+ payload.merge! drops: context[:drops], registers: context[:registers]
138
+ end
139
+
140
+ ActiveSupport::Notifications.instrument(instrument_name, payload, &block)
141
+ end
142
+
143
+ def instrument_name
144
+ "render_#{self.class.to_s.demodulize.underscore}.puffer_pages"
145
+ end
146
+
147
+ def render_method
148
+ Rails.application.config.puffer_pages.raise_errors ? 'render!' : 'render'
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end