spontaneous 0.2.0.beta4 → 0.2.0.beta5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/Gemfile +11 -6
  4. data/Readme.markdown +136 -69
  5. data/application/css/core.css.scss +27 -7
  6. data/application/css/editing.css.scss +4 -26
  7. data/application/css/schema_error.css.scss +22 -0
  8. data/application/js/content.js +11 -3
  9. data/application/js/edit_panel.js +1 -4
  10. data/application/js/field/file.js +17 -0
  11. data/application/js/field/image.js +30 -21
  12. data/application/js/field/string.js +4 -1
  13. data/application/js/field_preview.js +21 -16
  14. data/application/js/publish.js +6 -6
  15. data/application/js/types.js +5 -13
  16. data/application/js/views.js +2 -2
  17. data/application/js/views/box_view.js +3 -2
  18. data/application/js/views/page_piece_view.js +1 -1
  19. data/application/js/views/piece_view.js +1 -1
  20. data/application/views/schema_modification_error.html.erb +13 -3
  21. data/db/migrations/20131104101935_site_must_publish_all.rb +14 -0
  22. data/lib/spontaneous.rb +0 -1
  23. data/lib/spontaneous/box_style.rb +15 -9
  24. data/lib/spontaneous/capistrano/deploy.rb +13 -1
  25. data/lib/spontaneous/change.rb +11 -13
  26. data/lib/spontaneous/cli.rb +5 -2
  27. data/lib/spontaneous/cli/assets.rb +7 -1
  28. data/lib/spontaneous/cli/console.rb +7 -1
  29. data/lib/spontaneous/cli/content.rb +35 -0
  30. data/lib/spontaneous/cli/fields.rb +3 -2
  31. data/lib/spontaneous/cli/generate.rb +5 -2
  32. data/lib/spontaneous/cli/server.rb +12 -8
  33. data/lib/spontaneous/cli/site.rb +12 -12
  34. data/lib/spontaneous/cli/user.rb +28 -14
  35. data/lib/spontaneous/collections/box_set.rb +4 -4
  36. data/lib/spontaneous/collections/field_set.rb +4 -4
  37. data/lib/spontaneous/collections/prototype_set.rb +12 -4
  38. data/lib/spontaneous/data_mapper.rb +11 -7
  39. data/lib/spontaneous/data_mapper/content_model.rb +8 -0
  40. data/lib/spontaneous/data_mapper/content_model/associations.rb +1 -1
  41. data/lib/spontaneous/data_mapper/dataset.rb +14 -2
  42. data/lib/spontaneous/data_mapper/scope.rb +33 -13
  43. data/lib/spontaneous/facet.rb +4 -0
  44. data/lib/spontaneous/field.rb +12 -12
  45. data/lib/spontaneous/field/base.rb +27 -22
  46. data/lib/spontaneous/field/boolean.rb +4 -4
  47. data/lib/spontaneous/field/date.rb +2 -2
  48. data/lib/spontaneous/field/file.rb +24 -18
  49. data/lib/spontaneous/field/html.rb +1 -1
  50. data/lib/spontaneous/field/image.rb +6 -19
  51. data/lib/spontaneous/field/location.rb +1 -1
  52. data/lib/spontaneous/field/long_string.rb +3 -3
  53. data/lib/spontaneous/field/markdown.rb +3 -3
  54. data/lib/spontaneous/field/select.rb +2 -2
  55. data/lib/spontaneous/field/string.rb +2 -2
  56. data/lib/spontaneous/field/tags.rb +2 -2
  57. data/lib/spontaneous/field/update.rb +21 -20
  58. data/lib/spontaneous/field/webvideo.rb +6 -6
  59. data/lib/spontaneous/field/webvideo/fallback.rb +2 -2
  60. data/lib/spontaneous/field/webvideo/vimeo.rb +7 -7
  61. data/lib/spontaneous/generators/site.rb +2 -2
  62. data/lib/spontaneous/generators/site/Gemfile.tt +5 -1
  63. data/lib/spontaneous/layout.rb +2 -2
  64. data/lib/spontaneous/media.rb +1 -0
  65. data/lib/spontaneous/media/file.rb +6 -5
  66. data/lib/spontaneous/media/image/attributes.rb +4 -0
  67. data/lib/spontaneous/media/image/renderable.rb +4 -4
  68. data/lib/spontaneous/media/store.rb +22 -0
  69. data/lib/spontaneous/{storage → media/store}/backend.rb +1 -1
  70. data/lib/spontaneous/{storage → media/store}/cloud.rb +1 -1
  71. data/lib/spontaneous/{storage → media/store}/local.rb +1 -1
  72. data/lib/spontaneous/media/temp_file.rb +1 -1
  73. data/lib/spontaneous/model.rb +10 -7
  74. data/lib/spontaneous/model/action.rb +7 -0
  75. data/lib/spontaneous/model/action/clean.rb +87 -0
  76. data/lib/spontaneous/model/box/allowed_types.rb +15 -1
  77. data/lib/spontaneous/model/core.rb +10 -0
  78. data/lib/spontaneous/model/core/aliases.rb +1 -1
  79. data/lib/spontaneous/model/core/content_groups.rb +1 -1
  80. data/lib/spontaneous/model/core/fields.rb +1 -1
  81. data/lib/spontaneous/model/core/modifications.rb +2 -2
  82. data/lib/spontaneous/model/core/page_search.rb +4 -0
  83. data/lib/spontaneous/model/core/publishing.rb +4 -17
  84. data/lib/spontaneous/model/core/render.rb +4 -4
  85. data/lib/spontaneous/model/core/styles.rb +2 -2
  86. data/lib/spontaneous/model/core/visibility.rb +6 -2
  87. data/lib/spontaneous/model/page.rb +6 -2
  88. data/lib/spontaneous/model/page/controllers.rb +55 -17
  89. data/lib/spontaneous/model/page/formats.rb +12 -7
  90. data/lib/spontaneous/model/page/layouts.rb +2 -2
  91. data/lib/spontaneous/model/page/locks.rb +4 -1
  92. data/lib/spontaneous/model/page/page_tree.rb +40 -6
  93. data/lib/spontaneous/output.rb +14 -52
  94. data/lib/spontaneous/output/context.rb +11 -39
  95. data/lib/spontaneous/output/context/navigation.rb +31 -0
  96. data/lib/spontaneous/output/format.rb +15 -19
  97. data/lib/spontaneous/output/renderable.rb +99 -0
  98. data/lib/spontaneous/output/store.rb +24 -0
  99. data/lib/spontaneous/output/store/backend.rb +52 -0
  100. data/lib/spontaneous/output/store/file.rb +77 -0
  101. data/lib/spontaneous/output/store/moneta.rb +117 -0
  102. data/lib/spontaneous/output/store/revision.rb +34 -0
  103. data/lib/spontaneous/output/store/store.rb +15 -0
  104. data/lib/spontaneous/output/store/transaction.rb +44 -0
  105. data/lib/spontaneous/output/template/engine.rb +17 -7
  106. data/lib/spontaneous/output/template/renderer.rb +66 -40
  107. data/lib/spontaneous/page_lock.rb +5 -7
  108. data/lib/spontaneous/page_piece.rb +2 -2
  109. data/lib/spontaneous/permissions/user.rb +14 -7
  110. data/lib/spontaneous/plugins/application/features.rb +8 -4
  111. data/lib/spontaneous/plugins/application/state.rb +12 -6
  112. data/lib/spontaneous/prototypes/box_prototype.rb +9 -10
  113. data/lib/spontaneous/prototypes/field_prototype.rb +66 -15
  114. data/lib/spontaneous/publishing/immediate.rb +30 -26
  115. data/lib/spontaneous/rack.rb +12 -7
  116. data/lib/spontaneous/rack/back.rb +43 -37
  117. data/lib/spontaneous/rack/back/base.rb +4 -4
  118. data/lib/spontaneous/rack/back/changes.rb +2 -2
  119. data/lib/spontaneous/rack/back/file.rb +16 -24
  120. data/lib/spontaneous/rack/back/map.rb +5 -5
  121. data/lib/spontaneous/rack/back/preview.rb +3 -4
  122. data/lib/spontaneous/rack/back/schema.rb +1 -1
  123. data/lib/spontaneous/rack/back/site.rb +6 -7
  124. data/lib/spontaneous/rack/front.rb +19 -16
  125. data/lib/spontaneous/rack/middleware/authenticate.rb +3 -3
  126. data/lib/spontaneous/rack/middleware/reloader.rb +3 -2
  127. data/lib/spontaneous/rack/middleware/scope.rb +25 -19
  128. data/lib/spontaneous/rack/page_controller.rb +164 -13
  129. data/lib/spontaneous/rack/public.rb +23 -62
  130. data/lib/spontaneous/rack/static.rb +2 -3
  131. data/lib/spontaneous/schema.rb +27 -8
  132. data/lib/spontaneous/schema/schema_modification.rb +9 -1
  133. data/lib/spontaneous/schema/uid.rb +2 -2
  134. data/lib/spontaneous/schema/uid_map.rb +3 -2
  135. data/lib/spontaneous/search/database.rb +2 -2
  136. data/lib/spontaneous/search/field.rb +5 -3
  137. data/lib/spontaneous/search/index.rb +12 -7
  138. data/lib/spontaneous/search/results.rb +5 -3
  139. data/lib/spontaneous/server.rb +2 -2
  140. data/lib/spontaneous/site.rb +10 -3
  141. data/lib/spontaneous/site/features.rb +26 -6
  142. data/lib/spontaneous/site/helpers.rb +9 -12
  143. data/lib/spontaneous/site/level.rb +7 -9
  144. data/lib/spontaneous/site/map.rb +9 -11
  145. data/lib/spontaneous/site/paths.rb +5 -5
  146. data/lib/spontaneous/site/publishing.rb +83 -80
  147. data/lib/spontaneous/site/schema.rb +1 -7
  148. data/lib/spontaneous/site/search.rb +8 -18
  149. data/lib/spontaneous/site/selectors.rb +60 -54
  150. data/lib/spontaneous/site/state.rb +36 -30
  151. data/lib/spontaneous/site/storage.rb +10 -16
  152. data/lib/spontaneous/state.rb +8 -0
  153. data/lib/spontaneous/style.rb +32 -33
  154. data/lib/spontaneous/version.rb +1 -1
  155. data/spontaneous.gemspec +22 -21
  156. data/test/fixtures/public/templates/layouts/default.html.cut +1 -1
  157. data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -1
  158. data/test/fixtures/public/templates/layouts/default.rss.cut +1 -1
  159. data/test/fixtures/search/config/indexes.rb +1 -1
  160. data/test/fixtures/serialisation/class_hash.yaml.erb +13 -1
  161. data/test/fixtures/serialisation/root_hash.yaml.erb +10 -0
  162. data/test/functional/test_application.rb +20 -24
  163. data/test/functional/test_back.rb +26 -27
  164. data/test/functional/test_cli.rb +146 -0
  165. data/test/functional/test_front.rb +287 -216
  166. data/test/functional/test_user_manager.rb +1 -1
  167. data/test/test_helper.rb +15 -11
  168. data/test/unit/test_alias.rb +32 -25
  169. data/test/unit/test_asset_bundler.rb +1 -1
  170. data/test/unit/test_assets.rb +34 -33
  171. data/test/unit/test_authentication.rb +1 -1
  172. data/test/unit/test_boxes.rb +16 -2
  173. data/test/unit/test_changesets.rb +23 -11
  174. data/test/unit/test_content.rb +15 -0
  175. data/test/unit/test_context.rb +139 -0
  176. data/test/unit/test_controllers.rb +374 -0
  177. data/test/{experimental → unit}/test_crypt.rb +0 -0
  178. data/test/unit/test_datamapper.rb +260 -237
  179. data/test/unit/test_datamapper_content.rb +42 -12
  180. data/test/{experimental → unit}/test_features.rb +85 -3
  181. data/test/unit/test_fields.rb +117 -42
  182. data/test/unit/test_formats.rb +11 -1
  183. data/test/unit/test_generators.rb +2 -2
  184. data/test/unit/test_helpers.rb +7 -8
  185. data/test/unit/test_images.rb +39 -2
  186. data/test/unit/test_layouts.rb +14 -12
  187. data/test/unit/test_media.rb +32 -23
  188. data/test/unit/test_output_store.rb +342 -0
  189. data/test/unit/test_page.rb +8 -1
  190. data/test/unit/test_permissions.rb +11 -7
  191. data/test/unit/test_plugins.rb +3 -3
  192. data/test/unit/test_prototype_set.rb +8 -1
  193. data/test/unit/test_publishing.rb +67 -54
  194. data/test/unit/test_render.rb +91 -38
  195. data/test/unit/test_revisions.rb +4 -4
  196. data/test/unit/test_schema.rb +109 -84
  197. data/test/unit/test_search.rb +42 -42
  198. data/test/unit/test_serialisation.rb +3 -2
  199. data/test/unit/test_site.rb +39 -27
  200. data/test/unit/test_storage.rb +9 -6
  201. data/test/unit/test_styles.rb +25 -32
  202. data/test/unit/test_templates.rb +8 -4
  203. metadata +89 -54
  204. data/lib/spontaneous/model/page/request.rb +0 -105
  205. data/lib/spontaneous/storage.rb +0 -22
