tribeca_cms 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (565) hide show
  1. data/Gemfile +58 -0
  2. data/LICENSE +1 -0
  3. data/README.textile +0 -0
  4. data/app/assets/images/locomotive/background/body.png +0 -0
  5. data/app/assets/images/locomotive/datepicker/ui-widget-content-top.png +0 -0
  6. data/app/assets/images/locomotive/form/error-arrow.png +0 -0
  7. data/app/assets/images/locomotive/form/input-sep.png +0 -0
  8. data/app/assets/images/locomotive/icons/flags/de.png +0 -0
  9. data/app/assets/images/locomotive/icons/flags/en.png +0 -0
  10. data/app/assets/images/locomotive/icons/flags/es.png +0 -0
  11. data/app/assets/images/locomotive/icons/flags/et.png +0 -0
  12. data/app/assets/images/locomotive/icons/flags/fr.png +0 -0
  13. data/app/assets/images/locomotive/icons/flags/it.png +0 -0
  14. data/app/assets/images/locomotive/icons/flags/nb.png +0 -0
  15. data/app/assets/images/locomotive/icons/flags/nl.png +0 -0
  16. data/app/assets/images/locomotive/icons/flags/pl.png +0 -0
  17. data/app/assets/images/locomotive/icons/flags/pt-BR.png +0 -0
  18. data/app/assets/images/locomotive/icons/flags/ru.png +0 -0
  19. data/app/assets/images/locomotive/icons/start.png +0 -0
  20. data/app/assets/images/locomotive/list/empty.png +0 -0
  21. data/app/assets/images/locomotive/list/item-left.png +0 -0
  22. data/app/assets/images/locomotive/nocoffee.png +0 -0
  23. data/app/assets/images/locomotive/plugins/sites_picker_top_arrow.png +0 -0
  24. data/app/assets/images/locomotive/rails.png +0 -0
  25. data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/css/image.css +3 -0
  26. data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/img/image.gif +0 -0
  27. data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/lib/locomotive_media-plugin.js +96 -0
  28. data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/nls/fr/i18n.js +1 -0
  29. data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/nls/i18n.js +4 -0
  30. data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/package.json +1 -0
  31. data/app/assets/javascripts/locomotive.js +25 -0
  32. data/app/assets/javascripts/locomotive/aloha.js.coffee +2 -0
  33. data/app/assets/javascripts/locomotive/application.js.coffee +12 -0
  34. data/app/assets/javascripts/locomotive/inline_editor.js.coffee +22 -0
  35. data/app/assets/javascripts/locomotive/models/account.js.coffee +11 -0
  36. data/app/assets/javascripts/locomotive/models/content_asset.js.coffee +20 -0
  37. data/app/assets/javascripts/locomotive/models/content_entry.js.coffee +61 -0
  38. data/app/assets/javascripts/locomotive/models/content_type.js.coffee +26 -0
  39. data/app/assets/javascripts/locomotive/models/custom_field.js.coffee +38 -0
  40. data/app/assets/javascripts/locomotive/models/custom_field_select_option.js.coffee +16 -0
  41. data/app/assets/javascripts/locomotive/models/domain.js.coffee +3 -0
  42. data/app/assets/javascripts/locomotive/models/editable_element.js.coffee +27 -0
  43. data/app/assets/javascripts/locomotive/models/membership.js.coffee +13 -0
  44. data/app/assets/javascripts/locomotive/models/page.js.coffee +27 -0
  45. data/app/assets/javascripts/locomotive/models/site.js.coffee +34 -0
  46. data/app/assets/javascripts/locomotive/models/snippet.js.coffee +11 -0
  47. data/app/assets/javascripts/locomotive/models/theme_asset.js.coffee +11 -0
  48. data/app/assets/javascripts/locomotive/models/translation.js.coffee +5 -0
  49. data/app/assets/javascripts/locomotive/not_logged_in.js.coffee +1 -0
  50. data/app/assets/javascripts/locomotive/utils/aloha_settings.js.coffee +37 -0
  51. data/app/assets/javascripts/locomotive/utils/core_ext.js +75 -0
  52. data/app/assets/javascripts/locomotive/utils/growl.js +14 -0
  53. data/app/assets/javascripts/locomotive/utils/handlebar_helpers.js.coffee +9 -0
  54. data/app/assets/javascripts/locomotive/utils/tinymce_settings.js.coffee +48 -0
  55. data/app/assets/javascripts/locomotive/views/application_view.js.coffee +92 -0
  56. data/app/assets/javascripts/locomotive/views/content_assets/picker_item_view.js.coffee +30 -0
  57. data/app/assets/javascripts/locomotive/views/content_assets/picker_view.js.coffee +58 -0
  58. data/app/assets/javascripts/locomotive/views/content_entries/_form_view.js.coffee +144 -0
  59. data/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee +90 -0
  60. data/app/assets/javascripts/locomotive/views/content_entries/edit_view.js.coffee +9 -0
  61. data/app/assets/javascripts/locomotive/views/content_entries/index_view.js.coffee +36 -0
  62. data/app/assets/javascripts/locomotive/views/content_entries/new_view.js.coffee +8 -0
  63. data/app/assets/javascripts/locomotive/views/content_types/_form_view.js.coffee +86 -0
  64. data/app/assets/javascripts/locomotive/views/content_types/custom_field_entry_view.js.coffee +104 -0
  65. data/app/assets/javascripts/locomotive/views/content_types/custom_fields_view.coffee +94 -0
  66. data/app/assets/javascripts/locomotive/views/content_types/edit_view.coffee +14 -0
  67. data/app/assets/javascripts/locomotive/views/content_types/new_view.js.coffee +11 -0
  68. data/app/assets/javascripts/locomotive/views/content_types/select_options_view.js.coffee +89 -0
  69. data/app/assets/javascripts/locomotive/views/current_site/edit_view.js.coffee +86 -0
  70. data/app/assets/javascripts/locomotive/views/editable_elements/control_view.js.coffee +24 -0
  71. data/app/assets/javascripts/locomotive/views/editable_elements/edit_all_view.js.coffee +83 -0
  72. data/app/assets/javascripts/locomotive/views/editable_elements/file_view.js.coffee +74 -0
  73. data/app/assets/javascripts/locomotive/views/editable_elements/long_text_view.js.coffee +36 -0
  74. data/app/assets/javascripts/locomotive/views/editable_elements/short_text_view.js.coffee +22 -0
  75. data/app/assets/javascripts/locomotive/views/inline_editor/application_view.js.coffee +124 -0
  76. data/app/assets/javascripts/locomotive/views/inline_editor/toolbar_view.js.coffee +145 -0
  77. data/app/assets/javascripts/locomotive/views/my_account/edit_view.js.coffee +24 -0
  78. data/app/assets/javascripts/locomotive/views/pages/_form_view.js.coffee +162 -0
  79. data/app/assets/javascripts/locomotive/views/pages/edit_view.js.coffee +31 -0
  80. data/app/assets/javascripts/locomotive/views/pages/index_view.js.coffee +11 -0
  81. data/app/assets/javascripts/locomotive/views/pages/list_view.js.coffee +40 -0
  82. data/app/assets/javascripts/locomotive/views/pages/new_view.js.coffee +8 -0
  83. data/app/assets/javascripts/locomotive/views/shared/asset_picker_view.js.coffee +92 -0
  84. data/app/assets/javascripts/locomotive/views/shared/fields/file_view.js.coffee +88 -0
  85. data/app/assets/javascripts/locomotive/views/shared/fields/has_many_view.js.coffee +125 -0
  86. data/app/assets/javascripts/locomotive/views/shared/fields/many_to_many_view.js.coffee +131 -0
  87. data/app/assets/javascripts/locomotive/views/shared/fields/select_view.js.coffee +83 -0
  88. data/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee +138 -0
  89. data/app/assets/javascripts/locomotive/views/shared/list_item_view.js.coffee +22 -0
  90. data/app/assets/javascripts/locomotive/views/shared/list_view.js.coffee +53 -0
  91. data/app/assets/javascripts/locomotive/views/sites/domain_entry_view.js.coffee +26 -0
  92. data/app/assets/javascripts/locomotive/views/sites/domains_view.js.coffee +84 -0
  93. data/app/assets/javascripts/locomotive/views/sites/membership_entry_view.js.coffee +31 -0
  94. data/app/assets/javascripts/locomotive/views/sites/memberships_view.js.coffee +41 -0
  95. data/app/assets/javascripts/locomotive/views/sites/new_view.js.coffee +43 -0
  96. data/app/assets/javascripts/locomotive/views/snippets/_form_view.js.coffee +75 -0
  97. data/app/assets/javascripts/locomotive/views/snippets/edit_view.js.coffee +6 -0
  98. data/app/assets/javascripts/locomotive/views/snippets/list_item_view.js.coffee +8 -0
  99. data/app/assets/javascripts/locomotive/views/snippets/list_view.js.coffee +17 -0
  100. data/app/assets/javascripts/locomotive/views/snippets/new_view.js.coffee +8 -0
  101. data/app/assets/javascripts/locomotive/views/theme_assets/_form_view.js.coffee +104 -0
  102. data/app/assets/javascripts/locomotive/views/theme_assets/edit_view.js.coffee +16 -0
  103. data/app/assets/javascripts/locomotive/views/theme_assets/image_picker_view.js.coffee +48 -0
  104. data/app/assets/javascripts/locomotive/views/theme_assets/index_view.js.coffee +91 -0
  105. data/app/assets/javascripts/locomotive/views/theme_assets/list_item_view.js.coffee +8 -0
  106. data/app/assets/javascripts/locomotive/views/theme_assets/list_view.js.coffee +17 -0
  107. data/app/assets/javascripts/locomotive/views/theme_assets/new_view.js.coffee +8 -0
  108. data/app/assets/javascripts/locomotive/views/translations/_form_view.js.coffee +20 -0
  109. data/app/assets/javascripts/locomotive/views/translations/edit_view.js.coffee +6 -0
  110. data/app/assets/javascripts/locomotive/views/translations/new_view.js.coffee +8 -0
  111. data/app/assets/javascripts/tinymce/plugins/jqueryinlinepopups/editor_plugin.js +240 -0
  112. data/app/assets/javascripts/tinymce/plugins/locomotive_media/editor_plugin.js +78 -0
  113. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/content.css +66 -0
  114. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/dialog.css.scss +78 -0
  115. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/butt2.png +0 -0
  116. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/button-bg.png +0 -0
  117. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/buttons.png +0 -0
  118. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/down_arrow.gif +0 -0
  119. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/fade-butt.png +0 -0
  120. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/icons.png +0 -0
  121. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/items.gif +0 -0
  122. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/menu-arrow.png +0 -0
  123. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/menu-check.png +0 -0
  124. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/progress.gif +0 -0
  125. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/tabs.gif +0 -0
  126. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/toolbarbg.png +0 -0
  127. data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/ui.css +1018 -0
  128. data/app/assets/stylesheets/locomotive.css +16 -0
  129. data/app/assets/stylesheets/locomotive/backoffice/_box.css.scss +157 -0
  130. data/app/assets/stylesheets/locomotive/backoffice/_buttons.css.scss +178 -0
  131. data/app/assets/stylesheets/locomotive/backoffice/application.css.scss +332 -0
  132. data/app/assets/stylesheets/locomotive/backoffice/codemirror_changes.css.scss +19 -0
  133. data/app/assets/stylesheets/locomotive/backoffice/content_assets.css.scss +130 -0
  134. data/app/assets/stylesheets/locomotive/backoffice/datepicker.css.scss +178 -0
  135. data/app/assets/stylesheets/locomotive/backoffice/dialog_changes.css.scss +141 -0
  136. data/app/assets/stylesheets/locomotive/backoffice/editable_elements.css.scss +71 -0
  137. data/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.scss +735 -0
  138. data/app/assets/stylesheets/locomotive/backoffice/layout.css.scss +205 -0
  139. data/app/assets/stylesheets/locomotive/backoffice/menu.css +8 -0
  140. data/app/assets/stylesheets/locomotive/backoffice/menu/_colors.css.scss +125 -0
  141. data/app/assets/stylesheets/locomotive/backoffice/menu/_helpers.css.scss +6 -0
  142. data/app/assets/stylesheets/locomotive/backoffice/menu/default.css.scss +32 -0
  143. data/app/assets/stylesheets/locomotive/backoffice/menu/main.css.scss +127 -0
  144. data/app/assets/stylesheets/locomotive/backoffice/menu/sub.css.scss +276 -0
  145. data/app/assets/stylesheets/locomotive/backoffice/sites_picker.css.scss +12 -0
  146. data/app/assets/stylesheets/locomotive/inline_editor.css +13 -0
  147. data/app/assets/stylesheets/locomotive/inline_editor/_buttons.css.scss +60 -0
  148. data/app/assets/stylesheets/locomotive/inline_editor/layout.css.scss +22 -0
  149. data/app/assets/stylesheets/locomotive/inline_editor/toolbar.css.scss +114 -0
  150. data/app/assets/stylesheets/locomotive/not_logged_in.css +8 -0
  151. data/app/assets/stylesheets/locomotive/not_logged_in/installation.css.scss +62 -0
  152. data/app/assets/stylesheets/locomotive/not_logged_in/layout.css.scss +185 -0
  153. data/app/assets/stylesheets/locomotive/shared/_helpers.css.scss +150 -0
  154. data/app/assets/stylesheets/locomotive/shared/_picker.css.scss +73 -0
  155. data/app/assets/stylesheets/locomotive/shared/common.css.scss +34 -0
  156. data/app/assets/stylesheets/locomotive/shared/content_locale_picker.css.scss +80 -0
  157. data/app/assets/stylesheets/locomotive/shared/growl.css.scss +29 -0
  158. data/app/cells/locomotive/content_locale_picker/show.html.haml +7 -0
  159. data/app/cells/locomotive/content_locale_picker_cell.rb +21 -0
  160. data/app/cells/locomotive/global_actions/show.html.haml +12 -0
  161. data/app/cells/locomotive/global_actions_cell.rb +36 -0
  162. data/app/cells/locomotive/main_menu/show.html.haml +13 -0
  163. data/app/cells/locomotive/main_menu_cell.rb +12 -0
  164. data/app/cells/locomotive/menu/show.html.haml +1 -0
  165. data/app/cells/locomotive/menu_cell.rb +102 -0
  166. data/app/cells/locomotive/settings_menu_cell.rb +14 -0
  167. data/app/cells/locomotive/sub_menu/show.html.haml +4 -0
  168. data/app/cells/locomotive/sub_menu_cell.rb +13 -0
  169. data/app/controllers/locomotive/accounts_controller.rb +18 -0
  170. data/app/controllers/locomotive/api/accounts_controller.rb +79 -0
  171. data/app/controllers/locomotive/api/base_controller.rb +50 -0
  172. data/app/controllers/locomotive/api/content_assets_controller.rb +39 -0
  173. data/app/controllers/locomotive/api/content_entries_controller.rb +45 -0
  174. data/app/controllers/locomotive/api/content_types_controller.rb +39 -0
  175. data/app/controllers/locomotive/api/current_site_controller.rb +58 -0
  176. data/app/controllers/locomotive/api/documentation_controller.rb +15 -0
  177. data/app/controllers/locomotive/api/memberships_controller.rb +97 -0
  178. data/app/controllers/locomotive/api/my_account_controller.rb +35 -0
  179. data/app/controllers/locomotive/api/pages_controller.rb +41 -0
  180. data/app/controllers/locomotive/api/sites_controller.rb +93 -0
  181. data/app/controllers/locomotive/api/snippets_controller.rb +40 -0
  182. data/app/controllers/locomotive/api/theme_assets_controller.rb +39 -0
  183. data/app/controllers/locomotive/api/tokens_controller.rb +54 -0
  184. data/app/controllers/locomotive/api/translations_controller.rb +31 -0
  185. data/app/controllers/locomotive/base_controller.rb +61 -0
  186. data/app/controllers/locomotive/content_assets_controller.rb +23 -0
  187. data/app/controllers/locomotive/content_entries_controller.rb +71 -0
  188. data/app/controllers/locomotive/content_types_controller.rb +40 -0
  189. data/app/controllers/locomotive/current_site_controller.rb +52 -0
  190. data/app/controllers/locomotive/installation_controller.rb +72 -0
  191. data/app/controllers/locomotive/memberships_controller.rb +29 -0
  192. data/app/controllers/locomotive/my_account_controller.rb +24 -0
  193. data/app/controllers/locomotive/pages_controller.rb +63 -0
  194. data/app/controllers/locomotive/passwords_controller.rb +19 -0
  195. data/app/controllers/locomotive/public/base_controller.rb +22 -0
  196. data/app/controllers/locomotive/public/content_entries_controller.rb +55 -0
  197. data/app/controllers/locomotive/public/pages_controller.rb +50 -0
  198. data/app/controllers/locomotive/public/robots_controller.rb +16 -0
  199. data/app/controllers/locomotive/public/sitemaps_controller.rb +14 -0
  200. data/app/controllers/locomotive/sessions_controller.rb +29 -0
  201. data/app/controllers/locomotive/sites_controller.rb +33 -0
  202. data/app/controllers/locomotive/snippets_controller.rb +47 -0
  203. data/app/controllers/locomotive/theme_assets_controller.rb +52 -0
  204. data/app/controllers/locomotive/translations_controller.rb +32 -0
  205. data/app/helpers/locomotive/accounts_helper.rb +13 -0
  206. data/app/helpers/locomotive/base_helper.rb +182 -0
  207. data/app/helpers/locomotive/content_entries_helper.rb +15 -0
  208. data/app/helpers/locomotive/content_types_helper.rb +72 -0
  209. data/app/helpers/locomotive/custom_fields_helper.rb +70 -0
  210. data/app/helpers/locomotive/installation_helper.rb +9 -0
  211. data/app/helpers/locomotive/pages_helper.rb +95 -0
  212. data/app/helpers/locomotive/sites_helper.rb +15 -0
  213. data/app/helpers/locomotive/snippets_helper.rb +20 -0
  214. data/app/helpers/locomotive/theme_assets_helper.rb +30 -0
  215. data/app/helpers/locomotive/translations_helper.rb +19 -0
  216. data/app/inputs/locomotive/code_input.rb +51 -0
  217. data/app/inputs/locomotive/empty_input.rb +35 -0
  218. data/app/inputs/locomotive/file_input.rb +45 -0
  219. data/app/inputs/locomotive/locale_input.rb +40 -0
  220. data/app/inputs/locomotive/locales_input.rb +60 -0
  221. data/app/inputs/locomotive/rte_input.rb +13 -0
  222. data/app/inputs/locomotive/small_code_input.rb +22 -0
  223. data/app/inputs/locomotive/subdomain_input.rb +22 -0
  224. data/app/inputs/locomotive/toggle_input.rb +13 -0
  225. data/app/mailers/locomotive/devise_mailer.rb +10 -0
  226. data/app/mailers/locomotive/notifications.rb +15 -0
  227. data/app/models/locomotive/ability.rb +89 -0
  228. data/app/models/locomotive/account.rb +117 -0
  229. data/app/models/locomotive/content_asset.rb +40 -0
  230. data/app/models/locomotive/content_entry.rb +197 -0
  231. data/app/models/locomotive/content_type.rb +224 -0
  232. data/app/models/locomotive/editable_control.rb +52 -0
  233. data/app/models/locomotive/editable_element.rb +122 -0
  234. data/app/models/locomotive/editable_file.rb +85 -0
  235. data/app/models/locomotive/editable_long_text.rb +5 -0
  236. data/app/models/locomotive/editable_short_text.rb +66 -0
  237. data/app/models/locomotive/extensions/asset/types.rb +31 -0
  238. data/app/models/locomotive/extensions/asset/vignette.rb +19 -0
  239. data/app/models/locomotive/extensions/content_type/default_values.rb +57 -0
  240. data/app/models/locomotive/extensions/content_type/item_template.rb +49 -0
  241. data/app/models/locomotive/extensions/content_type/sync.rb +62 -0
  242. data/app/models/locomotive/extensions/page/editable_elements.rb +105 -0
  243. data/app/models/locomotive/extensions/page/listed.rb +18 -0
  244. data/app/models/locomotive/extensions/page/parse.rb +125 -0
  245. data/app/models/locomotive/extensions/page/redirect.rb +25 -0
  246. data/app/models/locomotive/extensions/page/render.rb +93 -0
  247. data/app/models/locomotive/extensions/page/templatized.rb +163 -0
  248. data/app/models/locomotive/extensions/page/tree.rb +133 -0
  249. data/app/models/locomotive/extensions/shared/seo.rb +16 -0
  250. data/app/models/locomotive/extensions/site/first_installation.rb +20 -0
  251. data/app/models/locomotive/extensions/site/locales.rb +112 -0
  252. data/app/models/locomotive/extensions/site/subdomain_domains.rb +91 -0
  253. data/app/models/locomotive/membership.rb +75 -0
  254. data/app/models/locomotive/page.rb +130 -0
  255. data/app/models/locomotive/site.rb +79 -0
  256. data/app/models/locomotive/snippet.rb +70 -0
  257. data/app/models/locomotive/theme_asset.rb +175 -0
  258. data/app/models/locomotive/translation.rb +32 -0
  259. data/app/presenters/locomotive/account_presenter.rb +19 -0
  260. data/app/presenters/locomotive/base_presenter.rb +99 -0
  261. data/app/presenters/locomotive/content_asset_presenter.rb +43 -0
  262. data/app/presenters/locomotive/content_entry_presenter.rb +217 -0
  263. data/app/presenters/locomotive/content_field_presenter.rb +71 -0
  264. data/app/presenters/locomotive/content_type_presenter.rb +68 -0
  265. data/app/presenters/locomotive/editable_control_presenter.rb +19 -0
  266. data/app/presenters/locomotive/editable_element_presenter.rb +40 -0
  267. data/app/presenters/locomotive/editable_file_presenter.rb +29 -0
  268. data/app/presenters/locomotive/editable_long_text_presenter.rb +5 -0
  269. data/app/presenters/locomotive/editable_short_text_presenter.rb +27 -0
  270. data/app/presenters/locomotive/membership_presenter.rb +36 -0
  271. data/app/presenters/locomotive/page_presenter.rb +58 -0
  272. data/app/presenters/locomotive/site_presenter.rb +36 -0
  273. data/app/presenters/locomotive/snippet_presenter.rb +22 -0
  274. data/app/presenters/locomotive/theme_asset_presenter.rb +61 -0
  275. data/app/presenters/locomotive/translation_presenter.rb +9 -0
  276. data/app/uploaders/locomotive/content_asset_uploader.rb +13 -0
  277. data/app/uploaders/locomotive/editable_file_uploader.rb +15 -0
  278. data/app/uploaders/locomotive/theme_asset_uploader.rb +28 -0
  279. data/app/views/locomotive/accounts/new.html.haml +21 -0
  280. data/app/views/locomotive/content_assets/_asset.html.haml +5 -0
  281. data/app/views/locomotive/content_assets/_picker.html.haml +33 -0
  282. data/app/views/locomotive/content_entries/_form.html.haml +22 -0
  283. data/app/views/locomotive/content_entries/_list.html.haml +18 -0
  284. data/app/views/locomotive/content_entries/edit.html.haml +21 -0
  285. data/app/views/locomotive/content_entries/index.html.haml +32 -0
  286. data/app/views/locomotive/content_entries/new.html.haml +19 -0
  287. data/app/views/locomotive/content_types/_form.html.haml +39 -0
  288. data/app/views/locomotive/content_types/edit.html.haml +19 -0
  289. data/app/views/locomotive/content_types/new.html.haml +15 -0
  290. data/app/views/locomotive/current_site/_form.html.haml +36 -0
  291. data/app/views/locomotive/current_site/edit.html.haml +19 -0
  292. data/app/views/locomotive/custom_fields/_form.html.haml +61 -0
  293. data/app/views/locomotive/custom_fields/_select_templates.html.haml +16 -0
  294. data/app/views/locomotive/custom_fields/types/_belongs_to.html.haml +5 -0
  295. data/app/views/locomotive/custom_fields/types/_boolean.html.haml +4 -0
  296. data/app/views/locomotive/custom_fields/types/_date.html.haml +5 -0
  297. data/app/views/locomotive/custom_fields/types/_file.html.haml +4 -0
  298. data/app/views/locomotive/custom_fields/types/_has_many.html.haml +70 -0
  299. data/app/views/locomotive/custom_fields/types/_many_to_many.html.haml +41 -0
  300. data/app/views/locomotive/custom_fields/types/_select.html.haml +34 -0
  301. data/app/views/locomotive/custom_fields/types/_string.html.haml +4 -0
  302. data/app/views/locomotive/custom_fields/types/_text.html.haml +5 -0
  303. data/app/views/locomotive/devise_mailer/reset_password_instructions.html.haml +12 -0
  304. data/app/views/locomotive/errors/404.html.haml +7 -0
  305. data/app/views/locomotive/errors/500.html.haml +7 -0
  306. data/app/views/locomotive/errors/no_page.html.haml +1 -0
  307. data/app/views/locomotive/errors/no_site.html.haml +1 -0
  308. data/app/views/locomotive/installation/step_1.html.haml +23 -0
  309. data/app/views/locomotive/installation/step_2.html.haml +24 -0
  310. data/app/views/locomotive/layouts/application.html.haml +34 -0
  311. data/app/views/locomotive/layouts/error.html.haml +1 -0
  312. data/app/views/locomotive/layouts/not_logged_in.html.haml +18 -0
  313. data/app/views/locomotive/memberships/new.html.haml +14 -0
  314. data/app/views/locomotive/my_account/edit.html.haml +40 -0
  315. data/app/views/locomotive/notifications/new_content_entry.html.haml +29 -0
  316. data/app/views/locomotive/pages/_editable_elements.html.haml +64 -0
  317. data/app/views/locomotive/pages/_form.html.haml +61 -0
  318. data/app/views/locomotive/pages/_page.html.haml +42 -0
  319. data/app/views/locomotive/pages/edit.html.haml +18 -0
  320. data/app/views/locomotive/pages/index.html.haml +19 -0
  321. data/app/views/locomotive/pages/new.html.haml +15 -0
  322. data/app/views/locomotive/passwords/edit.html.haml +18 -0
  323. data/app/views/locomotive/passwords/new.html.haml +17 -0
  324. data/app/views/locomotive/public/pages/show_toolbar.html.haml +64 -0
  325. data/app/views/locomotive/public/sitemaps/show.xml.builder +29 -0
  326. data/app/views/locomotive/sessions/new.html.haml +17 -0
  327. data/app/views/locomotive/shared/_footer.html.haml +1 -0
  328. data/app/views/locomotive/shared/_form_actions.html.haml +14 -0
  329. data/app/views/locomotive/shared/_head.html.haml +38 -0
  330. data/app/views/locomotive/shared/_header.html.haml +10 -0
  331. data/app/views/locomotive/shared/_locale_picker_link.html.haml +6 -0
  332. data/app/views/locomotive/shared/_main_app_head.html.haml +1 -0
  333. data/app/views/locomotive/shared/_site_picker.html.haml +10 -0
  334. data/app/views/locomotive/shared/actions/_contents.html.haml +7 -0
  335. data/app/views/locomotive/shared/menu/_contents.html.haml +51 -0
  336. data/app/views/locomotive/sites/_domains.html.haml +22 -0
  337. data/app/views/locomotive/sites/_form.html.haml +12 -0
  338. data/app/views/locomotive/sites/_memberships.html.haml +27 -0
  339. data/app/views/locomotive/sites/new.html.haml +12 -0
  340. data/app/views/locomotive/snippets/_form.html.haml +13 -0
  341. data/app/views/locomotive/snippets/_snippet.html.haml +8 -0
  342. data/app/views/locomotive/snippets/edit.html.haml +18 -0
  343. data/app/views/locomotive/snippets/new.html.haml +15 -0
  344. data/app/views/locomotive/theme_assets/_asset.html.haml +11 -0
  345. data/app/views/locomotive/theme_assets/_form.html.haml +35 -0
  346. data/app/views/locomotive/theme_assets/_list.html.haml +7 -0
  347. data/app/views/locomotive/theme_assets/_picker.html.haml +25 -0
  348. data/app/views/locomotive/theme_assets/edit.html.haml +21 -0
  349. data/app/views/locomotive/theme_assets/index.html.haml +50 -0
  350. data/app/views/locomotive/theme_assets/new.html.haml +12 -0
  351. data/app/views/locomotive/translations/_form.html.haml +12 -0
  352. data/app/views/locomotive/translations/edit.html.haml +15 -0
  353. data/app/views/locomotive/translations/index.html.haml +26 -0
  354. data/app/views/locomotive/translations/new.html.haml +12 -0
  355. data/config/cucumber.yml +8 -0
  356. data/config/initializers/deny_phantomjs_ttf.rb +29 -0
  357. data/config/initializers/devise.rb +15 -0
  358. data/config/initializers/formtastic.rb +4 -0
  359. data/config/initializers/haml.rb +2 -0
  360. data/config/initializers/locomotive_loaded_first.rb +19 -0
  361. data/config/locales/admin_ui.de.yml +316 -0
  362. data/config/locales/admin_ui.en.yml +332 -0
  363. data/config/locales/admin_ui.es.yml +296 -0
  364. data/config/locales/admin_ui.et.yml +315 -0
  365. data/config/locales/admin_ui.fr.yml +326 -0
  366. data/config/locales/admin_ui.it.yml +295 -0
  367. data/config/locales/admin_ui.nb.yml +314 -0
  368. data/config/locales/admin_ui.nl.yml +279 -0
  369. data/config/locales/admin_ui.pl.yml +319 -0
  370. data/config/locales/admin_ui.pt-BR.yml +274 -0
  371. data/config/locales/admin_ui.ru.yml +313 -0
  372. data/config/locales/carrierwave.de.yml +4 -0
  373. data/config/locales/carrierwave.en.yml +4 -0
  374. data/config/locales/carrierwave.es.yml +4 -0
  375. data/config/locales/carrierwave.et.yml +4 -0
  376. data/config/locales/carrierwave.fr.yml +4 -0
  377. data/config/locales/carrierwave.it.yml +4 -0
  378. data/config/locales/carrierwave.nb.yml +4 -0
  379. data/config/locales/carrierwave.nl.yml +4 -0
  380. data/config/locales/carrierwave.pl.yml +4 -0
  381. data/config/locales/carrierwave.pt-BR.yml +4 -0
  382. data/config/locales/carrierwave.ru.yml +4 -0
  383. data/config/locales/default.de.yml +244 -0
  384. data/config/locales/default.en.yml +43 -0
  385. data/config/locales/default.es.yml +216 -0
  386. data/config/locales/default.et.yml +240 -0
  387. data/config/locales/default.fr.yml +224 -0
  388. data/config/locales/default.it.yml +243 -0
  389. data/config/locales/default.nb.yml +313 -0
  390. data/config/locales/default.nl.yml +170 -0
  391. data/config/locales/default.pl.yml +317 -0
  392. data/config/locales/default.pt-BR.yml +211 -0
  393. data/config/locales/default.ru.yml +279 -0
  394. data/config/locales/devise.de.yml +62 -0
  395. data/config/locales/devise.en.yml +63 -0
  396. data/config/locales/devise.es.yml +63 -0
  397. data/config/locales/devise.et.yml +64 -0
  398. data/config/locales/devise.fr.yml +67 -0
  399. data/config/locales/devise.it.yml +63 -0
  400. data/config/locales/devise.nb.yml +63 -0
  401. data/config/locales/devise.nl.yml +63 -0
  402. data/config/locales/devise.pl.yml +63 -0
  403. data/config/locales/devise.pt-BR.yml +61 -0
  404. data/config/locales/devise.ru.yml +63 -0
  405. data/config/locales/flash.de.yml +106 -0
  406. data/config/locales/flash.en.yml +115 -0
  407. data/config/locales/flash.es.yml +106 -0
  408. data/config/locales/flash.et.yml +106 -0
  409. data/config/locales/flash.fr.yml +106 -0
  410. data/config/locales/flash.it.yml +106 -0
  411. data/config/locales/flash.nb.yml +106 -0
  412. data/config/locales/flash.nl.yml +106 -0
  413. data/config/locales/flash.pl.yml +106 -0
  414. data/config/locales/flash.pt-BR.yml +106 -0
  415. data/config/locales/flash.ru.yml +106 -0
  416. data/config/locales/formtastic.de.yml +97 -0
  417. data/config/locales/formtastic.en.yml +105 -0
  418. data/config/locales/formtastic.es.yml +84 -0
  419. data/config/locales/formtastic.et.yml +103 -0
  420. data/config/locales/formtastic.fr.yml +94 -0
  421. data/config/locales/formtastic.it.yml +99 -0
  422. data/config/locales/formtastic.nb.yml +103 -0
  423. data/config/locales/formtastic.nl.yml +85 -0
  424. data/config/locales/formtastic.pl.yml +105 -0
  425. data/config/locales/formtastic.pt-BR.yml +70 -0
  426. data/config/locales/formtastic.ru.yml +103 -0
  427. data/config/routes.rb +116 -0
  428. data/lib/generators/locomotive/install/install_generator.rb +35 -0
  429. data/lib/generators/locomotive/install/templates/README +26 -0
  430. data/lib/generators/locomotive/install/templates/carrierwave.rb +28 -0
  431. data/lib/generators/locomotive/install/templates/dragonfly.rb +22 -0
  432. data/lib/generators/locomotive/install/templates/locomotive.rb +69 -0
  433. data/lib/generators/locomotive/install/templates/mongoid.yml +34 -0
  434. data/lib/locomotive.rb +136 -0
  435. data/lib/locomotive/action_controller.rb +5 -0
  436. data/lib/locomotive/action_controller/locale_helpers.rb +61 -0
  437. data/lib/locomotive/action_controller/public_responder.rb +17 -0
  438. data/lib/locomotive/action_controller/responder.rb +78 -0
  439. data/lib/locomotive/action_controller/section_helpers.rb +29 -0
  440. data/lib/locomotive/action_controller/url_helpers.rb +38 -0
  441. data/lib/locomotive/carrierwave.rb +10 -0
  442. data/lib/locomotive/carrierwave/asset.rb +72 -0
  443. data/lib/locomotive/carrierwave/base.rb +15 -0
  444. data/lib/locomotive/carrierwave/patches.rb +32 -0
  445. data/lib/locomotive/configuration.rb +122 -0
  446. data/lib/locomotive/core_ext.rb +64 -0
  447. data/lib/locomotive/custom_fields.rb +66 -0
  448. data/lib/locomotive/dependencies.rb +30 -0
  449. data/lib/locomotive/devise.rb +1 -0
  450. data/lib/locomotive/dragonfly.rb +38 -0
  451. data/lib/locomotive/engine.rb +37 -0
  452. data/lib/locomotive/formtastic.rb +13 -0
  453. data/lib/locomotive/haml.rb +1 -0
  454. data/lib/locomotive/httparty.rb +2 -0
  455. data/lib/locomotive/httparty/patches.rb +18 -0
  456. data/lib/locomotive/httparty/webservice.rb +42 -0
  457. data/lib/locomotive/kaminari.rb +35 -0
  458. data/lib/locomotive/liquid.rb +7 -0
  459. data/lib/locomotive/liquid/drops/base.rb +42 -0
  460. data/lib/locomotive/liquid/drops/content_entry.rb +76 -0
  461. data/lib/locomotive/liquid/drops/content_types.rb +50 -0
  462. data/lib/locomotive/liquid/drops/current_user.rb +21 -0
  463. data/lib/locomotive/liquid/drops/page.rb +55 -0
  464. data/lib/locomotive/liquid/drops/proxy_collection.rb +56 -0
  465. data/lib/locomotive/liquid/drops/site.rb +19 -0
  466. data/lib/locomotive/liquid/drops/uploader.rb +15 -0
  467. data/lib/locomotive/liquid/errors.rb +7 -0
  468. data/lib/locomotive/liquid/filters/base.rb +47 -0
  469. data/lib/locomotive/liquid/filters/date.rb +54 -0
  470. data/lib/locomotive/liquid/filters/html.rb +115 -0
  471. data/lib/locomotive/liquid/filters/misc.rb +65 -0
  472. data/lib/locomotive/liquid/filters/resize.rb +16 -0
  473. data/lib/locomotive/liquid/filters/text.rb +45 -0
  474. data/lib/locomotive/liquid/filters/translate.rb +16 -0
  475. data/lib/locomotive/liquid/patches.rb +21 -0
  476. data/lib/locomotive/liquid/tags/consume.rb +67 -0
  477. data/lib/locomotive/liquid/tags/csrf.rb +40 -0
  478. data/lib/locomotive/liquid/tags/editable.rb +5 -0
  479. data/lib/locomotive/liquid/tags/editable/base.rb +88 -0
  480. data/lib/locomotive/liquid/tags/editable/control.rb +31 -0
  481. data/lib/locomotive/liquid/tags/editable/file.rb +39 -0
  482. data/lib/locomotive/liquid/tags/editable/long_text.rb +33 -0
  483. data/lib/locomotive/liquid/tags/editable/short_text.rb +41 -0
  484. data/lib/locomotive/liquid/tags/extends.rb +47 -0
  485. data/lib/locomotive/liquid/tags/google_analytics.rb +39 -0
  486. data/lib/locomotive/liquid/tags/inherited_block.rb +31 -0
  487. data/lib/locomotive/liquid/tags/inline_editor.rb +40 -0
  488. data/lib/locomotive/liquid/tags/locale_switcher.rb +83 -0
  489. data/lib/locomotive/liquid/tags/nav.rb +155 -0
  490. data/lib/locomotive/liquid/tags/paginate.rb +111 -0
  491. data/lib/locomotive/liquid/tags/seo.rb +72 -0
  492. data/lib/locomotive/liquid/tags/snippet.rb +75 -0
  493. data/lib/locomotive/liquid/tags/with_scope.rb +47 -0
  494. data/lib/locomotive/logger.rb +11 -0
  495. data/lib/locomotive/middlewares.rb +4 -0
  496. data/lib/locomotive/middlewares/cache.rb +27 -0
  497. data/lib/locomotive/middlewares/fonts.rb +42 -0
  498. data/lib/locomotive/middlewares/inline_editor.rb +36 -0
  499. data/lib/locomotive/middlewares/seo_trailing_slash.rb +24 -0
  500. data/lib/locomotive/misc/api_documentation.rb +96 -0
  501. data/lib/locomotive/misc/api_documentation/bootstrap.html.haml +119 -0
  502. data/lib/locomotive/mongoid.rb +4 -0
  503. data/lib/locomotive/mongoid/document.rb +19 -0
  504. data/lib/locomotive/mongoid/liquid.rb +39 -0
  505. data/lib/locomotive/mongoid/patches.rb +106 -0
  506. data/lib/locomotive/mongoid/presenter.rb +73 -0
  507. data/lib/locomotive/presentable.rb +212 -0
  508. data/lib/locomotive/rails.rb +1 -0
  509. data/lib/locomotive/rails/action_view.rb +9 -0
  510. data/lib/locomotive/regexps.rb +11 -0
  511. data/lib/locomotive/render.rb +177 -0
  512. data/lib/locomotive/routing.rb +2 -0
  513. data/lib/locomotive/routing/default_constraint.rb +42 -0
  514. data/lib/locomotive/routing/site_dispatcher.rb +54 -0
  515. data/lib/locomotive/session_store.rb +64 -0
  516. data/lib/locomotive/version.rb +3 -0
  517. data/lib/locomotive_cms.rb +1 -0
  518. data/lib/tasks/cucumber.rake +66 -0
  519. data/lib/tasks/locomotive.rake +220 -0
  520. data/public/favicon.ico +0 -0
  521. data/vendor/assets/fonts/locomotive/fontawesome-webfont.eot +0 -0
  522. data/vendor/assets/fonts/locomotive/fontawesome-webfont.svg +255 -0
  523. data/vendor/assets/fonts/locomotive/fontawesome-webfont.ttf +0 -0
  524. data/vendor/assets/fonts/locomotive/fontawesome-webfont.woff +0 -0
  525. data/vendor/assets/javascripts/locomotive/ICanHandlebarz.js +88 -0
  526. data/vendor/assets/javascripts/locomotive/backbone.modelbinding.js +565 -0
  527. data/vendor/assets/javascripts/locomotive/backbone.sync.js +113 -0
  528. data/vendor/assets/javascripts/locomotive/cmd.js +31 -0
  529. data/vendor/assets/javascripts/locomotive/cookies.js +96 -0
  530. data/vendor/assets/javascripts/locomotive/datepicker_i18n.js.erb +28 -0
  531. data/vendor/assets/javascripts/locomotive/editable_field.js +50 -0
  532. data/vendor/assets/javascripts/locomotive/form_submit_notification.js +39 -0
  533. data/vendor/assets/javascripts/locomotive/growl.js +143 -0
  534. data/vendor/assets/javascripts/locomotive/handlebars.js +1493 -0
  535. data/vendor/assets/javascripts/locomotive/liquid_mode.js +42 -0
  536. data/vendor/assets/javascripts/locomotive/menu_toggler.js +37 -0
  537. data/vendor/assets/javascripts/locomotive/resize.js +9 -0
  538. data/vendor/assets/javascripts/locomotive/slugify.js +31 -0
  539. data/vendor/assets/javascripts/locomotive/smartupdater.js +296 -0
  540. data/vendor/assets/javascripts/locomotive/subscribe.js +367 -0
  541. data/vendor/assets/javascripts/locomotive/toggle.js +143 -0
  542. data/vendor/assets/javascripts/locomotive/vendor.js +1 -0
  543. data/vendor/assets/stylesheets/locomotive/blueprint/ie.css +26 -0
  544. data/vendor/assets/stylesheets/locomotive/blueprint/print.css +30 -0
  545. data/vendor/assets/stylesheets/locomotive/blueprint/screen.css +253 -0
  546. data/vendor/assets/stylesheets/locomotive/font-awesome.scss +329 -0
  547. data/vendor/assets/stylesheets/locomotive/jquery.css +3 -0
  548. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  549. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  550. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  551. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  552. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  553. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  554. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  555. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  556. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_222222_256x240.png +0 -0
  557. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_2e83ff_256x240.png +0 -0
  558. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_454545_256x240.png +0 -0
  559. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_888888_256x240.png +0 -0
  560. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_cd0a0a_256x240.png +0 -0
  561. data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_ffffff_256x240.png +0 -0
  562. data/vendor/assets/stylesheets/locomotive/jquery/ui.css +406 -0
  563. data/vendor/assets/stylesheets/locomotive/liquid_mode.css +7 -0
  564. data/vendor/assets/stylesheets/locomotive/toggle.css.scss +75 -0
  565. metadata +1171 -0
