locomotivecms_steam 0.1.2.pre.beta → 1.0.0.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (355) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +8 -1
  4. data/Gemfile +17 -8
  5. data/Gemfile.lock +160 -113
  6. data/LICENSE +1 -1
  7. data/README.md +36 -15
  8. data/Rakefile +27 -1
  9. data/bin/steam.rb +97 -0
  10. data/config/locales/en.yml +2 -1
  11. data/config/locales/fr.yml +2 -1
  12. data/lib/locomotive/steam.rb +28 -19
  13. data/lib/locomotive/steam/adapters/concerns/key.rb +15 -0
  14. data/lib/locomotive/steam/adapters/filesystem.rb +124 -0
  15. data/lib/locomotive/steam/adapters/filesystem/sanitizer.rb +54 -0
  16. data/lib/locomotive/steam/adapters/filesystem/sanitizers/content_entry.rb +86 -0
  17. data/lib/locomotive/steam/adapters/filesystem/sanitizers/content_type.rb +21 -0
  18. data/lib/locomotive/steam/adapters/filesystem/sanitizers/page.rb +160 -0
  19. data/lib/locomotive/steam/adapters/filesystem/sanitizers/simple.rb +15 -0
  20. data/lib/locomotive/steam/adapters/filesystem/sanitizers/snippet.rb +33 -0
  21. data/lib/locomotive/steam/adapters/filesystem/simple_cache_store.rb +38 -0
  22. data/lib/locomotive/steam/adapters/filesystem/yaml_loader.rb +47 -0
  23. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_entry.rb +87 -0
  24. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_type.rb +96 -0
  25. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb +145 -0
  26. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/site.rb +25 -0
  27. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/snippet.rb +66 -0
  28. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/theme_asset.rb +21 -0
  29. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/translation.rb +72 -0
  30. data/lib/locomotive/steam/adapters/memory.rb +55 -0
  31. data/lib/locomotive/steam/adapters/memory/condition.rb +103 -0
  32. data/lib/locomotive/steam/adapters/memory/dataset.rb +77 -0
  33. data/lib/locomotive/steam/adapters/memory/order.rb +60 -0
  34. data/lib/locomotive/steam/adapters/memory/query.rb +116 -0
  35. data/lib/locomotive/steam/adapters/mongodb.rb +83 -0
  36. data/lib/locomotive/steam/adapters/mongodb/dataset.rb +20 -0
  37. data/lib/locomotive/steam/adapters/mongodb/origin.rb +3 -0
  38. data/lib/locomotive/steam/adapters/mongodb/query.rb +82 -0
  39. data/lib/locomotive/steam/configuration.rb +106 -2
  40. data/lib/locomotive/steam/core_ext.rb +2 -1
  41. data/lib/locomotive/steam/core_ext/hash.rb +31 -19
  42. data/lib/locomotive/steam/core_ext/kernel.rb +14 -0
  43. data/lib/locomotive/steam/core_ext/string.rb +35 -6
  44. data/lib/locomotive/steam/decorators/i18n_decorator.rb +99 -0
  45. data/lib/locomotive/steam/decorators/template_decorator.rb +37 -0
  46. data/lib/locomotive/steam/entities/content_entry.rb +151 -0
  47. data/lib/locomotive/steam/entities/content_type.rb +44 -6
  48. data/lib/locomotive/steam/entities/content_type_field.rb +71 -0
  49. data/lib/locomotive/steam/entities/editable_element.rb +21 -0
  50. data/lib/locomotive/steam/entities/page.rb +48 -127
  51. data/lib/locomotive/steam/entities/site.rb +36 -27
  52. data/lib/locomotive/steam/entities/snippet.rb +20 -0
  53. data/lib/locomotive/steam/entities/theme_asset.rb +9 -0
  54. data/lib/locomotive/steam/entities/translation.rb +15 -0
  55. data/lib/locomotive/steam/initializers.rb +0 -4
  56. data/lib/locomotive/steam/initializers/dragonfly.rb +51 -11
  57. data/lib/locomotive/steam/initializers/i18n.rb +6 -3
  58. data/lib/locomotive/steam/initializers/sprockets.rb +4 -1
  59. data/lib/locomotive/steam/liquid.rb +4 -7
  60. data/lib/locomotive/steam/liquid/drops/base.rb +0 -1
  61. data/lib/locomotive/steam/liquid/drops/content_entry.rb +37 -16
  62. data/lib/locomotive/steam/liquid/drops/content_entry_collection.rb +77 -0
  63. data/lib/locomotive/steam/liquid/drops/content_types.rb +5 -102
  64. data/lib/locomotive/steam/liquid/drops/current_user.rb +23 -0
  65. data/lib/locomotive/steam/liquid/drops/i18n_base.rb +39 -0
  66. data/lib/locomotive/steam/liquid/drops/page.rb +77 -11
  67. data/lib/locomotive/steam/liquid/drops/session_proxy.rb +1 -1
  68. data/lib/locomotive/steam/liquid/drops/site.rb +14 -8
  69. data/lib/locomotive/steam/liquid/drops/upload_file.rb +23 -0
  70. data/lib/locomotive/steam/liquid/errors.rb +3 -9
  71. data/lib/locomotive/steam/liquid/filters/base.rb +62 -0
  72. data/lib/locomotive/steam/liquid/filters/date.rb +85 -61
  73. data/lib/locomotive/steam/liquid/filters/html.rb +30 -115
  74. data/lib/locomotive/steam/liquid/filters/misc.rb +6 -5
  75. data/lib/locomotive/steam/liquid/filters/pagination.rb +55 -0
  76. data/lib/locomotive/steam/liquid/filters/resize.rb +2 -3
  77. data/lib/locomotive/steam/liquid/filters/text.rb +15 -15
  78. data/lib/locomotive/steam/liquid/filters/translate.rb +5 -14
  79. data/lib/locomotive/steam/liquid/patches.rb +29 -23
  80. data/lib/locomotive/steam/liquid/tags/concerns/i18n_page.rb +36 -0
  81. data/lib/locomotive/steam/liquid/tags/concerns/path.rb +114 -0
  82. data/lib/locomotive/steam/liquid/tags/consume.rb +39 -43
  83. data/lib/locomotive/steam/liquid/tags/csrf.rb +21 -12
  84. data/lib/locomotive/steam/liquid/tags/editable.rb +1 -3
  85. data/lib/locomotive/steam/liquid/tags/editable/base.rb +54 -15
  86. data/lib/locomotive/steam/liquid/tags/editable/control.rb +17 -4
  87. data/lib/locomotive/steam/liquid/tags/editable/file.rb +34 -2
  88. data/lib/locomotive/steam/liquid/tags/editable/text.rb +54 -2
  89. data/lib/locomotive/steam/liquid/tags/extends.rb +45 -8
  90. data/lib/locomotive/steam/liquid/tags/fetch_page.rb +38 -0
  91. data/lib/locomotive/steam/liquid/tags/google_analytics.rb +25 -12
  92. data/lib/locomotive/steam/liquid/tags/hybrid.rb +24 -12
  93. data/lib/locomotive/steam/liquid/tags/inherited_block.rb +39 -0
  94. data/lib/locomotive/steam/liquid/tags/inline_editor.rb +14 -4
  95. data/lib/locomotive/steam/liquid/tags/link_to.rb +16 -27
  96. data/lib/locomotive/steam/liquid/tags/locale_switcher.rb +45 -56
  97. data/lib/locomotive/steam/liquid/tags/model_form.rb +72 -0
  98. data/lib/locomotive/steam/liquid/tags/nav.rb +65 -57
  99. data/lib/locomotive/steam/liquid/tags/paginate.rb +79 -47
  100. data/lib/locomotive/steam/liquid/tags/path_to.rb +8 -20
  101. data/lib/locomotive/steam/liquid/tags/seo.rb +8 -8
  102. data/lib/locomotive/steam/liquid/tags/session_assign.rb +6 -8
  103. data/lib/locomotive/steam/liquid/tags/snippet.rb +26 -42
  104. data/lib/locomotive/steam/liquid/tags/with_scope.rb +44 -26
  105. data/lib/locomotive/steam/middlewares.rb +7 -13
  106. data/lib/locomotive/steam/middlewares/default_env.rb +25 -0
  107. data/lib/locomotive/steam/middlewares/dynamic_assets.rb +34 -17
  108. data/lib/locomotive/steam/middlewares/entry_submission.rb +117 -79
  109. data/lib/locomotive/steam/middlewares/favicon.rb +5 -2
  110. data/lib/locomotive/steam/middlewares/helpers.rb +44 -0
  111. data/lib/locomotive/steam/middlewares/locale.rb +25 -17
  112. data/lib/locomotive/steam/middlewares/locale_redirection.rb +62 -0
  113. data/lib/locomotive/steam/middlewares/logging.rb +7 -3
  114. data/lib/locomotive/steam/middlewares/page.rb +17 -48
  115. data/lib/locomotive/steam/middlewares/path.rb +5 -8
  116. data/lib/locomotive/steam/middlewares/renderer.rb +65 -106
  117. data/lib/locomotive/steam/middlewares/robots.rb +20 -0
  118. data/lib/locomotive/steam/middlewares/site.rb +42 -0
  119. data/lib/locomotive/steam/middlewares/sitemap.rb +94 -0
  120. data/lib/locomotive/steam/middlewares/stack_proxy.rb +46 -0
  121. data/lib/locomotive/steam/middlewares/templatized_page.rb +40 -14
  122. data/lib/locomotive/steam/middlewares/threadsafe.rb +65 -0
  123. data/lib/locomotive/steam/middlewares/timezone.rb +10 -6
  124. data/lib/locomotive/steam/models.rb +12 -0
  125. data/lib/locomotive/steam/models/associations/belongs_to.rb +18 -0
  126. data/lib/locomotive/steam/models/associations/embedded.rb +43 -0
  127. data/lib/locomotive/steam/models/associations/has_many.rb +22 -0
  128. data/lib/locomotive/steam/models/associations/many_to_many.rb +22 -0
  129. data/lib/locomotive/steam/models/associations/referenced.rb +48 -0
  130. data/lib/locomotive/steam/models/concerns/validation.rb +58 -0
  131. data/lib/locomotive/steam/models/entity.rb +40 -0
  132. data/lib/locomotive/steam/models/i18n_field.rb +42 -0
  133. data/lib/locomotive/steam/models/mapper.rb +119 -0
  134. data/lib/locomotive/steam/models/pager.rb +53 -0
  135. data/lib/locomotive/steam/models/repository.rb +101 -0
  136. data/lib/locomotive/steam/models/scope.rb +31 -0
  137. data/lib/locomotive/steam/repositories.rb +51 -0
  138. data/lib/locomotive/steam/repositories/content_entry_repository.rb +183 -0
  139. data/lib/locomotive/steam/repositories/content_type_field_repository.rb +50 -0
  140. data/lib/locomotive/steam/repositories/content_type_field_select_option_repository.rb +23 -0
  141. data/lib/locomotive/steam/repositories/content_type_repository.rb +38 -0
  142. data/lib/locomotive/steam/repositories/editable_element_repository.rb +20 -0
  143. data/lib/locomotive/steam/repositories/page_repository.rb +86 -0
  144. data/lib/locomotive/steam/repositories/site_repository.rb +29 -0
  145. data/lib/locomotive/steam/repositories/snippet_repository.rb +19 -0
  146. data/lib/locomotive/steam/repositories/theme_asset_repository.rb +24 -0
  147. data/lib/locomotive/steam/repositories/translation_repository.rb +17 -0
  148. data/lib/locomotive/steam/server.rb +61 -40
  149. data/lib/locomotive/steam/services.rb +120 -1
  150. data/lib/locomotive/steam/services/asset_host_service.rb +51 -0
  151. data/lib/locomotive/steam/services/concerns/decorator.rb +35 -0
  152. data/lib/locomotive/steam/services/csrf_protection_service.rb +13 -0
  153. data/lib/locomotive/steam/services/editable_element_service.rb +19 -0
  154. data/lib/locomotive/steam/services/entry_submission_service.rb +91 -0
  155. data/lib/locomotive/steam/services/external_api_service.rb +55 -0
  156. data/lib/locomotive/steam/services/image_resizer_service.rb +49 -0
  157. data/lib/locomotive/steam/services/liquid_parser_service.rb +23 -0
  158. data/lib/locomotive/steam/services/markdown_service.rb +17 -0
  159. data/lib/locomotive/steam/services/no_cache_service.rb +17 -0
  160. data/lib/locomotive/steam/services/page_finder_service.rb +44 -0
  161. data/lib/locomotive/steam/services/parent_finder_service.rb +23 -0
  162. data/lib/locomotive/steam/services/site_finder_service.rb +13 -0
  163. data/lib/locomotive/steam/services/snippet_finder_service.rb +17 -0
  164. data/lib/locomotive/steam/services/textile_service.rb +17 -0
  165. data/lib/locomotive/steam/services/theme_asset_url_service.rb +43 -0
  166. data/lib/locomotive/steam/services/translator_service.rb +34 -0
  167. data/lib/locomotive/steam/services/url_builder_service.rb +40 -0
  168. data/lib/locomotive/steam/version.rb +1 -1
  169. data/locomotivecms_steam.gemspec +34 -28
  170. data/script/ci/before_build.sh +4 -0
  171. data/spec/fixtures/default/app/content_types/bands.yml +3 -1
  172. data/spec/fixtures/default/app/content_types/events.yml +2 -2
  173. data/spec/fixtures/default/app/views/pages/about_us.liquid.haml +2 -1
  174. data/spec/fixtures/default/app/views/pages/archives.liquid.haml +6 -0
  175. data/spec/fixtures/default/app/views/pages/basic.liquid.haml +1 -0
  176. data/spec/fixtures/default/app/views/pages/contest.liquid.haml +2 -1
  177. data/spec/fixtures/default/app/views/pages/events.fr.liquid +4 -0
  178. data/spec/fixtures/default/app/views/pages/events.liquid.haml +23 -1
  179. data/spec/fixtures/default/app/views/pages/filtered.liquid.haml +16 -5
  180. data/spec/fixtures/default/app/views/pages/grunge_bands.liquid.haml +2 -1
  181. data/spec/fixtures/default/app/views/pages/index.liquid.haml +12 -11
  182. data/spec/fixtures/default/app/views/pages/music.liquid.haml +1 -1
  183. data/spec/fixtures/default/app/views/pages/songs.liquid +6 -0
  184. data/spec/fixtures/default/app/views/pages/songs/song-number-1.liquid.haml +5 -0
  185. data/spec/fixtures/default/app/views/pages/store.liquid +2 -1
  186. data/spec/fixtures/default/app/views/pages/tags.liquid +6 -0
  187. data/spec/fixtures/default/app/views/pages/unlisted_pages.liquid.haml +2 -1
  188. data/spec/fixtures/default/app/views/snippets/song.fr.liquid.haml +1 -1
  189. data/spec/fixtures/default/config/deploy.yml +2 -2
  190. data/spec/fixtures/default/config/site.yml +7 -1
  191. data/spec/fixtures/default/data/bands.yml +3 -0
  192. data/spec/fixtures/mongodb/locomotive_accounts.bson +0 -0
  193. data/spec/fixtures/mongodb/locomotive_accounts.metadata.json +1 -0
  194. data/spec/fixtures/mongodb/locomotive_content_assets.bson +0 -0
  195. data/spec/fixtures/mongodb/locomotive_content_assets.metadata.json +1 -0
  196. data/spec/fixtures/mongodb/locomotive_content_entries.bson +0 -0
  197. data/spec/fixtures/mongodb/locomotive_content_entries.metadata.json +1 -0
  198. data/spec/fixtures/mongodb/locomotive_content_types.bson +0 -0
  199. data/spec/fixtures/mongodb/locomotive_content_types.metadata.json +1 -0
  200. data/spec/fixtures/mongodb/locomotive_pages.bson +0 -0
  201. data/spec/fixtures/mongodb/locomotive_pages.metadata.json +1 -0
  202. data/spec/fixtures/mongodb/locomotive_sites.bson +0 -0
  203. data/spec/fixtures/mongodb/locomotive_sites.metadata.json +1 -0
  204. data/spec/fixtures/mongodb/locomotive_snippets.bson +0 -0
  205. data/spec/fixtures/mongodb/locomotive_snippets.metadata.json +1 -0
  206. data/spec/fixtures/mongodb/locomotive_theme_assets.bson +0 -0
  207. data/spec/fixtures/mongodb/locomotive_theme_assets.metadata.json +1 -0
  208. data/spec/fixtures/mongodb/locomotive_translations.bson +0 -0
  209. data/spec/fixtures/mongodb/locomotive_translations.metadata.json +1 -0
  210. data/spec/fixtures/mongodb/sessions.bson +0 -0
  211. data/spec/fixtures/mongodb/sessions.metadata.json +1 -0
  212. data/spec/fixtures/mongodb/system.indexes.bson +0 -0
  213. data/spec/integration/integration_helper.rb +2 -2
  214. data/spec/integration/liquid/tags/paginate_spec.rb +79 -0
  215. data/spec/integration/repositories/content_entry_repository_spec.rb +94 -0
  216. data/spec/integration/repositories/content_type_repository_spec.rb +69 -0
  217. data/spec/integration/repositories/page_repository_spec.rb +105 -0
  218. data/spec/integration/repositories/site_repository_spec.rb +45 -0
  219. data/spec/integration/repositories/snippet_repository_spec.rb +50 -0
  220. data/spec/integration/repositories/theme_asset_repository_spec.rb +48 -0
  221. data/spec/integration/repositories/translation_repository_spec.rb +50 -0
  222. data/spec/integration/server/assets_spec.rb +60 -0
  223. data/spec/integration/server/basic_spec.rb +100 -100
  224. data/spec/integration/server/contact_form_spec.rb +96 -25
  225. data/spec/integration/server/liquid_spec.rb +19 -41
  226. data/spec/integration/server/nav_spec.rb +49 -0
  227. data/spec/integration/server/session_spec.rb +33 -0
  228. data/spec/integration/server/sitemap_spec.rb +34 -0
  229. data/spec/integration/server/with_scope_spec.rb +28 -2
  230. data/spec/integration/services/external_api_service_spec.rb +20 -0
  231. data/spec/locales/locales_spec.rb +7 -7
  232. data/spec/spec_helper.rb +27 -13
  233. data/spec/support.rb +5 -1
  234. data/spec/support/cache_store.rb +3 -0
  235. data/spec/support/helpers.rb +20 -23
  236. data/spec/support/liquid.rb +29 -0
  237. data/spec/support/pry.rb +4 -0
  238. data/spec/support/time.rb +3 -0
  239. data/spec/unit/adapters/filesystem/yaml_loaders/content_entry_spec.rb +50 -0
  240. data/spec/unit/adapters/filesystem/yaml_loaders/content_type_spec.rb +25 -0
  241. data/spec/unit/adapters/filesystem/yaml_loaders/page_spec.rb +25 -0
  242. data/spec/unit/adapters/filesystem/yaml_loaders/site_spec.rb +19 -0
  243. data/spec/unit/adapters/filesystem/yaml_loaders/snippet_spec.rb +26 -0
  244. data/spec/unit/adapters/filesystem/yaml_loaders/translation_spec.rb +25 -0
  245. data/spec/unit/adapters/filesystem_adapter_spec.rb +53 -0
  246. data/spec/unit/adapters/memory/condition_spec.rb +125 -0
  247. data/spec/unit/adapters/memory/dataset_spec.rb +73 -0
  248. data/spec/unit/adapters/memory/order_spec.rb +67 -0
  249. data/spec/unit/adapters/memory/query_spec.rb +85 -0
  250. data/spec/unit/adapters/memory_adapter_spec.rb +36 -0
  251. data/spec/unit/adapters/mongodb/query_spec.rb +68 -0
  252. data/spec/unit/adapters/mongodb_adapter_spec.rb +17 -0
  253. data/spec/unit/configuration_spec.rb +29 -0
  254. data/spec/unit/core_ext/string_spec.rb +44 -0
  255. data/spec/unit/decorators/i18n_decorator_spec.rb +80 -0
  256. data/spec/unit/entities/content_entry_spec.rb +159 -0
  257. data/spec/unit/entities/content_type_field_spec.rb +67 -0
  258. data/spec/unit/entities/content_type_spec.rb +59 -0
  259. data/spec/unit/entities/page_spec.rb +40 -34
  260. data/spec/unit/entities/site_spec.rb +56 -5
  261. data/spec/unit/initializers/dragonfly_spec.rb +31 -0
  262. data/spec/unit/liquid/drops/content_entry_collection_spec.rb +81 -0
  263. data/spec/unit/liquid/drops/content_entry_spec.rb +99 -0
  264. data/spec/unit/liquid/drops/content_types_spec.rb +25 -0
  265. data/spec/unit/liquid/drops/current_user_spec.rb +45 -0
  266. data/spec/unit/liquid/drops/page_spec.rb +134 -0
  267. data/spec/unit/liquid/drops/session_proxy_spec.rb +13 -0
  268. data/spec/unit/liquid/drops/site_spec.rb +49 -0
  269. data/spec/unit/liquid/filters/date_spec.rb +160 -0
  270. data/spec/unit/liquid/filters/html_spec.rb +263 -0
  271. data/spec/unit/liquid/filters/misc_spec.rb +108 -0
  272. data/spec/unit/liquid/filters/pagination_spec.rb +42 -0
  273. data/spec/unit/liquid/filters/resize_spec.rb +36 -0
  274. data/spec/unit/liquid/filters/text_spec.rb +56 -0
  275. data/spec/unit/liquid/filters/translate_spec.rb +33 -0
  276. data/spec/unit/liquid/patches_spec.rb +50 -0
  277. data/spec/unit/liquid/tags/consume_spec.rb +87 -0
  278. data/spec/unit/liquid/tags/csrf_spec.rb +47 -0
  279. data/spec/unit/liquid/tags/editable/control_spec.rb +109 -0
  280. data/spec/unit/liquid/tags/editable/file_spec.rb +116 -0
  281. data/spec/unit/liquid/tags/editable/text_spec.rb +139 -0
  282. data/spec/unit/liquid/tags/extends_spec.rb +38 -0
  283. data/spec/unit/liquid/tags/fetch_page_spec.rb +39 -0
  284. data/spec/unit/liquid/tags/google_analytics_spec.rb +16 -0
  285. data/spec/unit/liquid/tags/inherited_block_spec.rb +33 -0
  286. data/spec/unit/liquid/tags/link_to_spec.rb +112 -0
  287. data/spec/unit/liquid/tags/locale_switcher_spec.rb +58 -0
  288. data/spec/unit/liquid/tags/model_form_spec.rb +35 -0
  289. data/spec/unit/liquid/tags/nav_spec.rb +184 -111
  290. data/spec/unit/liquid/tags/paginate_spec.rb +131 -0
  291. data/spec/unit/liquid/tags/path_to_spec.rb +100 -0
  292. data/spec/unit/liquid/tags/seo_spec.rb +85 -0
  293. data/spec/unit/liquid/tags/session_assign_spec.rb +51 -0
  294. data/spec/unit/liquid/tags/snippet_spec.rb +42 -0
  295. data/spec/unit/liquid/tags/with_scope_spec.rb +66 -0
  296. data/spec/unit/middlewares/dynamic_assets_spec.rb +25 -0
  297. data/spec/unit/middlewares/locale_redirection_spec.rb +105 -0
  298. data/spec/unit/middlewares/renderer_spec.rb +29 -0
  299. data/spec/unit/middlewares/stack_proxy_spec.rb +67 -0
  300. data/spec/unit/models/mapper_spec.rb +75 -0
  301. data/spec/unit/models/pager_spec.rb +82 -0
  302. data/spec/unit/models/repository_spec.rb +46 -0
  303. data/spec/unit/models/scope_spec.rb +27 -0
  304. data/spec/unit/repositories/content_entry_repository_spec.rb +347 -0
  305. data/spec/unit/repositories/content_type_repository_spec.rb +126 -0
  306. data/spec/unit/repositories/page_repository_spec.rb +365 -0
  307. data/spec/unit/repositories/site_repository_spec.rb +41 -0
  308. data/spec/unit/repositories/snippet_repository_spec.rb +37 -0
  309. data/spec/unit/repositories/theme_asset_repository_spec.rb +35 -0
  310. data/spec/unit/repositories/translation_repository_spec.rb +34 -0
  311. data/spec/unit/services/asset_host_service_spec.rb +79 -0
  312. data/spec/unit/services/entry_submission_service_spec.rb +143 -0
  313. data/spec/unit/services/external_api_service_spec.rb +80 -0
  314. data/spec/unit/services/image_resizer_service_spec.rb +75 -0
  315. data/spec/unit/services/markdown_service_spec.rb +36 -0
  316. data/spec/unit/services/parent_finder_service_spec.rb +41 -0
  317. data/spec/unit/services/textile_service_spec.rb +34 -0
  318. data/spec/unit/services/translator_service_spec.rb +65 -0
  319. data/spec/unit/services/url_builder_service_spec.rb +48 -0
  320. data/spec/unit/services_spec.rb +25 -0
  321. metadata +462 -119
  322. data/example/server.rb +0 -31
  323. data/lib/locomotive/steam/decorators.rb +0 -1
  324. data/lib/locomotive/steam/decorators/page_decorator.rb +0 -50
  325. data/lib/locomotive/steam/exceptions.rb +0 -62
  326. data/lib/locomotive/steam/liquid/scopeable.rb +0 -149
  327. data/lib/locomotive/steam/liquid/tags/editable/long_text.rb +0 -15
  328. data/lib/locomotive/steam/liquid/tags/editable/short_text.rb +0 -20
  329. data/lib/locomotive/steam/liquid/tags/path_helper.rb +0 -98
  330. data/lib/locomotive/steam/loaders/yml/pages_loader.rb +0 -193
  331. data/lib/locomotive/steam/loaders/yml/site_loader.rb +0 -49
  332. data/lib/locomotive/steam/loaders/yml/utils/localized_tree.rb +0 -33
  333. data/lib/locomotive/steam/loaders/yml/utils/yaml_front_matters_template.rb +0 -66
  334. data/lib/locomotive/steam/loaders/yml_loader.rb +0 -33
  335. data/lib/locomotive/steam/mapper.rb +0 -86
  336. data/lib/locomotive/steam/middlewares/base.rb +0 -65
  337. data/lib/locomotive/steam/middlewares/stack.rb +0 -66
  338. data/lib/locomotive/steam/middlewares/static_assets.rb +0 -25
  339. data/lib/locomotive/steam/monkey_patches.rb +0 -3
  340. data/lib/locomotive/steam/monkey_patches/haml.rb +0 -17
  341. data/lib/locomotive/steam/repositories/content_types_repository.rb +0 -14
  342. data/lib/locomotive/steam/repositories/pages_repository.rb +0 -23
  343. data/lib/locomotive/steam/repositories/sites_repository.rb +0 -16
  344. data/lib/locomotive/steam/services/dragonfly.rb +0 -49
  345. data/lib/locomotive/steam/services/external_api.rb +0 -47
  346. data/lib/locomotive/steam/services/markdown.rb +0 -20
  347. data/lib/locomotive/steam/standalone_server.rb +0 -30
  348. data/spec/unit/decorators/page_decorator_spec.rb +0 -55
  349. data/spec/unit/loaders/pages_loader_spec.rb +0 -42
  350. data/spec/unit/loaders/site_loader_spec.rb +0 -21
  351. data/spec/unit/loaders/utils/localized_tree_spec.rb +0 -33
  352. data/spec/unit/loaders/utils/yaml_front_matters_template_spec.rb +0 -39
  353. data/spec/unit/middlewares/base_spec.rb +0 -20
  354. data/spec/unit/middlewares/page_spec.rb +0 -51
  355. data/spec/unit/repositories/pages_spec.rb +0 -11