@@ -0,0 +1,117 @@
1
+ require 'moneta'
2
+ require 'json'
3
+
4
+ module Spontaneous::Output::Store
5
+ # Implements the template store API on top of a Moneta key-value store.
6
+ #
7
+ # Unlike the File backend, we don't need to differentiate the storage
8
+ # locations of static, protected & dynamic templates because no integration
9
+ # with Nginx (etc) is possible
10
+ #
11
+ # This is not thread safe because the operations at the revision level aren't
12
+ # thread safe, although the simple load/store template operations are. In the
13
+ # current use case this isn't a problem & isn't likely to be one - template
14
+ # generation is a part of publishing & the logical way to speed up publishing
15
+ # is to split the rendering of pages across multiple processes in a map-reduce
16
+ # pattern which would leave the Transaction#commit & Transaction#rollback
17
+ # operations, which use the revision level methods, as the `reduce` phase
18
+ # which is single threaded whilst the template inserts would need to support
19
+ # concurrent access.
20
+ class Moneta < Backend
21
+ REVISION_SEP = ":".freeze
22
+
23
+ attr_reader :backend
24
+
25
+ def initialize(name, options = {})
26
+ @backend = ::Moneta.build do
27
+ adapter name, options
28
+ end
29
+ end
30
+
31
+ def add_revision(revision, keys)
32
+ save_revisions(revisions.push(revision))
33
+ @backend.store(revision_key(revision), serialize(keys))
34
+ end
35
+
36
+ def revisions
37
+ unserialize(@backend.load(revisions_key)) || []
38
+ end
39
+
40
+ def delete_revision(revision, keys = nil)
41
+ revision_list = revisions
42
+ if revision_list.delete(revision)
43
+ keys ||= unserialize @backend.load(revision_key(revision))
44
+ save_revisions(revision_list)
45
+ end
46
+ @backend.delete(revision_key(revision))
47
+ # want to delete the keys even if the revision hasn't been created
48
+ # this covers the case of a transaction rollback where
49
+ # we have a list of keys but no committed revision
50
+ keys.each do |key|
51
+ @backend.delete(key)
52
+ end if keys
53
+ end
54
+
55
+ def revision_key(revision)
56
+ ":revision:#{revision}"
57
+ end
58
+
59
+ def revisions_key
60
+ ":revisions:"
61
+ end
62
+
63
+ protected
64
+
65
+ # The Template class wraps a String template response with IO characteristics
66
+ # based on StringIO & also supplies File-like characteristics by
67
+ # providing a #path method.
68
+ #
69
+ # The IO methods provide an #each method for Rack, and
70
+ # the #path method can be used by the rendering engine for caching.
71
+ #
72
+ # We don't provide a #to_path method for Rack because there
73
+ # is no file represantation of this object for passing to a proxy
74
+ # server
75
+ class Template < StringIO
76
+ def initialize(template, path)
77
+ @path = path
78
+ super(template)
79
+ end
80
+
81
+ attr_reader :path
82
+ end
83
+
84
+ def store(revision, partition, path, template, transaction)
85
+ key = key_for(revision, partition, path)
86
+ transaction.push(key) if transaction
87
+ @backend.store(key, template)
88
+ end
89
+
90
+ def load(revision, partition, path)
91
+ if (template = @backend.load(key_for(revision, partition, path)))
92
+ return Template.new(template, path_for(revision, partition, path))
93
+ end
94
+ nil
95
+ end
96
+
97
+ def key_for(revision, partition, path)
98
+ [revision, partition, path].join(REVISION_SEP)
99
+ end
100
+
101
+ def path_for(revision, partition, path)
102
+ ::File.join(Spontaneous::SLASH, revision.to_s, partition, path)
103
+ end
104
+
105
+ def serialize(obj)
106
+ Spontaneous::JSON.encode(obj)
107
+ end
108
+
109
+ def unserialize(obj)
110
+ Spontaneous::JSON.parse(obj)
111
+ end
112
+
113
+ def save_revisions(revisions)
114
+ @backend.store(revisions_key, serialize(revisions.sort))
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,34 @@
1
+ module Spontaneous::Output::Store
2
+ class Revision
3
+ attr_reader :revision, :store
4
+
5
+
6
+ def initialize(revision, store)
7
+ @revision, @store = revision, store
8
+ end
9
+
10
+ def transaction
11
+ Transaction.new(@revision, @store)
12
+ end
13
+
14
+ # Tests for the existance of a static template
15
+ # This provides a way to short-cut the render step as
16
+ # if this returns a non-nil result then we can reply
17
+ # directly to the request with this template & skip the
18
+ # render step
19
+ def static_template(output)
20
+ key = @store.output_key(output)
21
+ @store.load_protected(@revision, key) || @store.load_static(@revision, key)
22
+ end
23
+
24
+ # Return a template for the given output
25
+ def dynamic_template(output, request = nil)
26
+ key = @store.output_key(output, true)
27
+ @store.load_dynamic(@revision, key)
28
+ end
29
+
30
+ def delete
31
+ @store.delete_revision(@revision)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ module Spontaneous::Output::Store
2
+ class Store
3
+ def initialize(backing)
4
+ @backing = backing
5
+ end
6
+
7
+ def revision(revision)
8
+ Spontaneous::Output::Store::Revision.new(revision, @backing)
9
+ end
10
+
11
+ def revisions
12
+ @backing.revisions
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,44 @@
1
+ module Spontaneous::Output::Store
2
+ # A Transaction is a write-only view of the template store.
3
+ # It provides #commit & #rollback mechanisms that function
4
+ # like their DB equivalents, either preserving or removing the
5
+ # modifications made.
6
+ class Transaction
7
+ attr_reader :revision
8
+
9
+ def initialize(revision, store)
10
+ @revision, @store = revision, store
11
+ @index = []
12
+ @committed = false
13
+ end
14
+
15
+ def store(output, dynamic, template)
16
+ key = @store.output_key(output, dynamic)
17
+ case
18
+ when dynamic || output.dynamic? # dynamic
19
+ @store.store_dynamic(@revision, key, template, self)
20
+ when output.page.dynamic? # protected
21
+ @store.store_protected(@revision, key, template, self)
22
+ else # static
23
+ @store.store_static(@revision, key, template, self)
24
+ end
25
+ end
26
+
27
+ # Stores call this method to register the keys
28
+ # they write to their backends. This is necessary
29
+ # because we don't want to limit our backends to those
30
+ # that are able to return keys based on a glob
31
+ def push(key)
32
+ @index.push(key)
33
+ end
34
+
35
+ def commit
36
+ @store.add_revision(@revision, @index)
37
+ @committed = true
38
+ end
39
+
40
+ def rollback
41
+ @store.delete_revision(@revision, @index) unless @committed
42
+ end
43
+ end
44
+ end
@@ -4,7 +4,9 @@ module Spontaneous::Output::Template
4
4
  # Should be initialized with the Site template roots