@@ -0,0 +1,62 @@
1
+ module Locomotive
2
+ module Extensions
3
+ module ContentType
4
+ module Sync
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ after_save :sync_relationships_order_by
10
+ end
11
+
12
+ protected
13
+
14
+ # If the user changes the order of the content type, we have to make
15
+ # sure that other related content types tied to the current one through
16
+ # a belongs_to / has_many relationship also gets updated.
17
+ #
18
+ def sync_relationships_order_by
19
+ current_class_name = self.klass_with_custom_fields(:entries).name
20
+
21
+ self.entries_custom_fields.where(:type => 'belongs_to').each do |field|
22
+ target_content_type = self.class_name_to_content_type(field.class_name)
23
+
24
+ operations = { '$set' => {} }
25
+
26
+ target_content_type.entries_custom_fields.where(:type.in => %w(has_many many_to_many), :ui_enabled => false, :class_name => current_class_name).each do |target_field|
27
+ if target_field.order_by != self.order_by_definition
28
+ target_field.order_by = self.order_by_definition # needed by the custom_fields_recipe_for method in order to be up to date
29
+
30
+ operations['$set']["entries_custom_fields.#{target_field._index}.order_by"] = self.order_by_definition
31
+ end
32
+ end
33
+
34
+ unless operations['$set'].empty?
35
+ persist_content_type_changes target_content_type, operations
36
+ end
37
+ end
38
+ end
39
+
40
+ # Save the changes for the content type passed in parameter without forgetting
41
+ # to bump the version.. It also updates the recipe for related entries.
42
+ # That method does not call the Mongoid API but directly MongoDB.
43
+ #
44
+ # @param [ ContentType ] content_type The content type to update
45
+ # @param [ Hash ] operations The MongoDB atomic operations
46
+ #
47
+ def persist_content_type_changes(content_type, operations)
48
+ content_type.entries_custom_fields_version += 1
49
+
50
+ operations['$set']['entries_custom_fields_version'] = content_type.entries_custom_fields_version
51
+
52
+ self.collection.update({ '_id' => content_type._id }, operations)
53
+
54
+ collection, selector = content_type.entries.collection, content_type.entries.criteria.selector
55
+
56
+ collection.update selector, { '$set' => { 'custom_fields_recipe' => content_type.custom_fields_recipe_for(:entries) } }, :multi => true
57
+ end
58
+
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,105 @@
1
+ module Locomotive
2
+ module Extensions
3
+ module Page
4
+ module EditableElements
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ embeds_many :editable_elements, :class_name => 'Locomotive::EditableElement', :cascade_callbacks => true
10
+
11
+ after_save :remove_disabled_editable_elements
12
+
13
+ accepts_nested_attributes_for :editable_elements
14
+ end
15
+
16
+ def disable_parent_editable_elements(block)
17
+ Rails.logger.debug "[disable_parent_editable_elements] #{block.inspect}"
18
+ self.editable_elements.each { |el| el.disabled = true if el.from_parent? && el.block == block }
19
+ end
20
+
21
+ def disable_all_editable_elements
22
+ self.editable_elements.each { |el| el.disabled = true }
23
+ end
24
+
25
+ def editable_element_blocks
26
+ self.editable_elements.collect(&:block)
27
+ end
28
+
29
+ def enabled_editable_elements
30
+ self.editable_elements.by_priority.find_all(&:editable?)
31
+ end
32
+
33
+ def editable_elements_grouped_by_blocks
34
+ groups = self.enabled_editable_elements.group_by(&:block)
35
+ groups.delete_if { |block, elements| elements.empty? }
36
+ end
37
+
38
+ def find_editable_elements(block)
39
+ self.editable_elements.find_all { |el| el.block == block }
40
+ end
41
+
42
+ def find_editable_element(block, slug)
43
+ self.editable_elements.detect { |el| el.block == block && el.slug == slug }
44
+ end
45
+
46
+ def find_editable_files
47
+ self.editable_elements.find_all { |el| el.respond_to?(:source) }
48
+ end
49
+
50
+ def add_or_update_editable_element(attributes, type)
51
+ element = self.find_editable_element(attributes[:block], attributes[:slug])
52
+
53
+ if element
54
+ element.copy_attributes(attributes)
55
+ else
56
+ element = self.editable_elements.build(attributes, type)
57
+ end
58
+
59
+ element.add_current_locale
60
+
61
+ element
62
+ end
63
+
64
+ def enable_editable_elements(block)
65
+ Rails.logger.debug "[enable_editable_elements] #{block.inspect}"
66
+ self.editable_elements.each { |el| el.disabled = false if el.block == block }
67
+ end
68
+
69
+ def merge_editable_elements_from_page(source)
70
+ source.editable_elements.each do |el|
71
+ next if el.disabled?
72
+
73
+ existing_el = self.find_editable_element(el.block, el.slug)
74
+
75
+ if existing_el.nil? # new one from parents
76
+ new_el = self.editable_elements.build({}, el.class)
77
+ new_el.copy_attributes_from(el)
78
+ else
79
+ existing_el.disabled = false
80
+
81
+ # make sure the default content gets updated too
82
+ existing_el.set_default_content_from(el)
83
+
84
+ # only the type, hint and fixed properties can be modified from the parent element
85
+ %w(_type hint fixed priority).each do |attr|
86
+ existing_el.send(:"#{attr}=", el.send(attr.to_sym))
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ def remove_disabled_editable_elements
93
+ # get only those which are fully disabled, meaning in ALL the locales
94
+ ids = self.editable_elements.find_all { |el| el.disabled_in_all_translations? }.map(&:_id)
95
+
96
+ return if ids.empty?
97
+
98
+ # super fast way to remove useless elements all in once
99
+ self.collection.update(self.atomic_selector, '$pull' => { 'editable_elements' => { '_id' => { '$in' => ids } } })
100
+ end
101
+
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,18 @@
1
+ module Locomotive
2
+ module Extensions
3
+ module Page
4
+ module Listed
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ ## fields ##
11
+ field :listed, :type => Boolean, :default => true
12
+
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,125 @@
1
+ module Locomotive
2
+ module Extensions
3
+ module Page
4
+ module Parse
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ ## fields ##
10
+ field :serialized_template, :type => Binary, :localize => true
11
+ field :template_dependencies, :type => Array, :default => [], :localize => true
12
+ field :snippet_dependencies, :type => Array, :default => [], :localize => true
13
+
14
+ ## virtual attributes
15
+ attr_reader :template_changed
16
+
17
+ ## callbacks ##
18
+ before_validation :serialize_template
19
+ after_save :update_template_descendants
20
+
21
+ ## validations ##
22
+ validate :template_must_be_valid
23
+
24
+ ## scopes ##
25
+ scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
26
+ end
27
+
28
+ def template
29
+ @template ||= Marshal.load(self.serialized_template.to_s) rescue nil
30
+ end
31
+
32
+ def force_serialize_template
33
+ self.serialize_template
34
+ @done_serialize_template = true
35
+ end
36
+
37
+ protected
38
+
39
+ def serialize_template
40
+ if !@done_serialize_template &&
41
+ (self.new_record? || self.raw_template_changed?)
42
+ @template_changed = true
43
+
44
+ @parsing_errors = []
45
+
46
+ begin
47
+ self._parse_and_serialize_template
48
+ rescue ::Liquid::SyntaxError => error
49
+ @parsing_errors << I18n.t(:liquid_syntax, :fullpath => self.fullpath, :error => error.to_s, :scope => [:errors, :messages, :page])
50
+ rescue ::Locomotive::Liquid::PageNotFound => error
51
+ @parsing_errors << I18n.t(:liquid_extend, :fullpath => self.fullpath, :scope => [:errors, :messages, :page])
52
+ rescue ::Locomotive::Liquid::PageNotTranslated => error
53
+ @parsing_errors << I18n.t(:liquid_translation, :fullpath => self.fullpath, :scope => [:errors, :messages, :page])
54
+ end
55
+ end
56
+ end
57
+
58
+ def _parse_and_serialize_template(context = {})
59
+ self.parse(context)
60
+ self._serialize_template
61
+ end
62
+
63
+ def _serialize_template
64
+ self.serialized_template = BSON::Binary.new(Marshal.dump(@template))
65
+ end
66
+
67
+ def parse(context = {})
68
+ self.disable_all_editable_elements
69
+
70
+ default_context = { :site => self.site, :page => self, :templates => [], :snippets => [] }
71
+
72
+ context = default_context.merge(context)
73
+
74
+ @template = ::Liquid::Template.parse(self.raw_template, context)
75
+
76
+ self.template_dependencies = context[:templates]
77
+ self.snippet_dependencies = context[:snippets]
78
+
79
+ @template.root.context.clear
80
+ end
81
+
82
+ def template_must_be_valid
83
+ @parsing_errors.try(:each) do |msg|
84
+ self.errors.add :template, msg
85
+ self.errors.add :raw_template, msg
86
+ end
87
+ end
88
+
89
+ def update_template_descendants
90
+ return unless @template_changed == true
91
+
92
+ # we admit at this point that the current template is up-to-date
93
+ template_descendants = self.site.pages.any_in("template_dependencies.#{::Mongoid::Fields::I18n.locale}" => [self.id]).to_a
94
+
95
+ # group them by fullpath for better performance
96
+ cached = template_descendants.inject({}) { |memo, page| memo[page.fullpath] = page; memo }
97
+
98
+ self._update_direct_template_descendants(template_descendants.clone, cached)
99
+
100
+ # finally save them all
101
+ ::Locomotive::Page.without_callback(:save, :after, :update_template_descendants) do
102
+ template_descendants.each do |page|
103
+ page.save(:validate => false)
104
+ end
105
+ end
106
+ end
107
+
108
+ def _update_direct_template_descendants(template_descendants, cached)
109
+ direct_descendants = template_descendants.select do |page|
110
+ ((self.template_dependencies || []) + [self._id]) == (page.template_dependencies || [])
111
+ end
112
+
113
+ direct_descendants.each do |page|
114
+ page.send(:_parse_and_serialize_template, { :cached_parent => self, :cached_pages => cached })
115
+
116
+ template_descendants.delete(page) # no need to loop over it next time
117
+
118
+ page.send(:_update_direct_template_descendants, template_descendants, cached) # move down
119
+ end
120
+ end
121
+
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,25 @@
1
+ module Locomotive
2
+ module Extensions
3
+ module Page
4
+ module Redirect
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ ## fields ##
11
+ field :redirect, :type => Boolean, :default => false
12
+ field :redirect_url, :type => String, :localize => true
13
+ field :redirect_type, :type => Integer, :default => 301
14
+
15
+ ## validations ##
16
+ validates_presence_of :redirect_type, :if => :redirect?
17
+ validates_presence_of :redirect_url, :if => :redirect?
18
+ validates_format_of :redirect_url, :with => Locomotive::Regexps::URL, :allow_blank => true
19
+
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,93 @@
1
+ module Locomotive
2
+ module Extensions
3
+ module Page
4
+ module Render
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ def render(context)
9
+ self.template.render(context)
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ # Given both a site and a path, this method tries
15
+ # to get the matching page.
16
+ # If the page is templatized, the related content entry is
17
+ # associated to the page (page.content_entry stores the entry).
18
+ # If no page is found, then it returns the 404 one instead.
19
+ #
20
+ # @param [ Site ] site The site where to find the page
21
+ # @param [ String ] path The fullpath got from the request
22
+ # @param [ Boolean ] logged_in True if someone is logged in Locomotive
23
+ #
24
+ # @return [ Page ] The page matching the criteria OR the 404 one if none
25
+ #
26
+ def fetch_page_from_path(site, path, logged_in)
27
+ page = nil
28
+ depth = path == 'index' ? 0 : path.split('/').size
29
+
30
+ matching_paths = path == 'index' ? %w(index) : path_combinations(path)
31
+
32
+ site.pages.where(:depth => depth, :fullpath.in => matching_paths).each do |_page|
33
+ if !_page.published? && !logged_in
34
+ next
35
+ else
36
+ if _page.templatized?
37
+ %r(^#{_page.fullpath.gsub('content_type_template', '([^\/]+)')}$) =~ path
38
+
39
+ permalink = $1
40
+
41
+ _page.content_entry = _page.fetch_target_entry(permalink)
42
+
43
+ if _page.content_entry.nil? || (!_page.content_entry.visible? && !logged_in) # content instance not found or not visible
44
+ next
45
+ end
46
+ end
47
+ end
48
+
49
+ page = _page
50
+
51
+ break
52
+ end
53
+
54
+ page || site.pages.not_found.published.first
55
+ end
56
+
57
+ # Calculate all the combinations possible based on the
58
+ # fact that one of the segment of the path could be
59
+ # a content type from a templatized page.
60
+ # We postulate that there is only one templatized page in a path
61
+ # (ie: no nested templatized pages)
62
+ #
63
+ # @param [ String ] path The path to the page
64
+ #
65
+ # @return [ Array ] An array of all the combinations
66
+ #
67
+ def path_combinations(path)
68
+ _path_combinations(path.split('/'))
69
+ end
70
+
71
+ #:nodoc:
72
+ def _path_combinations(segments, can_include_template = true)
73
+ return nil if segments.empty?
74
+
75
+ segment = segments.shift
76
+
77
+ (can_include_template ? [segment, 'content_type_template'] : [segment]).map do |_segment|
78
+ if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != 'content_type_template'))
79
+ [*_combinations].map do |_combination|
80
+ File.join(_segment, _combination)
81
+ end
82
+ else
83
+ [_segment]
84
+ end
85
+ end.flatten
86
+ end
87
+
88
+ end
89
+
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,163 @@
1
+ module Locomotive
2
+ module Extensions
3
+ module Page
4
+ module Templatized
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ ## fields ##
11
+ field :templatized, :type => Boolean, :default => false
12
+ field :templatized_from_parent, :type => Boolean, :default => false
13
+ field :target_klass_name
14
+
15
+ ## validations ##
16
+ validates_presence_of :target_klass_name, :if => :templatized?
17
+ validate :ensure_target_klass_name_security
18
+
19
+ ## callbacks ##
20
+ before_validation :get_templatized_from_parent
21
+ before_validation :set_slug_if_templatized
22
+ before_validation :ensure_target_klass_name_security
23
+ after_save :propagate_templatized
24
+
25
+ ## scopes ##
26
+ scope :templatized, :where => { :templatized => true }
27
+
28
+ ## virtual attributes ##
29
+ attr_accessor :content_entry
30
+ end
31
+
32
+ # Return the class specified by the target_klass_name property
33
+ #
34
+ # @example
35
+ #
36
+ # page.target_klass_name = 'Locomotive::Entry12345'
37
+ # page.target_klass # <Locomotive::Entry12345...>
38
+ #
39
+ # @return [ Class ] The target class
40
+ #
41
+ def target_klass
42
+ target_klass_name.constantize
43
+ end
44
+
45
+ # Return the slug related to the target_klass.
46
+ # In other words, it returns the slug of the target content type.
47
+ #
48
+ # @return [ String ] The slug of the target class / content type. Nil if no target klass.
49
+ #
50
+ def target_klass_slug
51
+ if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
52
+ @content_type ||= self.site.content_types.find($1)
53
+ @content_type.slug
54
+ else
55
+ nil
56
+ end
57
+ end
58
+
59
+ # Set the target klass from the slug of a content type
60
+ #
61
+ # @param [ String ] slug The slug of the content type
62
+ #
63
+ # @return [ Object ] The content type or nil if not found
64
+ #
65
+ def target_klass_slug=(slug)
66
+ if @content_type = self.site.content_types.where(:slug => slug).first
67
+ self.target_klass_name = @content_type.entries_class_name
68
+ end
69
+ @content_type
70
+ end
71
+
72
+ # Give the name which can be used in a liquid template in order
73
+ # to reference an entry. It uses the slug property if the target klass
74
+ # is a Locomotive content type or the class name itself for the other classes.
75
+ #
76
+ # @example
77
+ #
78
+ # page.target_klass_name = 'Locomotive::Entry12345' # related to the content type Articles
79
+ # page.target_entry_name = 'article'
80
+ #
81
+ # page.target_klass_name = 'OurProduct'
82
+ # page.target_entry_name = 'our_product'
83
+ #
84
+ # @return [ String ] The name in lowercase and underscored
85
+ #
86
+ def target_entry_name
87
+ if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
88
+ @content_type ||= self.site.content_types.find($1)
89
+ @content_type.slug.singularize
90
+ else
91
+ self.target_klass_name.underscore
92
+ end
93
+ end
94
+
95
+ # Find the entry both specified by the target klass and identified by the permalink
96
+ #
97
+ # @param [ String ] permalink The permalink of the entry
98
+ #
99
+ # @return [ Object ] The document
100
+ #
101
+ def fetch_target_entry(permalink)
102
+ target_klass.find_by_permalink(permalink)
103
+ end
104
+
105
+ protected
106
+
107
+ def get_templatized_from_parent
108
+ return if self.parent.nil?
109
+
110
+ if self.parent.templatized?
111
+ self.templatized = self.templatized_from_parent = true
112
+ self.target_klass_name = self.parent.target_klass_name
113
+ elsif !self.templatized?
114
+ self.templatized = self.templatized_from_parent = false
115
+ self.target_klass_name = nil
116
+ end
117
+ end
118
+
119
+ def set_slug_if_templatized
120
+ self.slug = 'content_type_template' if self.templatized? && !self.templatized_from_parent?
121
+ end
122
+
123
+ # Make sure the target_klass is owned by the site OR
124
+ # if it belongs to the models allowed by the application
125
+ # thanks to the models_for_templatization option.
126
+ #
127
+ def ensure_target_klass_name_security
128
+ return if !self.templatized? || self.target_klass_name.blank?
129
+
130
+ if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
131
+ content_type = Locomotive::ContentType.find($1)
132
+
133
+ if content_type.site_id != self.site_id
134
+ self.errors.add :target_klass_name, :security
135
+ end
136
+ elsif !Locomotive.config.models_for_templatization.include?(self.target_klass_name)
137
+ self.errors.add :target_klass_name, :security
138
+ end
139
+ end
140
+
141
+ # Set the templatized, templatized_from_parent properties of
142
+ # the children of the current page ONLY IF the templatized
143
+ # attribute got changed.
144
+ #
145
+ def propagate_templatized
146
+ return unless self.templatized_changed?
147
+
148
+ selector = { 'parent_ids' => { '$in' => [self._id] } }
149
+ operations = {
150
+ '$set' => {
151
+ 'templatized' => self.templatized,
152
+ 'templatized_from_parent' => self.templatized,
153
+ 'target_klass_name' => self.target_klass_name
154
+ }
155
+ }
156
+
157
+ self.collection.update selector, operations, :multi => true
158
+ end
159
+
160
+ end
161
+ end
162
+ end
163
+ end