spontaneous 0.2.0.alpha7 → 0.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (247) hide show
  1. data/Gemfile +10 -4
  2. data/Readme.markdown +1 -1
  3. data/application/css/definitions.css.scss +5 -0
  4. data/application/css/dialogue.css.scss +62 -0
  5. data/application/js/content.js +1 -1
  6. data/application/js/dom.js +1 -1
  7. data/application/js/event_source.js +3 -0
  8. data/application/js/{field_types/date_field.js → field/date.js} +2 -2
  9. data/application/js/{field_types/file_field.js → field/file.js} +2 -2
  10. data/application/js/{field_types/image_field.js → field/image.js} +54 -20
  11. data/application/js/{field_types/long_string_field.js → field/long_string.js} +2 -2
  12. data/application/js/{field_types/markdown_field.js → field/markdown.js} +2 -2
  13. data/application/js/{field_types/select_field.js → field/select.js} +2 -2
  14. data/application/js/{field_types/string_field.js → field/string.js} +21 -7
  15. data/application/js/{field_types/webvideo_field.js → field/webvideo.js} +2 -2
  16. data/application/js/field.js +2 -2
  17. data/application/js/publish.js +99 -19
  18. data/application/js/spontaneous.js +8 -8
  19. data/application/js/top_bar.js +6 -4
  20. data/db/migrations/20130109125023_add_page_publish_lock.rb +17 -0
  21. data/db/migrations/20130111161934_convert_bcrypt_passwords.rb +22 -0
  22. data/db/migrations/20130114120000_create_revision_tables.rb +106 -0
  23. data/db/migrations/20130116220423_add_index_to_archive.rb +9 -0
  24. data/lib/spontaneous/box.rb +53 -18
  25. data/lib/spontaneous/box_style.rb +2 -3
  26. data/lib/spontaneous/change.rb +39 -13
  27. data/lib/spontaneous/cli/fields.rb +29 -0
  28. data/lib/spontaneous/cli/init.rb +2 -2
  29. data/lib/spontaneous/cli/migrate.rb +0 -1
  30. data/lib/spontaneous/cli/server.rb +14 -10
  31. data/lib/spontaneous/cli/site.rb +20 -9
  32. data/lib/spontaneous/cli.rb +8 -6
  33. data/lib/spontaneous/collections/box_set.rb +11 -0
  34. data/lib/spontaneous/collections/field_set.rb +24 -1
  35. data/lib/spontaneous/concern.rb +37 -0
  36. data/lib/spontaneous/config.rb +3 -4
  37. data/lib/spontaneous/crypt/version.rb +130 -0
  38. data/lib/spontaneous/crypt.rb +84 -0
  39. data/lib/spontaneous/data_mapper/content_model/associations.rb +199 -0
  40. data/lib/spontaneous/data_mapper/content_model/column_accessors.rb +52 -0
  41. data/lib/spontaneous/data_mapper/content_model/instance_hooks.rb +34 -0
  42. data/lib/spontaneous/data_mapper/content_model/serialization.rb +54 -0
  43. data/lib/spontaneous/data_mapper/content_model/timestamps.rb +39 -0
  44. data/lib/spontaneous/data_mapper/content_model.rb +343 -0
  45. data/lib/spontaneous/data_mapper/content_table.rb +103 -0
  46. data/lib/spontaneous/data_mapper/dataset.rb +194 -0
  47. data/lib/spontaneous/data_mapper/scope.rb +195 -0
  48. data/lib/spontaneous/data_mapper.rb +161 -0
  49. data/lib/spontaneous/facet.rb +2 -2
  50. data/lib/spontaneous/field/base.rb +418 -0
  51. data/lib/spontaneous/field/date.rb +54 -0
  52. data/lib/spontaneous/{field_version.rb → field/field_version.rb} +1 -1
  53. data/lib/spontaneous/field/file.rb +100 -0
  54. data/lib/spontaneous/{field_types/image_field.rb → field/image.rb} +33 -33
  55. data/lib/spontaneous/{field_types/location_field.rb → field/location.rb} +2 -2
  56. data/lib/spontaneous/{field_types/long_string_field.rb → field/long_string.rb} +3 -3
  57. data/lib/spontaneous/field/markdown.rb +36 -0
  58. data/lib/spontaneous/{field_types/select_field.rb → field/select.rb} +4 -5
  59. data/lib/spontaneous/field/string.rb +17 -0
  60. data/lib/spontaneous/field/update.rb +156 -0
  61. data/lib/spontaneous/field/webvideo.rb +310 -0
  62. data/lib/spontaneous/field.rb +80 -0
  63. data/lib/spontaneous/generators/site/Gemfile.tt +2 -2
  64. data/lib/spontaneous/generators/site/config/environments/development.rb.tt +1 -1
  65. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +1 -1
  66. data/lib/spontaneous/generators/site/lib/content.rb.tt +6 -0
  67. data/lib/spontaneous/generators/site/schema/box.rb.tt +3 -2
  68. data/lib/spontaneous/generators/site/schema/page.rb.tt +3 -1
  69. data/lib/spontaneous/generators/site/schema/piece.rb.tt +3 -1
  70. data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +3 -1
  71. data/lib/spontaneous/generators/site.rb +4 -3
  72. data/lib/spontaneous/image_size.rb +8 -1
  73. data/lib/spontaneous/layout.rb +5 -1
  74. data/lib/spontaneous/loader.rb +2 -5
  75. data/lib/spontaneous/media/file.rb +11 -2
  76. data/lib/spontaneous/media/temp_file.rb +23 -0
  77. data/lib/spontaneous/media.rb +20 -39
  78. data/lib/spontaneous/{plugins → model/box}/allowed_types.rb +38 -17
  79. data/lib/spontaneous/model/box.rb +18 -0
  80. data/lib/spontaneous/{plugins → model/core}/aliases.rb +10 -14
  81. data/lib/spontaneous/{plugins → model/core}/boxes.rb +2 -2
  82. data/lib/spontaneous/{plugins → model/core}/content_groups.rb +2 -2
  83. data/lib/spontaneous/model/core/editor_class.rb +4 -0
  84. data/lib/spontaneous/{plugins → model/core}/entries.rb +19 -7
  85. data/lib/spontaneous/{plugins → model/core}/entry.rb +3 -3
  86. data/lib/spontaneous/{plugins → model/core}/fields.rb +38 -5
  87. data/lib/spontaneous/{plugins → model/core}/instance_code.rb +2 -2
  88. data/lib/spontaneous/{plugins → model/core}/media.rb +2 -12
  89. data/lib/spontaneous/{plugins → model/core}/modifications.rb +7 -6
  90. data/lib/spontaneous/model/core/page_search.rb +36 -0
  91. data/lib/spontaneous/{plugins → model/core}/permissions.rb +4 -4
  92. data/lib/spontaneous/{plugins → model/core}/prototypes.rb +4 -4
  93. data/lib/spontaneous/{plugins → model/core}/publishing.rb +93 -115
  94. data/lib/spontaneous/{plugins → model/core}/render.rb +2 -2
  95. data/lib/spontaneous/{plugins → model/core}/schema_hierarchy.rb +7 -11
  96. data/lib/spontaneous/model/core/schema_id.rb +65 -0
  97. data/lib/spontaneous/{plugins → model/core}/schema_title.rb +2 -2
  98. data/lib/spontaneous/{plugins → model/core}/serialisation.rb +2 -2
  99. data/lib/spontaneous/{plugins → model/core}/styles.rb +2 -2
  100. data/lib/spontaneous/{plugins → model/core}/supertype.rb +2 -2
  101. data/lib/spontaneous/{plugins → model/core}/visibility.rb +7 -48
  102. data/lib/spontaneous/model/core.rb +143 -0
  103. data/lib/spontaneous/{plugins → model/page}/controllers.rb +3 -3
  104. data/lib/spontaneous/{plugins → model}/page/formats.rb +2 -2
  105. data/lib/spontaneous/{plugins → model/page}/layouts.rb +2 -2
  106. data/lib/spontaneous/model/page/locks.rb +14 -0
  107. data/lib/spontaneous/{plugins → model/page}/page_tree.rb +3 -3
  108. data/lib/spontaneous/{plugins → model/page}/paths.rb +30 -12
  109. data/lib/spontaneous/{plugins → model}/page/request.rb +2 -2
  110. data/lib/spontaneous/{plugins → model/page}/site_map.rb +2 -2
  111. data/lib/spontaneous/model/page/site_timestamps.rb +44 -0
  112. data/lib/spontaneous/{page.rb → model/page.rb} +49 -28
  113. data/lib/spontaneous/{piece.rb → model/piece.rb} +7 -6
  114. data/lib/spontaneous/model.rb +97 -0
  115. data/lib/spontaneous/output/context.rb +1 -1
  116. data/lib/spontaneous/output/format.rb +4 -0
  117. data/lib/spontaneous/output/template/renderer.rb +2 -2
  118. data/lib/spontaneous/output.rb +2 -2
  119. data/lib/spontaneous/page_lock.rb +62 -0
  120. data/lib/spontaneous/page_piece.rb +1 -1
  121. data/lib/spontaneous/permissions/access_key.rb +9 -4
  122. data/lib/spontaneous/permissions/user.rb +19 -9
  123. data/lib/spontaneous/permissions.rb +2 -5
  124. data/lib/spontaneous/plugins/application/facets.rb +1 -2
  125. data/lib/spontaneous/plugins/application/features.rb +1 -1
  126. data/lib/spontaneous/plugins/application/paths.rb +1 -1
  127. data/lib/spontaneous/plugins/application/render.rb +1 -1
  128. data/lib/spontaneous/plugins/application/serialisation.rb +1 -1
  129. data/lib/spontaneous/plugins/application/state.rb +30 -1
  130. data/lib/spontaneous/plugins/application/system.rb +12 -12
  131. data/lib/spontaneous/prototypes/box_prototype.rb +1 -1
  132. data/lib/spontaneous/prototypes/field_prototype.rb +3 -6
  133. data/lib/spontaneous/prototypes/style_prototype.rb +1 -1
  134. data/lib/spontaneous/publishing/immediate.rb +77 -49
  135. data/lib/spontaneous/publishing/revision.rb +355 -0
  136. data/lib/spontaneous/publishing/simultaneous.rb +10 -49
  137. data/lib/spontaneous/publishing.rb +1 -0
  138. data/lib/spontaneous/rack/around_back.rb +1 -1
  139. data/lib/spontaneous/rack/around_front.rb +2 -4
  140. data/lib/spontaneous/rack/around_preview.rb +1 -1
  141. data/lib/spontaneous/rack/back.rb +80 -63
  142. data/lib/spontaneous/rack/cacheable_file.rb +2 -2
  143. data/lib/spontaneous/rack/cookie_authentication.rb +1 -1
  144. data/lib/spontaneous/rack/front.rb +1 -1
  145. data/lib/spontaneous/rack/helpers.rb +8 -9
  146. data/lib/spontaneous/{page_controller.rb → rack/page_controller.rb} +1 -1
  147. data/lib/spontaneous/rack/public.rb +3 -3
  148. data/lib/spontaneous/rack.rb +15 -15
  149. data/lib/spontaneous/schema/uid.rb +4 -1
  150. data/lib/spontaneous/schema.rb +57 -24
  151. data/lib/spontaneous/search/database.rb +12 -1
  152. data/lib/spontaneous/search/index.rb +34 -6
  153. data/lib/spontaneous/search/results.rb +1 -1
  154. data/lib/spontaneous/server.rb +3 -3
  155. data/lib/spontaneous/simultaneous.rb +53 -0
  156. data/lib/spontaneous/{plugins/site → site}/features.rb +2 -2
  157. data/lib/spontaneous/{plugins/site → site}/helpers.rb +2 -3
  158. data/lib/spontaneous/{plugins/site → site}/hooks.rb +2 -2
  159. data/lib/spontaneous/{plugins/site → site}/instance.rb +4 -6
  160. data/lib/spontaneous/{plugins/site → site}/level.rb +2 -2
  161. data/lib/spontaneous/{plugins/site → site}/map.rb +4 -4
  162. data/lib/spontaneous/{plugins/site → site}/paths.rb +2 -2
  163. data/lib/spontaneous/site/publishing.rb +89 -0
  164. data/lib/spontaneous/{plugins/site → site}/schema.rb +4 -4
  165. data/lib/spontaneous/{plugins/site → site}/search.rb +2 -2
  166. data/lib/spontaneous/{plugins/site → site}/selectors.rb +15 -7
  167. data/lib/spontaneous/{plugins/site → site}/state.rb +2 -2
  168. data/lib/spontaneous/{plugins/site → site}/storage.rb +2 -2
  169. data/lib/spontaneous/{plugins/site → site}/url.rb +2 -2
  170. data/lib/spontaneous/site.rb +31 -14
  171. data/lib/spontaneous/state.rb +5 -6
  172. data/lib/spontaneous/style.rb +3 -2
  173. data/lib/spontaneous/utils/database/mysql_dumper.rb +13 -0
  174. data/lib/spontaneous/utils/database/postgres_dumper.rb +5 -0
  175. data/lib/spontaneous/version.rb +1 -1
  176. data/lib/spontaneous.rb +34 -89
  177. data/spontaneous.gemspec +112 -114
  178. data/test/experimental/test_crypt.rb +158 -0
  179. data/test/experimental/test_features.rb +3 -3
  180. data/test/fixtures/example_application/config/environments/development.rb +1 -1
  181. data/test/fixtures/example_application/lib/content.rb +5 -0
  182. data/test/fixtures/example_application/schema/page.rb +2 -1
  183. data/test/fixtures/example_application/schema/piece.rb +3 -2
  184. data/test/fixtures/serialisation/class_hash.yaml.erb +5 -5
  185. data/test/fixtures/serialisation/root_hash.yaml.erb +8 -0
  186. data/test/functional/test_application.rb +12 -1
  187. data/test/functional/test_back.rb +80 -48
  188. data/test/functional/test_front.rb +39 -46
  189. data/test/functional/test_user_manager.rb +3 -9
  190. data/test/javascript/test_markdown.rb +2 -2
  191. data/test/test_helper.rb +78 -23
  192. data/test/unit/test_alias.rb +21 -15
  193. data/test/unit/test_asset_bundler.rb +3 -3
  194. data/test/unit/test_assets.rb +2 -2
  195. data/test/unit/test_async.rb +7 -6
  196. data/test/unit/test_authentication.rb +43 -37
  197. data/test/unit/test_boxes.rb +46 -21
  198. data/test/unit/test_changesets.rb +65 -20
  199. data/test/unit/test_config.rb +9 -9
  200. data/test/unit/test_content.rb +50 -51
  201. data/test/unit/test_content_inheritance.rb +6 -20
  202. data/test/unit/test_datamapper.rb +1330 -0
  203. data/test/unit/test_datamapper_content.rb +214 -0
  204. data/test/unit/test_fields.rb +543 -54
  205. data/test/unit/test_formats.rb +2 -3
  206. data/test/unit/test_generators.rb +6 -6
  207. data/test/unit/test_helpers.rb +1 -1
  208. data/test/unit/test_image_size.rb +10 -5
  209. data/test/unit/test_images.rb +17 -18
  210. data/test/unit/test_layouts.rb +18 -3
  211. data/test/unit/test_media.rb +74 -49
  212. data/test/unit/test_modifications.rb +43 -43
  213. data/test/unit/test_page.rb +7 -10
  214. data/test/unit/test_permissions.rb +3 -10
  215. data/test/unit/test_piece.rb +5 -6
  216. data/test/unit/test_plugins.rb +7 -14
  217. data/test/unit/test_prototypes.rb +3 -3
  218. data/test/unit/test_publishing.rb +49 -27
  219. data/test/unit/test_render.rb +46 -15
  220. data/test/unit/test_revisions.rb +124 -127
  221. data/test/unit/test_schema.rb +53 -58
  222. data/test/unit/test_search.rb +64 -16
  223. data/test/unit/test_serialisation.rb +4 -11
  224. data/test/unit/test_site.rb +11 -12
  225. data/test/unit/test_structure.rb +2 -5
  226. data/test/unit/test_styles.rb +22 -24
  227. data/test/unit/test_type_hierarchy.rb +7 -5
  228. data/test/unit/test_visibility.rb +79 -55
  229. metadata +128 -102
  230. data/lib/sequel/plugins/content_table_inheritance.rb +0 -203
  231. data/lib/sequel/plugins/scoped_table_name.rb +0 -54
  232. data/lib/spontaneous/content.rb +0 -129
  233. data/lib/spontaneous/field_types/date_field.rb +0 -56
  234. data/lib/spontaneous/field_types/field.rb +0 -302
  235. data/lib/spontaneous/field_types/file_field.rb +0 -68
  236. data/lib/spontaneous/field_types/markdown_field.rb +0 -38
  237. data/lib/spontaneous/field_types/string_field.rb +0 -19
  238. data/lib/spontaneous/field_types/webvideo_field.rb +0 -313
  239. data/lib/spontaneous/field_types.rb +0 -38
  240. data/lib/spontaneous/generators/site/lib/site.rb.tt +0 -4
  241. data/lib/spontaneous/plugins/field/editor_class.rb +0 -13
  242. data/lib/spontaneous/plugins/page/site_timestamps.rb +0 -28
  243. data/lib/spontaneous/plugins/page_search.rb +0 -63
  244. data/lib/spontaneous/plugins/schema_id.rb +0 -68
  245. data/lib/spontaneous/plugins/site/publishing.rb +0 -75
  246. data/lib/spontaneous/rack/fiber_pool.rb +0 -26
  247. data/test/unit/test_table_scoping.rb +0 -80