5
5
  def initialize(template_roots, cache = Spontaneous::Output.cache_templates?)
6
6
  @engine = template_engine_class(cache).new(template_roots, syntax)
7
- self.write_compiled_scripts = Spontaneous::Output.write_compiled_scripts?
7
+ # disabled until I figure out where to write compiled scripts when using a
8
+ # non-File based template store
9
+ self.write_compiled_scripts = false # Spontaneous::Output.write_compiled_scripts?
8
10
  end
9
11
 
10
12
  def write_compiled_scripts=(state)
@@ -19,29 +21,37 @@ module Spontaneous::Output::Template
19
21
  @engine.roots
20
22
  end
21
23
 
22
- def render(content, context, format = "html")
24
+ def render(content, context, format = :html)
23
25
  render_template(template_path(content, format), context, format)
24
26
  end
25
27
 
26
- def render_template(template_path, context, format = "html")
28
+ def render_template(template_path, context, format = :html)
27
29
  @engine.render(template_path, context, format)
28
30
  end
29
31
 
30
- def render_string(template_string, context, format = "html")
32
+ def render_string(template_string, context, format = :html)
31
33
  @engine.render_string(template_string, context, format)
32
34
  end
33
35
 
34
36
  def template_path(content, format)
35
- content.template(format)
37
+ content.template(format, self)
36
38
  end