data/example/server.rb DELETED
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'bundler/setup'
5
-
6
- Bundler.require
7
-
8
- require 'thin'
9
- # require 'common'
10
- require 'locomotive/common'
11
-
12
- require_relative '../lib/locomotive/steam'
13
- require_relative '../lib/locomotive/steam/server'
14
- require_relative '../lib/locomotive/steam/initializers'
15
-
16
- path = ENV['SITE_PATH'] || File.join(File.expand_path(File.dirname(__FILE__)), '../spec/fixtures/default')
17
-
18
- # reader = Locomotive::Mounter::Reader::FileSystem.instance
19
- # reader.run!(path: path)
20
-
21
- datastore = Locomotive::Steam::FileSystemDatastore.new(path: path)
22
-
23
- app = Locomotive::Steam::Server.new(datastore, {
24
- serve_assets: true
25
- })
26
-
27
- server = Thin::Server.new('localhost', '3333', app)
28
- server.threaded = true
29
-
30
- Locomotive::Common::Logger.info 'Server started...'
31
- server.start
@@ -1 +0,0 @@
1
- require_relative 'decorators/page_decorator'
@@ -1,50 +0,0 @@
1
- module Locomotive
2
- module Steam
3
- module Decorators
4
- class PageDecorator < SimpleDelegator
5
-
6
- # Return the fullpath dasherized and with the "*" character
7
- # for the slug of templatized page.
8
- #
9
- # @return [ hash ] The safe full paths
10
- #
11
-
12
- def safe_fullpath
13
- if index_or_404?
14
- slug[current_locale]
15
- else
16
- base = parent.safe_fullpath
17
- _slug = if templatized? && !templatized_from_parent
18
- '*'
19
- else
20
- slug[current_locale]
21
- end
22
- (base == 'index' ? _slug : File.join(base, _slug)).dasherize
23
- end
24
- end
25
-
26
- def parent
27
- Locomotive::Steam::Decorators::PageDecorator.new(
28
- Locomotive::Decorators::I18nDecorator.new(
29
- __getobj__.parent, current_locale
30
- )
31
- )
32
- end
33
-
34
- # Return the Liquid template based on the raw_template property
35
- # of the page. If the template is HAML or SLIM, then a pre-rendering to Liquid is done.
36
- #
37
- # @return [ String ] The liquid template or nil if not template has been provided
38
- #
39
- def source(locale)
40
- @source ||= self.template[locale].source
41
- end
42
-
43
- def to_liquid
44
- ::Locomotive::Steam::Liquid::Drops::Page.new(self)
45
- end
46
-
47
- end
48
- end
49
- end
50
- end
@@ -1,62 +0,0 @@
1
- module Locomotive
2
- module Steam
3
-
4
- class DefaultException < ::Exception
5
-
6
- def initialize(message = nil, parent_exception = nil)
7
- self.log_backtrace(parent_exception) if parent_exception
8
-
9
- super(message)
10
- end
11
-
12
- protected
13
-
14
- def log_backtrace(parent_exception)
15
- full_error_message = "#{parent_exception.message}\n\t"
16
- full_error_message += parent_exception.backtrace.join("\n\t")
17
- full_error_message += "\n\n"
18
- Locomotive::Common::Logger.fatal full_error_message
19
- end
20
-
21
- end
22
-
23
- class RendererException < DefaultException
24
-
25
- attr_accessor :name, :template, :liquid_context
26
-
27
- def initialize(exception, name, template, liquid_context)
28
- self.name, self.template, self.liquid_context = name, template, liquid_context
29
-
30
- self.log_page_into_backtrace(exception)
31
-
32
- super(exception.message)
33
-
34
- self.set_backtrace(exception.backtrace)
35
- end
36
-
37
- def log_page_into_backtrace(exception)
38
- line = self.template.line_offset
39
- line += (exception.respond_to?(:line) ? exception.line || 0 : 0) + 1
40
-
41
- message = "#{self.template.filepath}:#{line}:in `#{self.name}'"
42
-
43
- Locomotive::Common::Logger.fatal "[ERROR] #{exception.message} - #{message}\n".red
44
-
45
- exception.backtrace.unshift message
46
- end
47
-
48
- end
49
-
50
- class MounterException < DefaultException
51
- end
52
-
53
- class GeneratorException < DefaultException
54
-
55
- def log_backtrace(parent_exception)
56
- # Logger not initialized at this step
57
- end
58
-
59
- end
60
-
61
- end
62
- end
@@ -1,149 +0,0 @@
1
- module Locomotive
2
- module Steam
3
- module Liquid
4
- module Scopeable
5
-
6
- def apply_scope(entries)
7
- if @context['with_scope'].blank?
8
- entries
9
- else
10
- # extract the conditions
11
- _conditions = @context['with_scope'].clone.delete_if { |k, _| %w(order_by per_page page).include?(k) }
12
-
13
- # build the chains of conditions
14
- conditions = _conditions.map { |name, value| Condition.new(name, value) }
15
-
16
- Locomotive::Common::Logger.info "[with_scope] conditions: #{conditions.map(&:to_s).join(', ')}"
17
-
18
- # get only the entries matching ALL the conditions
19
- _entries = entries.find_all do |content|
20
- accepted = true
21
-
22
- conditions.each do |_condition|
23
- unless _condition.matches?(content)
24
- accepted = false
25
- break # no to go further
26
- end
27
- end
28
-
29
- accepted
30
- end
31
-
32
- self._apply_scope_order(_entries, @context['with_scope']['order_by'])
33
- end
34
- end
35
-
36
- def _apply_scope_order(entries, order_by)
37
- return entries if order_by.blank?
38
-
39
- name, direction = order_by.split.map(&:to_sym)
40
-
41
- Locomotive::Common::Logger.info "[with_scope] order_by #{name} #{direction || 'asc'}"
42
-
43
- if direction == :asc || direction.nil?
44
- entries.sort { |a, b| a.send(name) <=> b.send(name) }
45
- else
46
- entries.sort { |a, b| b.send(name) <=> a.send(name) }
47
- end
48
- end
49
-
50
- class Condition
51
-
52
- OPERATORS = %w(all gt gte in lt lte ne nin size)
53
-
54
- attr_accessor :name, :operator, :right_operand
55
-
56
- def initialize(name, value)
57
- self.name, self.right_operand = name, value
58
-
59
- self.process_right_operand
60
-
61
- # default value
62
- self.operator = :==
63
-
64
- self.decode_operator_based_on_name
65
- end
66
-
67
- def matches?(entry)
68
- value = self.get_value(entry)
69
-
70
- self.decode_operator_based_on_value(value)
71
-
72
- case self.operator
73
- when :== then value == self.right_operand
74
- when :ne then value != self.right_operand
75
- when :matches then self.right_operand =~ value
76
- when :gt then value > self.right_operand
77
- when :gte then value >= self.right_operand
78
- when :lt then value < self.right_operand
79
- when :lte then value <= self.right_operand
80
- when :size then value.size == self.right_operand
81
- when :all then [*self.right_operand].contains?(value)
82
- when :in, :nin
83
- _matches = if value.is_a?(Array)
84
- [*value].contains?([*self.right_operand])
85
- else
86
- [*self.right_operand].include?(value)
87
- end
88
- self.operator == :in ? _matches : !_matches
89
- else
90
- raise UnknownConditionInScope.new("#{self.operator} is unknown or not implemented.")
91
- end
92
- end
93
-
94
- def to_s
95
- "#{name} #{operator} #{self.right_operand.to_s}"
96
- end
97
-
98
- protected
99
-
100
- def get_value(entry)
101
- value = entry.send(self.name)
102
-
103
- if value.respond_to?(:_slug)
104
- # belongs_to
105
- value._slug
106
- elsif value.respond_to?(:map)
107
- # many_to_many or tags ?
108
- value.map { |v| v.respond_to?(:_slug) ? v._slug : v }
109
- else
110
- value
111
- end
112
- end
113
-
114
- def process_right_operand
115
- if self.right_operand.respond_to?(:_slug)
116
- # belongs_to
117
- self.right_operand = self.right_operand._slug
118
- elsif self.right_operand.respond_to?(:map) && self.right_operand.first.respond_to?(:_slug)
119
- # many_to_many
120
- self.right_operand = self.right_operand.map do |entry|
121
- entry.try(&:_slug)
122
- end
123
- end
124
- end
125
-
126
- def decode_operator_based_on_name
127
- if name =~ /^([a-z0-9_-]+)\.(#{OPERATORS.join('|')})$/
128
- self.name = $1.to_sym
129
- self.operator = $2.to_sym
130
- end
131
-
132
- if self.right_operand.is_a?(Regexp)
133
- self.operator = :matches
134
- end
135
- end
136
-
137
- def decode_operator_based_on_value(value)
138
- case value
139
- when Array
140
- self.operator = :in if self.operator == :==
141
- end
142
- end
143
-
144
- end
145
-
146
- end
147
- end
148
- end
149
- end
@@ -1,15 +0,0 @@
1
- module Locomotive
2
- module Steam
3
- module Liquid
4
- module Tags
5
- module Editable
6
- class LongText < ShortText
7
-
8
- end
9
-
10
- ::Liquid::Template.register_tag('editable_long_text', LongText)
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,20 +0,0 @@
1
- module Locomotive
2
- module Steam
3
- module Liquid
4
- module Tags
5
- module Editable
6
- class ShortText < Base
7
-
8
- def render(context)
9
- Locomotive::Common::Logger.warn " [#{self.current_block_name(context)}/#{@slug}] The editable_{short|long}_text tags are deprecated. Use editable_text instead.".colorize(:orange)
10
- super(context)
11
- end
12
-
13
- end
14
-
15
- ::Liquid::Template.register_tag('editable_short_text', ShortText)
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,98 +0,0 @@
1
- module Locomotive
2
- module Steam
3
- module Liquid
4
- module Tags
5
-
6
- module PathHelper
7
-
8
- def render_path(context, &block)
9
- site = context.registers[:site]
10
-
11
- if page = self.retrieve_page_from_handle(context)
12
- path = self.public_page_fullpath(context, page)
13
-
14
- if block_given?
15
- block.call page, path
16
- else
17
- path
18
- end
19
- else
20
- raise Liquid::PageNotTranslated.new(%{[link_to] Unable to find a page for the #{@handle}. Wrong handle or missing template for your content.})
21
- end
22
- end
23
-
24
- protected
25
-
26
- def retrieve_page_from_handle(context)
27
- mounting_point = context.registers[:mounting_point]
28
-
29
- context.scopes.reverse_each do |scope|
30
- handle = scope[@handle] || @handle
31
-
32
- page = case handle
33
- when Locomotive::Mounter::Models::Page then handle
34
- when Liquid::Drops::Page then handle.instance_variable_get(:@_source)
35
- when String then fetch_page(mounting_point, handle)
36
- when Liquid::Drops::ContentEntry then fetch_page(mounting_point, handle.instance_variable_get(:@_source), true)
37
- when Locomotive::Mounter::Models::ContentEntry then fetch_page(mounting_point, handle, true)
38
- else
39
- nil
40
- end
41
-
42
- return page unless page.nil?
43
- end
44
-
45
- nil
46
- end
47
-
48
- def fetch_page(mounting_point, handle, templatized = false)
49
- ::Locomotive::Mounter.with_locale(@_options['locale']) do
50
- if templatized
51
- page = mounting_point.pages.values.find do |_page|
52
- _page.templatized? &&
53
- !_page.templatized_from_parent &&
54
- _page.content_type.slug == handle.content_type.slug &&
55
- (@_options['with'].nil? || _page.handle == @_options['with'])
56
- end
57
-
58
- page.content_entry = handle if page
59
-
60
- page
61
- else
62
- mounting_point.pages.values.find { |_page| _page.handle == handle }
63
- end
64
- end
65
- end
66
-
67
- def public_page_fullpath(context, page)
68
- mounting_point = context.registers[:mounting_point]
69
- locale = @_options['locale'] || ::I18n.locale
70
-
71
- if !page.translated_in?(locale)
72
- title = page.title_translations.values.compact.first
73
- raise Liquid::PageNotTranslated.new(%{the "#{title}" page is not translated in #{locale.upcase}})
74
- end
75
-
76
- fullpath = ::Locomotive::Mounter.with_locale(locale) do
77
- page.fullpath.clone
78
- end
79
-
80
- fullpath = "#{locale}/#{fullpath}" if locale.to_s != mounting_point.default_locale.to_s
81
-
82
- if page.templatized?
83
- if page.content_entry._slug.nil?
84
- title = %{#{page.content_entry.content_type.name.singularize} "#{page.content_entry.send(page.content_entry.content_type.label_field_name)}"}
85
- raise Liquid::ContentEntryNotTranslated.new(%{the #{title} slug is not translated in #{locale.upcase}})
86
- end
87
- fullpath.gsub!(/(content[_-]type[_-]template|template)/, page.content_entry._slug)
88
- end
89
-
90
- File.join('/', fullpath)
91
- end
92
-
93
- end
94
- end
95
-
96
- end
97
- end
98
- end
@@ -1,193 +0,0 @@
1
- module Locomotive
2
- module Steam
3
- module Loader
4
- module Yml
5
- class PagesLoader
6
- def initialize(path, mapper)
7
- @root_path = path
8
- @path = File.join(path, 'app', 'views', 'pages')
9
- @mapper = mapper
10
- end
11
-
12
-
13
- # Build the tree of pages based on the filesystem structure
14
- #
15
- # @return [ Hash ] The pages organized as a Hash (using the fullpath as the key)
16
- #
17
- def load!
18
- entity_class = @mapper.collection(:pages).entity
19
- repository = @mapper.collection(:pages).repository
20
- all.each do |record|
21
- page = entity_class.new(record)
22
- repository.create page
23
- end
24
- end
25
-
26
- protected
27
-
28
- def build_relationships(parent, list)
29
- # do not use an empty template for other locales than the default one
30
- parent.set_default_template_for_each_locale(self.default_locale)
31
-
32
- list.dup.each do |page|
33
- next unless self.is_subpage_of?(page.fullpath, parent.fullpath)
34
-
35
- # attach the page to the parent (order by position), also set the parent
36
- parent.add_child(page)
37
-
38
- # localize the fullpath in all the locales
39
- page.localize_fullpath
40
-
41
- # remove the page from the list
42
- list.delete(page)
43
-
44
- # go under
45
- self.build_relationships(page, list)
46
- end
47
- end
48
-
49
- # Record pages found in file system
50
- def all
51
- [].tap do |page_records|
52
- position, last_dirname = nil, nil
53
- tree.each do |pagename, localizations|
54
- filepath = localizations.delete(:default)
55
- #next unless File.directory?(filepath) || filepath =~ /\.(#{Locomotive::Steam::TEMPLATE_EXTENSIONS.join('|')})$/
56
- if last_dirname != File.dirname(filepath)
57
- position, last_dirname = 100, File.dirname(filepath)
58
- end
59
- page = page_attributes(filepath, localizations)
60
- page[:position] = position
61
-
62
- page_records << page
63
- position += 1
64
- end
65
- end
66
- end
67
-
68
- def tree
69
- Locomotive::Steam::Utils::LocalizedTree
70
- .new(all_files, Locomotive::Steam::TEMPLATE_EXTENSIONS)
71
- .to_hash
72
- end
73
-
74
- def all_files
75
- Dir.glob(File.join(root_dir, '**/*')).sort
76
- end
77
-
78
- def page_attributes(filepath, localizations)
79
- {}.tap do |attributes|
80
- add_base_attributes(attributes, filepath)
81
- add_localized_attributes(attributes, filepath, :en)
82
- localizations.each { |locale, locale_file| add_localized_attributes(attributes, locale_file, locale) }
83
- end
84
- end
85
-
86
- def add_base_attributes(attributes, filepath)
87
- attributes.merge! _base_attributes(filepath)
88
- end
89
-
90
- def add_localized_attributes(attributes, filepath, locale)
91
- attributes.deep_merge! _localized_attributes(filepath, locale)
92
- end
93
-
94
- def _localized_attributes(filepath, locale)
95
- fetch_raw_attrs(filepath).dup.select do |key, value|
96
- %i{title slug fullpath redirect_url template
97
- seo_title meta_keywords meta_description editable_elements}
98
- .include? key
99
-
100
- end.map { |key, item| {key => { "#{locale}".to_sym => item }} }.reduce(:merge)
101
- end
102
-
103
- def _base_attributes(filepath)
104
- fetch_raw_attrs(filepath).dup.select do |key, value|
105
- %i{content_type redirect_type handle listed searchable
106
- templatized content_type published cache_strategy response_type
107
- position}
108
- .include? key
109
- end
110
- end
111
-
112
- def fetch_raw_attrs(filepath)
113
- raw_attrs[filepath]
114
- end
115
-
116
- def raw_attrs
117
- @raw_attrs ||= Hash.new do |hsh, filepath|
118
- attributes = {}
119
- fullpath = self.filepath_to_fullpath(filepath)
120
- attributes[:title] = File.basename(fullpath).humanize
121
- attributes[:fullpath] = fullpath
122
- attributes[:template] = OpenStruct.new(raw_source: '') if File.directory?(filepath)
123
- attributes.merge!(get_attributes_from_header(filepath)) unless File.directory?(filepath)
124
- if content_type_slug = attributes.delete('content_type')
125
- attributes[:templatized] = true
126
- attributes[:content_type] = Locomotive::Models[:content_types][content_type_slug]
127
- end
128
- hsh[filepath] = attributes
129
- end
130
- end
131
- # Set attributes of a page from the information
132
- # stored in the header of the template (YAML matters).
133
- # It also stores the template.
134
- #
135
- # @param [ Object ] page The page
136
- # @param [ String ] filepath The path of the template
137
- #
138
- def get_attributes_from_header(filepath)
139
- {}.tap do |attributes|
140
- template = Locomotive::Steam::Utils::YAMLFrontMattersTemplate.new(filepath)
141
- attributes[:template] = template
142
- if template.attributes
143
- attributes.merge! template.attributes.symbolize_keys
144
- end
145
- end
146
- end
147
-
148
- # Return the directory where all the templates of
149
- # pages are stored in the filesystem.
150
- #
151
- # @return [ String ] The root directory
152
- #
153
- def root_dir
154
- @path
155
- end
156
-
157
- # Take the path to a file on the filesystem
158
- # and return its matching value for a Page.
159
- #
160
- # @param [ String ] filepath The path to the file
161
- #
162
- # @return [ String ] The fullpath of the page
163
- #
164
- def filepath_to_fullpath(filepath)
165
- fullpath = filepath.gsub(File.join(self.root_dir, '/'), '')
166
-
167
- fullpath.gsub!(/^\.\//, '')
168
-
169
- fullpath.split('.').first.dasherize
170
- end
171
-
172
- # Tell is a page described by its fullpath is a sub page of a parent page
173
- # also described by its fullpath
174
- #
175
- # @param [ String ] fullpath The full path of the page to test
176
- # @param [ String ] parent_fullpath The full path of the parent page
177
- #
178
- # @return [ Boolean] True if the page is a sub page of the parent one
179
- #
180
- def is_subpage_of?(fullpath, parent_fullpath)
181
- return false if %w(index 404).include?(fullpath)
182
-
183
- if parent_fullpath == 'index' && fullpath.split('/').size == 1
184
- return true
185
- end
186
-
187
- File.dirname(fullpath.dasherize) == parent_fullpath.dasherize
188
- end
189
- end
190
- end
191
- end
192
- end
193
- end