@@ -0,0 +1,143 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Model
4
+ module Core
5
+ autoload :Aliases, "spontaneous/model/core/aliases"
6
+ autoload :Boxes, "spontaneous/model/core/boxes"
7
+ autoload :ContentGroups, "spontaneous/model/core/content_groups"
8
+ autoload :EditorClass, "spontaneous/model/core/editor_class"
9
+ autoload :Entries, "spontaneous/model/core/entries"
10
+ autoload :Entry, "spontaneous/model/core/entry"
11
+ autoload :Fields, "spontaneous/model/core/fields"
12
+ autoload :InstanceCode, "spontaneous/model/core/instance_code"
13
+ autoload :Media, "spontaneous/model/core/media"
14
+ autoload :Modifications, "spontaneous/model/core/modifications"
15
+ autoload :PageSearch, "spontaneous/model/core/page_search"
16
+ autoload :Permissions, "spontaneous/model/core/permissions"
17
+ autoload :Prototypes, "spontaneous/model/core/prototypes"
18
+ autoload :Publishing, "spontaneous/model/core/publishing"
19
+ autoload :Render, "spontaneous/model/core/render"
20
+ autoload :SchemaHierarchy, "spontaneous/model/core/schema_hierarchy"
21
+ autoload :SchemaId, "spontaneous/model/core/schema_id"
22
+ autoload :SchemaTitle, "spontaneous/model/core/schema_title"
23
+ autoload :Serialisation, "spontaneous/model/core/serialisation"
24
+ autoload :Styles, "spontaneous/model/core/styles"
25
+ autoload :Supertype, "spontaneous/model/core/supertype"
26
+ autoload :Visibility, "spontaneous/model/core/visibility"
27
+
28
+ extend Spontaneous::Concern
29
+
30
+ module ClassMethods
31
+ def page?
32
+ false
33
+ end
34
+
35
+ def is_page?
36
+ page?
37
+ end
38
+
39
+ # terminate the supertype chain here
40
+ def supertype
41
+ nil
42
+ end
43
+
44
+ def supertype?
45
+ !supertype.nil?
46
+ end
47
+
48
+ def root
49
+ content_model::Page.root
50
+ end
51
+
52
+ def log_sql(io = $stdout)
53
+ mapper.logger = ::Logger.new(io)
54
+ yield if block_given?
55
+ ensure
56
+ mapper.logger = nil
57
+ end
58
+ end
59
+
60
+ include Enumerable
61
+
62
+ include SchemaId
63
+ include Entry
64
+ include Boxes
65
+ include Fields
66
+ include Entries
67
+ include Styles
68
+ include SchemaTitle
69
+ include Render
70
+ include InstanceCode
71
+ include Serialisation
72
+ include Media
73
+ include Publishing
74
+ include Modifications
75
+ include Aliases
76
+ include Visibility
77
+ include Prototypes
78
+ include Permissions
79
+ include ContentGroups
80
+ include SchemaHierarchy
81
+ include PageSearch
82
+
83
+ # marker method enabling a simple test for "cms content" vs "everything else"
84
+ def spontaneous_content?
85
+ true
86
+ end
87
+
88
+ def alias?
89
+ false
90
+ end
91
+
92
+ def root
93
+ content_model::Page.root
94
+ end
95
+
96
+ def content_instance
97
+ self
98
+ end
99
+
100
+ # Provides consistency between aliases & non-aliases
101
+ # so that a mixed list of both can be treated the same
102
+ # (for instance when ensuring uniqueness)
103
+ def target
104
+ self
105
+ end
106
+
107
+ def page?
108
+ false
109
+ end
110
+
111
+ alias_method :is_page?, :page?
112
+
113
+ def start_inline_edit_marker
114
+ "spontaneous:previewedit:start:content id:#{id}"
115
+ end
116
+
117
+ def end_inline_edit_marker
118
+ "spontaneous:previewedit:end:content id:#{id}"
119
+ end
120
+
121
+ def to_s
122
+ %(#<#{self.class.name} id=#{id}>)
123
+ end
124
+
125
+ def each
126
+ iterable.each do |i|
127
+ yield i if block_given?
128
+ end
129
+ end
130
+
131
+ def formats
132
+ return page.formats if page
133
+ [:html]
134
+ end
135
+
136
+ def log_sql(io = $stdout)
137
+ mapper.logger = ::Logger.new(io)
138
+ yield if block_given?
139
+ ensure
140
+ mapper.logger = nil
141
+ end
142
+ end
143
+ end
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Spontaneous::Plugins
3
+ module Spontaneous::Model::Page
4
4
  module Controllers
5
- extend ActiveSupport::Concern
5
+ extend Spontaneous::Concern
6
6
 
7
7
  ACTION_SEPARATOR = "@".freeze
8
8
 
@@ -17,7 +17,7 @@ module Spontaneous::Plugins
17
17
  end
18
18
 
19
19
  def default_controller_base_class
20
- Spontaneous::PageController
20
+ Spontaneous::Rack::PageController
21
21
  end
22
22
 
23
23
  def controller(namespace, base_class = controller_base_class, &block)
@@ -2,9 +2,9 @@
2
2
 
3
3
  require 'rack'
4
4
 
5
- module Spontaneous::Plugins::Page
5
+ module Spontaneous::Model::Page
6
6
  module Formats
7
- extend ActiveSupport::Concern
7
+ extend Spontaneous::Concern
8
8
 
9
9
  module ClassMethods
10
10
  def outputs(*outputs)
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Spontaneous::Plugins
3
+ module Spontaneous::Model::Page
4
4
  module Layouts
5
- extend ActiveSupport::Concern
5
+ extend Spontaneous::Concern
6
6
 
7
7
  module ClassMethods
8
8
  def layout(name = nil, options = {}, &block)
@@ -0,0 +1,14 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Model::Page
4
+ module Locks
5
+ extend Spontaneous::Concern
6
+
7
+ included do
8
+ one_to_many :update_locks, :model => Spontaneous::PageLock, :key => :page_id
9
+ end
10
+ def locked_for_update?
11
+ !update_locks.empty?
12
+ end
13
+ end
14
+ end
@@ -1,13 +1,13 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Spontaneous::Plugins
3
+ module Spontaneous::Model::Page
4
4
  module PageTree
5
- extend ActiveSupport::Concern
5
+ extend Spontaneous::Concern
6
6
 
7
7
  # InstanceMethods
8
8
 
9
9
  def ancestors
10
- @ancestors ||= ancestor_path.map { |id| Spontaneous::Content[id] }
10
+ @ancestors ||= ancestor_path.map { |id| content_model[id] }
11
11
  end
12
12
 
13
13
  def ancestor(depth)
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Spontaneous::Plugins
3
+ module Spontaneous::Model::Page
4
4
  module Paths
5
- extend ActiveSupport::Concern
5
+ extend Spontaneous::Concern
6
6
 
7
7
  module ClassMethods
8
8
  def generate_default_slug
@@ -28,17 +28,39 @@ module Spontaneous::Plugins
28
28
  super
29
29
  end
30
30
 
31
+ # Test for title changes and update the slug to match if it hasn't already
32
+ # been set.
33
+ #
34
+ # This doesn't happen when the item is created (i.e. #new? => true)
35
+ # because otherwise the slug would always take on the title fields
36
+ # default value.
31
37
  def before_save
32
38
  unless new?
33
- if title = self.fields[:title]
34
- if title.modified? and !title.blank? and self.class.is_default_slug?(slug)
35
- self.slug = title.value
36
- end
39
+ if (title = self.fields[title_field])
40
+ set_slug_from_title(title)
37
41
  end
38
42
  end
39
43
  super
40
44
  end
41
45
 
46
+ # Syncing the slug with the title is made more difficult because the field
47
+ # update mechanism works differently from the more direct, console version.
48
+ # This is called by the field updater before re-serializing each modified field.
49
+ def before_save_field(field)
50
+ set_slug_from_title(field) if (field.name == title_field)
51
+ super
52
+ end
53
+
54
+ def set_slug_from_title(title)
55
+ if title.modified? and !title.blank? and has_generated_slug?
56
+ self.slug = title.value
57
+ end
58
+ end
59
+
60
+ def has_generated_slug?
61
+ self.class.is_default_slug?(slug)
62
+ end
63
+
42
64
  def after_save
43
65
  super
44
66
  check_for_path_changes
@@ -56,9 +78,7 @@ module Spontaneous::Plugins
56
78
 
57
79
  def place_in_page_tree
58
80
  if self.parent_id.nil?
59
- if Spontaneous::Page.root.nil?
60
- make_root
61
- end
81
+ make_root unless content_model.has_root?
62
82
  else
63
83
  update_path
64
84
  end
@@ -77,11 +97,9 @@ module Spontaneous::Plugins
77
97
  def root?
78
98
  path == Spontaneous::SLASH
79
99
  end
100
+
80
101
  alias_method :is_root?, :root?
81
102
 
82
- def root
83
- Spontaneous::Page.root
84
- end
85
103
 
86
104
  def update_path
87
105
  self.path = calculate_path
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Spontaneous::Plugins::Page
3
+ module Spontaneous::Model::Page
4
4
  module Request
5
- extend ActiveSupport::Concern
5
+ extend Spontaneous::Concern
6
6
 
7
7
  # liked this but it didn't work particularly well so wasn't used in the end
8
8
  # perhaps, when I re-write the bloody Public handler i can use it
@@ -1,8 +1,8 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Spontaneous::Plugins
3
+ module Spontaneous::Model::Page
4
4
  module SiteMap
5
- extend ActiveSupport::Concern
5
+ extend Spontaneous::Concern
6
6
 
7
7
  # InstanceMethods
8
8
  def map_children
@@ -0,0 +1,44 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Model::Page
4
+ # Various scenarios where we need to Update the Site's modification
5
+ # time to force clients to reload their map data
6
+ module SiteTimestamps
7
+ extend Spontaneous::Concern
8
+
9
+ def before_save_field(field)
10
+ mark_site_modified if ((field.name == title_field) && field.modified?)
11
+ super
12
+ end
13
+
14
+ # The UI map uses the slugs for the pulldown values so changes to the
15
+ # slug must force a reload or things get very odd.
16
+ def before_update
17
+ mark_site_modified if changed_columns.include?(:slug)
18
+ super
19
+ end
20
+
21
+ def after_update
22
+ mark_site_modified if field?(title_field) && fields[title_field].modified?
23
+ super
24
+ end
25
+
26
+ def after_create
27
+ mark_site_modified
28
+ super
29
+ end
30
+
31
+ # Update the Site's modification time to force clients
32
+ # to reload their map data
33
+ def after_destroy
34
+ mark_site_modified
35
+ super
36
+ end
37
+
38
+ protected
39
+
40
+ def mark_site_modified
41
+ ::Spontaneous::State.site_modified!
42
+ end
43
+ end
44
+ end
@@ -1,36 +1,50 @@
1
1
  # encoding: UTF-8
2
2
 
3
- module Spontaneous
4
- class Page < Content
5
- include Plugins::Supertype
6
- include Plugins::Page::Formats
7
- include Plugins::Layouts
8
- include Plugins::Paths
9
- include Plugins::PageTree
10
- include Plugins::SiteMap
11
- include Plugins::PageSearch
12
- include Plugins::Controllers
13
- include Plugins::Page::Request
14
- include Plugins::Page::SiteTimestamps
15
-
16
- many_to_one :parent, :class => Content, :reciprocal => :children
17
- one_to_many :children, :class => Content, :key => :parent_id, :reciprocal => :parent
18
- one_to_many :content, :class => Content, :key => :page_id, :reciprocal => :page
3
+ require "spontaneous/model/page/controllers"
4
+ require "spontaneous/model/page/formats"
5
+ require "spontaneous/model/page/layouts"
6
+ require "spontaneous/model/page/locks"
7
+ require "spontaneous/model/page/page_tree"
8
+ require "spontaneous/model/page/paths"
9
+ require "spontaneous/model/page/request"
10
+ require "spontaneous/model/page/site_map"
11
+ require "spontaneous/model/page/site_timestamps"
12
+
13
+ module Spontaneous::Model
14
+ module Page
15
+ extend Spontaneous::Concern
16
+
17
+ include Spontaneous::Model::Core::Supertype
18
+ include Controllers
19
+ include Formats
20
+ include Layouts
21
+ include PageTree
22
+ include Paths
23
+ include Request
24
+ include SiteMap
25
+ include SiteTimestamps
26
+ include Locks
27
+
28
+ included do
29
+ many_to_one :parent, :model => self, :key => :parent_id, :reciprocal => :unordered_children
30
+ one_to_many :unordered_children, :model => self, :key => :parent_id, :reciprocal => :parent
31
+ one_to_many :content, :model => self, :key => :page_id, :reciprocal => :page
32
+ end
19
33
 
20
34
  # field :title, :string, :default => "New Page"
21
35
 
22
- set_inheritance_root
23
-
24
- def self.page?
25
- true
26
- end
36
+ module ClassMethods
37
+ def page?
38
+ true
39
+ end
27
40
 
28
- def self.export(user = nil)
29
- super(user).merge(:title_field => self.title_field.to_s)
30
- end
41
+ def export(user = nil)
42
+ super(user).merge(:title_field => self.title_field.to_s)
43
+ end
31
44
 
32
- def self.title_field
33
- :title
45
+ def title_field
46
+ :title
47
+ end
34
48
  end
35
49
 
36
50
  def page?
@@ -39,10 +53,17 @@ module Spontaneous
39
53
 
40
54
  alias_method :is_page?, :page?
41
55
 
42
- alias_method :unordered_children, :children
56
+ def parent
57
+ # Test for the common case where a page's owner is also its parent
58
+ if (owner_id == parent_id)
59
+ owner
60
+ else
61
+ super
62
+ end
63
+ end
43
64
 
44
65
  def children
45
- @ordered_children ||= generate_ordered_children(super)
66
+ @ordered_children ||= generate_ordered_children(unordered_children)
46
67
  end
47
68
 
48
69
  def generate_ordered_children(unordered_children)
@@ -1,18 +1,19 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ module Spontaneous::Model
4
+ module Piece
5
+ extend Spontaneous::Concern
3
6
 
4
- module Spontaneous
5
- class Piece < Content
6
- include Plugins::Supertype
7
+ include Spontaneous::Model::Core::Supertype
7
8
 
8
9
  # Public: for Pieces #parent is the same as the #owner
9
10
  # whereas for pages, parent is the next page up in the
10
11
  # page hierarchy.
11
12
  #
12
13
  # Returns: Content node one up in the page hierarchy
13
- alias_method :parent, :owner
14
-
15
- set_inheritance_root
14
+ def parent
15
+ owner
16
+ end
16
17
 
17
18
  def export(user = nil)
18
19
  super(user).merge(export_styles)
@@ -0,0 +1,97 @@
1
+ module Spontaneous
2
+
3
+ module Model
4
+ autoload :Core, "spontaneous/model/core"
5
+ autoload :Page, "spontaneous/model/page"
6
+ autoload :Piece, "spontaneous/model/piece"
7
+ autoload :Box, "spontaneous/model/box"
8
+ end
9
+
10
+ def self.models
11
+ @models ||= {}
12
+ end
13
+
14
+ def self.Model(table_name, database = Spontaneous.database, schema = Site.schema)
15
+ define_content_model(table_name, database, schema)
16
+ end
17
+
18
+ def self.define_content_model(table_name, database = Spontaneous.database, schema = Site.schema)
19
+ model = Spontaneous::DataMapper::Model(table_name, database, schema) do
20
+ serialize_columns :field_store, :entry_store, :box_store, :serialized_modifications
21
+ include_all_types
22
+ end
23
+ model.class_eval do
24
+ many_to_one :owner, :key => :owner_id, :model => self, :reciprocal => :_pieces
25
+ one_to_many :_pieces, :key => :owner_id, :model => self, :reciprocal => :owner
26
+ many_to_one :page, :key => :page_id, :model => self, :reciprocal => :content
27
+ many_to_one :created_by, :key => :created_by_id, :model => Spontaneous::Permissions::User
28
+ # '__target' rather than 'target' because we want to override the behaviour of the
29
+ # Content#target method only on classes that are aliases, and this is defined dynamically
30
+ many_to_one :__target, :key => :target_id, :model => self, :reciprocal => :aliases
31
+ one_to_many :aliases, :key => :target_id, :model => self, :reciprocal => :__target, :dependent => :destroy
32
+ end
33
+ model.send :extend, ContentModelClassMethods
34
+ model.send :include, ContentModelInstanceMethods
35
+ model
36
+ end
37
+
38
+ module ContentModelClassMethods
39
+ # Can't just use the @@ syntax here because it gets scoped to the
40
+ # enclosing module rather than the generated class...
41
+ def content_model
42
+ class_variable_get(:@@content_model)
43
+ end
44
+
45
+ # This is fiddly because we want the Content.content_model to refer to the
46
+ # first subclass of the Spontaneous::Content call as that is going to be our
47
+ # ::Content model. In this particular instance I want the behaviour of Ruby's
48
+ # class variables -- I want a single value to be shared across all subclasses
49
+ # Use this moment to include the core functionality because this is the first
50
+ # access to the subclass derived from the base model.
51
+ def inherited(subclass)
52
+ unless class_variable_defined?(:@@content_model)
53
+ class_variable_set(:@@content_model, subclass)
54
+ subclass.send :include, Spontaneous::Model::Core
55
+ end
56
+ super
57
+ end
58
+
59
+ def const_missing(name)
60
+ # Only the top-level content model has the auto generated
61
+ # Page & Piece models
62
+ return super unless content_model == self
63
+ case name
64
+ when :Page, :Piece
65
+ klass = Class.new(self) do
66
+ include_types { subclasses }
67
+ def self.inherited(subclass, real_caller = nil)
68
+ __determine_source_file(subclass, real_caller || caller[0])
69
+ subclass.include_types { [self] }
70
+ super
71
+ end
72
+ end
73
+ klass.send :include, ::Spontaneous::Model.const_get(name)
74
+ const_set(name, klass)
75
+ klass
76
+ when :Box
77
+ klass = Class.new(Spontaneous::Box)
78
+ klass.send :include, ::Spontaneous::Model.const_get(name)
79
+ klass.instance_variable_set(:"@mapper", mapper)
80
+ const_set(name, klass)
81
+ klass
82
+ else
83
+ super
84
+ end
85
+ end
86
+
87
+ def pages
88
+ content_model::Page.all
89
+ end
90
+ end
91
+
92
+ module ContentModelInstanceMethods
93
+ def content_model
94
+ model.content_model
95
+ end
96
+ end
97
+ end
@@ -68,7 +68,7 @@ module Spontaneous::Output::Context
68
68
  def render_content
69
69
  __target.map do |c|
70
70
  __render_content(c)
71
- end.join("\n")
71
+ end.reject(&:blank?).join("\n")
72
72
  end
73
73
 
74
74
  def first
@@ -117,6 +117,10 @@ module Spontaneous::Output
117
117
  @content ||= page
118
118
  end
119
119
 
120
+ def model
121
+ content.model
122
+ end
123
+
120
124
  def render(params = {}, *args)
121
125
  render_using(default_renderer, params, *args)
122
126
  end
@@ -17,13 +17,13 @@ module Spontaneous::Output::Template
17
17
  end
18
18
 
19
19
  def render(output, params = {})
20
- Spontaneous::Content.with_visible do
20
+ output.model.with_visible do
21
21
  engine.render(output.content, context(output, params), output.name.to_s)
22
22
  end
23
23
  end
24
24
 
25
25
  def render_string(template_string, output, params = {})
26
- Spontaneous::Content.with_visible do
26
+ output.model.with_visible do
27
27
  engine.render_string(template_string, context(output, params), output.name.to_s)
28
28
  end
29
29
  end
@@ -76,11 +76,11 @@ module Spontaneous
76
76
 
77
77
  # TODO: Is this ever used? Delete it & see what breaks
78
78
  def self.revision_dir(revision=nil, root = nil)
79
- Site.instance.revision_dir(revision, root)
79
+ Spontaneous::Site.instance.revision_dir(revision, root)
80
80
  end
81
81
 
82
82
  def self.revision_root(revision)
83
- Site.instance.revision_dir(revision)
83
+ Spontaneous::Site.instance.revision_dir(revision)
84
84
  end
85
85
 
86
86
  def self.context_class