37
39
 
38
- def template_exists?(root, template, format)
39
- @engine.template_exists?(root, template, format)
40
+ def template_exists?(template, format)
41
+ @engine.template_exists?(template, format)
42
+ end
43
+
44
+ def template_location(template, format)
45
+ @engine.template_location(template, format)
40
46
  end
41
47
 
42
48
  def template_engine_class(cache)
43
49
  ::Spontaneous::Output.template_engine_class(cache)
44
50
  end
51
+
52
+ def dynamic_template?(template_string)
53
+ @engine.dynamic_template?(template_string)
54
+ end
45
55
  end
46
56
 
47
57
  # Should be initialized with the path to the current rendered revision
@@ -12,24 +12,26 @@ module Spontaneous::Output::Template
12
12
  # caching can be effective
13
13
 
14
14
  class Renderer
15
- def initialize(cache = Spontaneous::Output.cache_templates?)
15
+ def initialize(site, cache = Spontaneous::Output.cache_templates?)
16
+ @site = site
16
17
  @cache = cache
17
18
  end
18
19
 
19
- def render(output, params = {})
20
+ def render(output, params = {}, parent_context = nil)
20
21
  output.model.with_visible do
21
- engine.render(output.content, context(output, params), output.name)
22
+ engine.render(output.content, context(output, params, parent_context), output.name)
22
23
  end
23
24
  end
24
25
 
25
- def render_string(template_string, output, params = {})
26
+ def render_string(template_string, output, params = {}, parent_context = nil)
26
27
  output.model.with_visible do
27
- engine.render_string(template_string, context(output, params), output.name)
28
+ engine.render_string(template_string, context(output, params, parent_context), output.name)
28
29
  end
29
30
  end
30
31
 
31
- def context(output, params)
32
- context_class(output).new(output.content, params).tap do |context|
32
+ def context(output, params, parent)
33
+ context_class(output).new(Spontaneous::Output::Renderable.new(output.content), params, parent).tap do |context|
34
+ context.site = @site
33
35
  context._renderer = renderer_for_context
34
36
  end
35
37
  end
@@ -51,9 +53,10 @@ module Spontaneous::Output::Template
51
53
  end
52
54
 
53
55
  def generate_context_class(output)
56
+ site = @site
54
57
  context_class = Class.new(Spontaneous::Output.context_class) do
55
58
  include Spontaneous::Output::Context::ContextCore
56
- include output.context
59
+ include output.context(site)
57
60
  end
58
61
  context_extensions.each do |mod|
59
62
  context_class.send :include, mod
@@ -68,17 +71,37 @@ module Spontaneous::Output::Template
68
71
  def write_compiled_scripts=(state)
69
72
  end
70
73
 
71
- def template_exists?(root, template, format)
72
- engine.template_exists?(root, template, format)
74
+ def template_exists?(template, format)
75
+ engine.template_exists?(template, format)
76
+ end
77
+
78
+ def template_location(template, format)
79
+ engine.template_location(template, format)
80
+ end
81
+
82
+ def is_dynamic_template?(template_string)
83
+ second_pass_engine.dynamic_template?(template_string)
84
+ end
85
+
86
+ def is_model?(klass)
87
+ klass < @site.model
73
88
  end
74
89
 
75
90
  def engine
76
- @engine ||= Spontaneous::Output::Template::PublishEngine.new(Spontaneous::Site.paths(:templates), @cache)
91
+ @engine ||= create_engine(:PublishEngine)
92
+ end
93
+
94
+ def second_pass_engine
95
+ @second_pass_engine ||= create_engine(:RequestEngine)
96
+ end
97
+
98
+ def create_engine(engine_class, template_roots = @site.paths(:templates))
99
+ Spontaneous::Output::Template.const_get(engine_class).new(template_roots, @cache)
77
100
  end
78
101
  end
79
102
 
80
103
  class PublishRenderer < Renderer
81
- def initialize(cache = Spontaneous::Output.cache_templates?)
104
+ def initialize(site, cache = Spontaneous::Output.cache_templates?)
82
105
  super
83
106
  Thread.current[:_render_cache] = {}
84
107
  end
@@ -87,8 +110,9 @@ module Spontaneous::Output::Template
87
110
  Thread.current[:_render_cache]
88
111
  end
89
112
 
113
+ # Disabled for moment
90
114
  def write_compiled_scripts=(state)
91
- engine.write_compiled_scripts = state
115
+ engine.write_compiled_scripts = false # state
92
116
  end
93
117
 
94
118
  def context_extensions
@@ -98,68 +122,70 @@ module Spontaneous::Output::Template
98
122
 
99
123
  class RequestRenderer < Renderer
100
124
  def engine
101
- @engine ||= Spontaneous::Output::Template::RequestEngine.new(Spontaneous::Site.paths(:templates), @cache)
125
+ @engine ||= create_engine(:RequestEngine)
102
126
  end
103
127
  end
104
128
 
105
129
  class PublishedRenderer < Renderer
106
- def initialize(revision, cache = Spontaneous::Output.cache_templates?)
107
- super(cache)
130
+ def initialize(site, revision, cache = Spontaneous::Output.cache_templates?)
131
+ super(site, cache)
108
132
  @revision = revision
133
+ @output_store = @site.output_store.revision(@revision)
109
134
  end
110
135
 
111
- def render(output, params = {})
112
- request = params[:request]
113
- response = params[:response]
114
- headers = request.env
115
- # Test for static template
116
- path = template_path(output, false, request)
117
- return static_template(path) if ::File.exist?(path)
118
- # Attempt to render a published template
119
- super
136
+ def render(output, params = {}, parent_context = nil)
137
+ render!(output, params, parent_context)
120
138
  rescue Cutaneous::UnknownTemplateError => e
121
- template = publish_renderer.render(output, params)
122
- render_string(template, output, params)
139
+ render_on_demand(output, params, parent_context)
123
140
  end
124
141
 
125
- def static_template(template_path)
126
- File.open(template_path)
142
+ def render!(output, params, parent_context)
143
+ if (template = @output_store.static_template(output))
144
+ return template
145
+ end
146
+ # Attempt to render a published template
147
+ if (template = @output_store.dynamic_template(output))
148
+ return engine.render_template(template, context(output, params, parent_context), output.name)
149
+ end
150
+ logger.warn("missing template for #{output}")
151
+ render_on_demand(output, params, parent_context)
127
152
  end
128
153
 
129
- def template_path(output, dynamic, request)
130
- Spontaneous::Output.output_path(@revision, output, dynamic, request.request_method)
154
+ def render_on_demand(output, params, parent_context)
155
+ template = publish_renderer.render(output, params)
156
+ render_string(template, output, params)
131
157
  end
132
158
 
133
159
  def engine
134
- @engine ||= Spontaneous::Output::Template::RequestEngine.new(revision_root, @cache)
160
+ @engine ||= create_engine(:RequestEngine, revision_root)
135
161
  end
136
162
 
137
163
  def publish_renderer
138
- @publish_renderer ||= PublishRenderer.new
164
+ @publish_renderer ||= PublishRenderer.new(@site)
139
165
  end
140
166
 
141
167
  def revision_root
142
- [Spontaneous::Site.revision_dir(@revision)/ "dynamic"]
168
+ [@site.revision_dir(@revision)/ "dynamic"]
143
169
  end
144
170
  end
145
171
 
146
172
  class PreviewRenderer < Renderer
147
- def render(output, params = {})
173
+ def render(output, params = {}, parent_context = nil)
148
174
  rendered = super(output)
149
- request_renderer.render_string(rendered, output, params)
175
+ request_renderer.render_string(rendered, output, params, parent_context)
150
176
  end
151
177
 
152
- def render_string(template_string, output, params = {})
178
+ def render_string(template_string, output, params = {}, parent_context = nil)
153
179
  rendered = super(template_string, output)
154
- request_renderer.render_string(rendered, output, params)
180
+ request_renderer.render_string(rendered, output, params, parent_context)
155
181
  end
156
182
 
157
183
  def renderer_for_context
158
- @renderer_for_context ||= PublishRenderer.new(@cache)
184
+ @renderer_for_context ||= PublishRenderer.new(@site, @cache)
159
185
  end
160
186
 
161
187
  def request_renderer
162
- @request_renderer ||= RequestRenderer.new(@cache)
188
+ @request_renderer ||= RequestRenderer.new(@site, @cache)
163
189
  end
164
190
  end
165
191
  end