dm_cms 4.2.1.5

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 (298) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.md +31 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/dm_cms/admin.js +58 -0
  6. data/app/assets/javascripts/dm_cms/application.js +16 -0
  7. data/app/assets/stylesheets/dm_cms/admin.css +3 -0
  8. data/app/assets/stylesheets/dm_cms/application.css +13 -0
  9. data/app/controllers/dm_cms/admin/admin_controller.rb +14 -0
  10. data/app/controllers/dm_cms/admin/cms_blogs_controller.rb +89 -0
  11. data/app/controllers/dm_cms/admin/cms_contentitems_controller.rb +96 -0
  12. data/app/controllers/dm_cms/admin/cms_pages_controller.rb +100 -0
  13. data/app/controllers/dm_cms/admin/cms_posts_controller.rb +67 -0
  14. data/app/controllers/dm_cms/admin/cms_snippets_controller.rb +73 -0
  15. data/app/controllers/dm_cms/admin/dashboard_controller.rb +12 -0
  16. data/app/controllers/dm_cms/admin/media_files_controller.rb +80 -0
  17. data/app/controllers/dm_cms/application_controller.rb +9 -0
  18. data/app/controllers/dm_cms/blogs_controller.rb +50 -0
  19. data/app/controllers/dm_cms/comments_controller.rb +3 -0
  20. data/app/controllers/dm_cms/contact_form_controller.rb +27 -0
  21. data/app/controllers/dm_cms/pages_controller.rb +67 -0
  22. data/app/controllers/dm_cms/posts_controller.rb +69 -0
  23. data/app/datatables/blog_user_datatable.rb +79 -0
  24. data/app/helpers/dm_cms/analytics_helper.rb +27 -0
  25. data/app/helpers/dm_cms/application_helper.rb +4 -0
  26. data/app/helpers/dm_cms/cms_contentitems_helper.rb +8 -0
  27. data/app/helpers/dm_cms/cms_pages_helper.rb +30 -0
  28. data/app/helpers/dm_cms/pages_helper.rb +204 -0
  29. data/app/helpers/dm_cms/posts_helper.rb +26 -0
  30. data/app/helpers/dm_cms/render_helper.rb +50 -0
  31. data/app/inputs/media_input.rb +17 -0
  32. data/app/liquid/tags/markdown.rb +30 -0
  33. data/app/mailers/post_notify_mailer.rb +36 -0
  34. data/app/models/cms_blog.rb +89 -0
  35. data/app/models/cms_contentitem.rb +76 -0
  36. data/app/models/cms_page.rb +227 -0
  37. data/app/models/cms_post.rb +76 -0
  38. data/app/models/cms_snippet.rb +42 -0
  39. data/app/models/contact_form.rb +28 -0
  40. data/app/models/dm_cms/concerns/ability.rb +54 -0
  41. data/app/models/dm_cms/permitted_params.rb +34 -0
  42. data/app/models/media_file.rb +102 -0
  43. data/app/presenters/cms_blog_presenter.rb +15 -0
  44. data/app/presenters/cms_page_presenter.rb +23 -0
  45. data/app/presenters/cms_post_presenter.rb +11 -0
  46. data/app/presenters/cms_snippet_presenter.rb +10 -0
  47. data/app/uploaders/media_uploader.rb +169 -0
  48. data/app/views/customized/analytics/_google_analytics.html.erb +11 -0
  49. data/app/views/dm_cms/admin/cms_blogs/_form.html.erb +34 -0
  50. data/app/views/dm_cms/admin/cms_blogs/edit.html.erb +2 -0
  51. data/app/views/dm_cms/admin/cms_blogs/index.html.erb +44 -0
  52. data/app/views/dm_cms/admin/cms_blogs/new.html.erb +2 -0
  53. data/app/views/dm_cms/admin/cms_blogs/show.html.erb +167 -0
  54. data/app/views/dm_cms/admin/cms_contentitems/_form.html.erb +43 -0
  55. data/app/views/dm_cms/admin/cms_contentitems/_form_dialog.html.erb +17 -0
  56. data/app/views/dm_cms/admin/cms_contentitems/edit.html.erb +1 -0
  57. data/app/views/dm_cms/admin/cms_contentitems/markdown.html.erb +21 -0
  58. data/app/views/dm_cms/admin/cms_contentitems/new_content.html.erb +1 -0
  59. data/app/views/dm_cms/admin/cms_pages/_content_toolbar.html.erb +11 -0
  60. data/app/views/dm_cms/admin/cms_pages/_form.html.erb +50 -0
  61. data/app/views/dm_cms/admin/cms_pages/_tree.html.erb +20 -0
  62. data/app/views/dm_cms/admin/cms_pages/_tree_sidebar.html.erb +8 -0
  63. data/app/views/dm_cms/admin/cms_pages/edit.html.erb +2 -0
  64. data/app/views/dm_cms/admin/cms_pages/index.html.erb +32 -0
  65. data/app/views/dm_cms/admin/cms_pages/new_page.html.erb +2 -0
  66. data/app/views/dm_cms/admin/cms_pages/show.html.erb +54 -0
  67. data/app/views/dm_cms/admin/cms_posts/_form.html.erb +59 -0
  68. data/app/views/dm_cms/admin/cms_posts/edit.html.erb +2 -0
  69. data/app/views/dm_cms/admin/cms_posts/new.html.erb +1 -0
  70. data/app/views/dm_cms/admin/cms_snippets/_form.html.erb +28 -0
  71. data/app/views/dm_cms/admin/cms_snippets/edit.html.erb +1 -0
  72. data/app/views/dm_cms/admin/cms_snippets/index.html.erb +29 -0
  73. data/app/views/dm_cms/admin/cms_snippets/new.html.erb +1 -0
  74. data/app/views/dm_cms/admin/dashboard/_widget_blog_comments.html.erb +37 -0
  75. data/app/views/dm_cms/admin/dashboard/widget_blog_comments.js.erb +1 -0
  76. data/app/views/dm_cms/admin/media_files/_form.html.erb +102 -0
  77. data/app/views/dm_cms/admin/media_files/edit.html.erb +3 -0
  78. data/app/views/dm_cms/admin/media_files/index.html.erb +98 -0
  79. data/app/views/dm_cms/admin/media_files/new.html.erb +3 -0
  80. data/app/views/dm_cms/admin/shared/_liquid_tags_ref.html.erb +35 -0
  81. data/app/views/dm_cms/blogs/show.html.erb +0 -0
  82. data/app/views/dm_cms/blogs/toggle_follow.js.coffee +5 -0
  83. data/app/views/dm_cms/contact_form/create.html.erb +2 -0
  84. data/app/views/dm_cms/contact_form/create.js.erb +2 -0
  85. data/app/views/dm_cms/pages/_content_fragment.html.erb +13 -0
  86. data/app/views/dm_cms/pages/_snippet_fragment.html.erb +12 -0
  87. data/app/views/dm_cms/pages/coming_soon.html.erb +2 -0
  88. data/app/views/dm_cms/pages/show.html.erb +0 -0
  89. data/app/views/dm_cms/posts/show.html.erb +0 -0
  90. data/app/views/dm_cms/shared/_comment.html.erb +22 -0
  91. data/app/views/dm_cms/shared/_comment_form.html.erb +16 -0
  92. data/app/views/dm_cms/shared/_comment_list.html.erb +11 -0
  93. data/app/views/dm_cms/shared/_social_buttons.html.erb +6 -0
  94. data/app/views/layouts/email_templates/dm_cms_email_layout.html.erb +320 -0
  95. data/app/views/layouts/email_templates/dm_cms_email_layout.text.erb +1 -0
  96. data/app/views/layouts/email_templates/dm_cms_post_notify.html.erb +13 -0
  97. data/app/views/layouts/email_templates/dm_cms_post_notify.text.erb +9 -0
  98. data/app/views/liquid_tags/_contact_form.html.erb +17 -0
  99. data/config/initializers/liquid_init.rb +2 -0
  100. data/config/locales/cms.cs.yml +42 -0
  101. data/config/locales/cms.de.yml +42 -0
  102. data/config/locales/cms.en.yml +42 -0
  103. data/config/locales/cms.fi.yml +42 -0
  104. data/config/locales/cms.ja.yml +42 -0
  105. data/config/routes.rb +70 -0
  106. data/db/migrate/20121103181909_create_cms.rb +91 -0
  107. data/db/migrate/20130206213720_add_account_to_cms.rb +10 -0
  108. data/db/migrate/20130507123255_create_blog.rb +61 -0
  109. data/db/migrate/20130531212537_add_notification_sent.rb +5 -0
  110. data/db/migrate/20130605184116_add_blog_comment.rb +7 -0
  111. data/db/migrate/20131128201053_add_blog_image.rb +5 -0
  112. data/db/migrate/20140217135228_rename_snippet_slug.rb +13 -0
  113. data/db/migrate/20140303121217_add_requires_subscription_blog.rb +7 -0
  114. data/db/migrate/20140328205246_add_pages_ranked_model.rb +22 -0
  115. data/db/migrate/20140423113417_add_blog_owner.rb +6 -0
  116. data/db/migrate/20140428122156_create_media_files.rb +29 -0
  117. data/db/migrate/20140523134543_add_cmspage_summary.rb +6 -0
  118. data/db/migrate/20140601151631_add_blog_image_email_header.rb +5 -0
  119. data/db/migrate/20141004154725_add_header_image.rb +9 -0
  120. data/db/migrate/20160821150108_index_foreign_keys_in_cms_blogs.rb +6 -0
  121. data/db/migrate/20160821150109_index_foreign_keys_in_cms_media_files.rb +6 -0
  122. data/db/migrate/20160821150110_index_foreign_keys_in_cms_posts.rb +6 -0
  123. data/lib/dm_cms.rb +4 -0
  124. data/lib/dm_cms/engine.rb +16 -0
  125. data/lib/dm_cms/liquid/filters/liquid_filters.rb +11 -0
  126. data/lib/dm_cms/liquid/tags/contact_form.rb +35 -0
  127. data/lib/dm_cms/liquid/tags/div.rb +42 -0
  128. data/lib/dm_cms/liquid/tags/image.rb +76 -0
  129. data/lib/dm_cms/liquid/tags/quote.rb +38 -0
  130. data/lib/dm_cms/liquid/tags/snippet.rb +37 -0
  131. data/lib/dm_cms/liquid/tags/url_asset.rb +41 -0
  132. data/lib/dm_cms/liquid/tags/url_media.rb +42 -0
  133. data/lib/dm_cms/liquid/tags/url_protected.rb +31 -0
  134. data/lib/tasks/dm_cms_tasks.rake +4 -0
  135. data/spec/controllers/admin/cms_blogs_controller_spec.rb +173 -0
  136. data/spec/controllers/admin/cms_pages_controller_spec.rb +182 -0
  137. data/spec/controllers/admin/cms_posts_controller_spec.rb +166 -0
  138. data/spec/dummy/README.rdoc +28 -0
  139. data/spec/dummy/Rakefile +6 -0
  140. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  141. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  142. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  143. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  144. data/spec/dummy/app/models/ability.rb +12 -0
  145. data/spec/dummy/app/models/user.rb +6 -0
  146. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  147. data/spec/dummy/bin/bundle +3 -0
  148. data/spec/dummy/bin/rails +4 -0
  149. data/spec/dummy/bin/rake +4 -0
  150. data/spec/dummy/config.ru +4 -0
  151. data/spec/dummy/config/application.rb +26 -0
  152. data/spec/dummy/config/boot.rb +5 -0
  153. data/spec/dummy/config/database.yml +25 -0
  154. data/spec/dummy/config/environment.rb +5 -0
  155. data/spec/dummy/config/environments/development.rb +37 -0
  156. data/spec/dummy/config/environments/production.rb +82 -0
  157. data/spec/dummy/config/environments/test.rb +39 -0
  158. data/spec/dummy/config/initializers/_themes_for_rails.rb +39 -0
  159. data/spec/dummy/config/initializers/account_initialization.rb +28 -0
  160. data/spec/dummy/config/initializers/assets.rb +8 -0
  161. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  162. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  163. data/spec/dummy/config/initializers/dm_core.rb +6 -0
  164. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  165. data/spec/dummy/config/initializers/inflections.rb +16 -0
  166. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  167. data/spec/dummy/config/initializers/session_store.rb +3 -0
  168. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  169. data/spec/dummy/config/locales/en.yml +23 -0
  170. data/spec/dummy/config/routes.rb +19 -0
  171. data/spec/dummy/config/secrets.yml +22 -0
  172. data/spec/dummy/db/development.sqlite3 +0 -0
  173. data/spec/dummy/db/migrate/20141114170927_add_globalize_countries.dm_core.rb +50 -0
  174. data/spec/dummy/db/migrate/20141114170928_devise_create_users.dm_core.rb +46 -0
  175. data/spec/dummy/db/migrate/20141114170929_add_user_fields.dm_core.rb +14 -0
  176. data/spec/dummy/db/migrate/20141114170930_rolify_create_roles.dm_core.rb +20 -0
  177. data/spec/dummy/db/migrate/20141114170931_add_last_access.dm_core.rb +10 -0
  178. data/spec/dummy/db/migrate/20141114170932_create_versions.dm_core.rb +19 -0
  179. data/spec/dummy/db/migrate/20141114170933_add_object_changes_column_to_versions.dm_core.rb +12 -0
  180. data/spec/dummy/db/migrate/20141114170934_create_dm_core_accounts.dm_core.rb +13 -0
  181. data/spec/dummy/db/migrate/20141114170935_add_account_to_users.dm_core.rb +9 -0
  182. data/spec/dummy/db/migrate/20141114170936_create_preferences.dm_core.rb +13 -0
  183. data/spec/dummy/db/migrate/20141114170937_create_comments.dm_core.rb +22 -0
  184. data/spec/dummy/db/migrate/20141114170938_add_activity.dm_core.rb +21 -0
  185. data/spec/dummy/db/migrate/20141114170939_add_type_to_comments.dm_core.rb +9 -0
  186. data/spec/dummy/db/migrate/20141114170940_add_category.dm_core.rb +28 -0
  187. data/spec/dummy/db/migrate/20141114170941_create_email_table.dm_core.rb +26 -0
  188. data/spec/dummy/db/migrate/20141114170942_add_user_profile.dm_core.rb +46 -0
  189. data/spec/dummy/db/migrate/20141114170943_add_profile_email.dm_core.rb +14 -0
  190. data/spec/dummy/db/migrate/20141114170944_create_payment_history.dm_core.rb +37 -0
  191. data/spec/dummy/db/migrate/20141114170945_change_anchor_field.dm_core.rb +10 -0
  192. data/spec/dummy/db/migrate/20141114170946_create_user_site_profile.dm_core.rb +27 -0
  193. data/spec/dummy/db/migrate/20141114170947_add_avatar.dm_core.rb +12 -0
  194. data/spec/dummy/db/migrate/20141114170948_add_notify_to_payment_history.dm_core.rb +8 -0
  195. data/spec/dummy/db/migrate/20141114170949_acts_as_votable_migration.dm_core.rb +28 -0
  196. data/spec/dummy/db/migrate/20141114170950_add_user_site_profile_uuid.dm_core.rb +19 -0
  197. data/spec/dummy/db/migrate/20141114170951_add_invoice_id.dm_core.rb +7 -0
  198. data/spec/dummy/db/migrate/20141114170952_acts_as_follower_migration.dm_core.rb +18 -0
  199. data/spec/dummy/db/migrate/20141114170953_rename_invoice_id.dm_core.rb +12 -0
  200. data/spec/dummy/db/migrate/20141114170954_add_core_addresses.dm_core.rb +18 -0
  201. data/spec/dummy/db/migrate/20141114170955_papertrail_increase_column.dm_core.rb +9 -0
  202. data/spec/dummy/db/migrate/20141114170956_acts_as_taggable_on_migration.dm_core.rb +32 -0
  203. data/spec/dummy/db/migrate/20141114170957_add_missing_unique_indices.dm_core.rb +23 -0
  204. data/spec/dummy/db/migrate/20141114170958_add_taggings_counter_cache_to_tags.dm_core.rb +16 -0
  205. data/spec/dummy/db/migrate/20141114170959_create_custom_fields.dm_core.rb +40 -0
  206. data/spec/dummy/db/migrate/20141114170960_add_missing_taggable_index.dm_core.rb +11 -0
  207. data/spec/dummy/db/migrate/20141114170961_create_documents.dm_knowledge.rb +19 -0
  208. data/spec/dummy/db/migrate/20141114170962_add_document_notes.dm_knowledge.rb +7 -0
  209. data/spec/dummy/db/migrate/20160128134522_add_favored_locale.dm_core.rb +17 -0
  210. data/spec/dummy/db/migrate/20160128134523_update_papertrail_v4.dm_core.rb +41 -0
  211. data/spec/dummy/db/schema.rb +590 -0
  212. data/spec/dummy/db/seeds.rb +18 -0
  213. data/spec/dummy/public/404.html +67 -0
  214. data/spec/dummy/public/422.html +67 -0
  215. data/spec/dummy/public/500.html +66 -0
  216. data/spec/dummy/public/favicon.ico +0 -0
  217. data/spec/dummy/themes/_mbus/_readme.md +6 -0
  218. data/spec/dummy/themes/_mbus/_theme.yml +21 -0
  219. data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/application.js +9 -0
  220. data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/bootstrap.js +2114 -0
  221. data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/bootstrap.min.js +6 -0
  222. data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/contact_me.js +75 -0
  223. data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/jqBootstrapValidation.js +912 -0
  224. data/spec/dummy/themes/_mbus/theme_assets/_mbus/javascripts/jquery-1.11.0.js +4 -0
  225. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/application.css +14 -0
  226. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/bootstrap.css +6203 -0
  227. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/bootstrap.min.css +5 -0
  228. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/css/font-awesome.css +1566 -0
  229. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/css/font-awesome.min.css +4 -0
  230. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/FontAwesome.otf +0 -0
  231. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/fontawesome-webfont.eot +0 -0
  232. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/fontawesome-webfont.svg +504 -0
  233. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/fontawesome-webfont.ttf +0 -0
  234. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/fonts/fontawesome-webfont.woff +0 -0
  235. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/bordered-pulled.less +16 -0
  236. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/core.less +12 -0
  237. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/fixed-width.less +6 -0
  238. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/font-awesome.less +17 -0
  239. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/icons.less +506 -0
  240. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/larger.less +13 -0
  241. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/list.less +19 -0
  242. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/mixins.less +20 -0
  243. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/path.less +14 -0
  244. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/rotated-flipped.less +9 -0
  245. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/spinning.less +32 -0
  246. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/stacked.less +20 -0
  247. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/less/variables.less +515 -0
  248. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_bordered-pulled.scss +16 -0
  249. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_core.scss +12 -0
  250. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_fixed-width.scss +6 -0
  251. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_icons.scss +506 -0
  252. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_larger.scss +13 -0
  253. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_list.scss +19 -0
  254. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_mixins.scss +20 -0
  255. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_path.scss +14 -0
  256. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_rotated-flipped.scss +9 -0
  257. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_spinning.scss +32 -0
  258. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_stacked.scss +20 -0
  259. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/_variables.scss +515 -0
  260. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/font-awesome-4.1.0/scss/font-awesome.scss +17 -0
  261. data/spec/dummy/themes/_mbus/theme_assets/_mbus/stylesheets/modern-business.css +93 -0
  262. data/spec/dummy/themes/_mbus/theme_support/config/load_theme.rb +0 -0
  263. data/spec/dummy/themes/_mbus/theme_support/locales/site.cs.yml +57 -0
  264. data/spec/dummy/themes/_mbus/theme_support/locales/site.de.yml +57 -0
  265. data/spec/dummy/themes/_mbus/theme_support/locales/site.en.yml +57 -0
  266. data/spec/dummy/themes/_mbus/theme_support/locales/site.fi.yml +58 -0
  267. data/spec/dummy/themes/_mbus/theme_support/locales/site.ja.yml +57 -0
  268. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_blog_right_sidebar.html.erb +91 -0
  269. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_comment.html.erb +21 -0
  270. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_comment_form.html.erb +16 -0
  271. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_comment_list.html.erb +7 -0
  272. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_comment_section.html.erb +17 -0
  273. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_page_footer.html.erb +11 -0
  274. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_page_header.html.erb +39 -0
  275. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_page_top.html.erb +24 -0
  276. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_post_summary_item.html.erb +11 -0
  277. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/_social_buttons_initialization.html.erb +10 -0
  278. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/blog.html.erb +47 -0
  279. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/blog_post.html.erb +55 -0
  280. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/content_full_width.html.erb +28 -0
  281. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/content_with_left_nav.html.erb +44 -0
  282. data/spec/dummy/themes/_mbus/theme_support/views/layouts/cms_templates/index.html.erb +19 -0
  283. data/spec/dummy/themes/local/_theme.yml +8 -0
  284. data/spec/factories/accounts.rb +17 -0
  285. data/spec/factories/blogs.rb +19 -0
  286. data/spec/factories/posts.rb +23 -0
  287. data/spec/factories/user_profiles.rb +10 -0
  288. data/spec/factories/users.rb +19 -0
  289. data/spec/features/admin/blog_admin_spec.rb +16 -0
  290. data/spec/models/cms_blog_spec.rb +37 -0
  291. data/spec/models/cms_page_spec.rb +9 -0
  292. data/spec/models/cms_post_spec.rb +44 -0
  293. data/spec/rails_helper.rb +70 -0
  294. data/spec/spec_helper.rb +85 -0
  295. data/spec/support/accounts.rb +17 -0
  296. data/spec/support/devise.rb +44 -0
  297. data/spec/support/fix_locale.rb +57 -0
  298. metadata +545 -0
@@ -0,0 +1,30 @@
1
+ module Liquid
2
+ class Markdown < DmCore::LiquidBlock
3
+ include DmCore::LiquidHelper
4
+
5
+ #------------------------------------------------------------------------------
6
+ def render(context)
7
+ markdown(super, safe: false)
8
+ end
9
+
10
+ def self.details
11
+ { name: self.tag_name,
12
+ summary: 'Process text with Markdown',
13
+ category: 'structure',
14
+ description: <<-END_OF_DESCRIPTION
15
+ Process the enclosed text with Markdown. Useful when your processing a page as HTML, but you would like to use
16
+ Markdown in certain sections.
17
+
18
+ ~~~
19
+ {% markdown %}
20
+ ...content
21
+ {% endmarkdown %}
22
+ ~~~
23
+ END_OF_DESCRIPTION
24
+ }
25
+ end
26
+ end
27
+
28
+ Template.register_tag('markdown', Markdown)
29
+
30
+ end
@@ -0,0 +1,36 @@
1
+ class PostNotifyMailer < DmCore::SiteMailer
2
+
3
+ helper DmCms::PostsHelper
4
+ helper DmCore::LiquidHelper
5
+ helper DmCore::UrlHelper
6
+ helper DmCore::AccountHelper
7
+
8
+ layout 'email_templates/dm_cms_email_layout'
9
+
10
+ # send notification email, using the users preferred locale if possible
11
+ #------------------------------------------------------------------------------
12
+ def post_notify(user, post, account)
13
+ Account.current = account # needed so this can run in a background job
14
+ # Account.current.set_default_values
15
+ locale = account.verify_locale(user.locale)
16
+ I18n.with_locale(locale) do
17
+ @subject = "Blog: #{post.cms_blog.title} :: #{post.title}"
18
+ @recipients = user.email
19
+ @blog_title = post.cms_blog.title
20
+ @post_title = post.title
21
+ @post_link = dm_cms.post_show_url(post.cms_blog.slug, post.slug, locale: locale, host: account.url_host, protocol: account.url_protocol)
22
+ @post = post
23
+ @header_image = post.cms_blog.image_email_header || post.cms_blog.header_image
24
+
25
+ headers = { "Return-Path" => account.preferred_blog_from_email || account.preferred_smtp_from_email }
26
+ mail( from: account.preferred_blog_from_email || account.preferred_smtp_from_email,
27
+ reply_to: account.preferred_blog_from_email || account.preferred_smtp_from_email,
28
+ to: @recipients, subject: @subject,
29
+ theme: account.account_prefix) do |format|
30
+ format.text { render "layouts/email_templates/dm_cms_post_notify.text.erb" }
31
+ format.html { render "layouts/email_templates/dm_cms_post_notify.html.erb" }
32
+ end
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,89 @@
1
+ class CmsBlog < ActiveRecord::Base
2
+ include DmCore::Concerns::PublicPrivate
3
+
4
+ # --- globalize
5
+ translates :title, :fallbacks_for_empty_translations => true
6
+ globalize_accessors :locales => DmCore::Language.language_array
7
+
8
+ # --- FriendlyId
9
+ extend FriendlyId
10
+ include DmCore::Concerns::FriendlyId
11
+
12
+ acts_as_followable
13
+
14
+ resourcify
15
+
16
+ include RankedModel
17
+ ranks :row_order, :with_same => :account_id
18
+
19
+ default_scope { where(account_id: Account.current.id).order(:row_order) }
20
+ scope :published, -> { where(:published => true) }
21
+
22
+ has_many :posts, -> { order('published_on DESC') }, :class_name => 'CmsPost', :dependent => :destroy
23
+ belongs_to :account
24
+ belongs_to :owner, :polymorphic => true
25
+
26
+ preference :show_social_buttons, :boolean, :default => false
27
+ preference :header_accent_color, :string
28
+
29
+ validates :title, presence_default_locale: true
30
+ validates_uniqueness_of :slug, scope: :account_id
31
+
32
+ #------------------------------------------------------------------------------
33
+ def model_slug
34
+ send("title_#{Account.current.preferred_default_locale}")
35
+ end
36
+
37
+ #------------------------------------------------------------------------------
38
+ def is_published?
39
+ published
40
+ end
41
+
42
+ #------------------------------------------------------------------------------
43
+ def show_social_buttons?
44
+ preferred_show_social_buttons? && !is_private?
45
+ end
46
+
47
+ # Are any of the blogs readable by this user? One positive is all need...
48
+ #------------------------------------------------------------------------------
49
+ def any_readable_blogs?(user)
50
+ CmsBlog.all.any? { |b| b.can_be_read_by?(user) }
51
+ end
52
+
53
+ # Return the header image, or a default if not specified
54
+ #------------------------------------------------------------------------------
55
+ def header_image(default = nil)
56
+ self.attributes['header_image'] || default
57
+ end
58
+
59
+ #------------------------------------------------------------------------------
60
+ def header_accent_color(default = '')
61
+ self.preferred_header_accent_color || default
62
+ end
63
+
64
+ # Grab a list of the recent posts. Can pull from all blogs or a specific
65
+ # one.
66
+ #------------------------------------------------------------------------------
67
+ def self.recent_posts(options = {user: nil, limit: 5, blog: nil})
68
+ if options[:blog].nil? # get all available to user
69
+ query_blogs = CmsBlog.available_to_user(options[:user]).map(&:id)
70
+ else
71
+ query_blogs = CmsBlog.friendly.find(options[:blog])
72
+ end
73
+ CmsPost.where(cms_blog_id: query_blogs).includes(:cms_blog, :translations).published.order('published_on DESC').limit(options[:limit])
74
+ end
75
+
76
+ # Send new post notifications to any followers
77
+ # NOTE: Currently, we don't do automated notifications for new blog posts.
78
+ # You must click on the button in the backend to trigger it. At the moment,
79
+ # we desire that extra level of control. If we decided to enable this in the
80
+ # future, selecting using the notification_sent_on column, make sure that
81
+ # all current posts are non-nil, so we don't trigger a much of old posts
82
+ # being sent
83
+ #------------------------------------------------------------------------------
84
+ # def self.notify_followers(start_time, end_time = Time.now)
85
+ # posts = CmsPost.published.includes(:cms_blog).where(cms_blogs: {published: true}).where(notification_sent_on: nil)
86
+ # posts.each {|post| post.send_notification_emails }
87
+ # end
88
+
89
+ end
@@ -0,0 +1,76 @@
1
+ # Note: fragment caching is used during rendering. The cache key is based
2
+ # on both the model and the current locale (because each model supports
3
+ # multiple translations). The cache will be busted automatically since
4
+ # the updated_at attribute will be updated on save.
5
+ #------------------------------------------------------------------------------
6
+ class CmsContentitem < ActiveRecord::Base
7
+ class Translation < ::Globalize::ActiveRecord::Translation
8
+ has_paper_trail
9
+ end
10
+
11
+ belongs_to :cms_page
12
+
13
+ include RankedModel
14
+ ranks :row_order, with_same: [:account_id, :cms_page_id]
15
+ default_scope { where(account_id: Account.current.id) }
16
+
17
+ # --- globalize (don't use versioning: true, translations erased when updating regular model data. Maybe fixed in github version)
18
+ translates :content, fallbacks_for_empty_translations: true
19
+ globalize_accessors locales: DmCore::Language.language_array
20
+
21
+ # --- versioning - skip anything translated
22
+ has_paper_trail skip: :content
23
+
24
+ amoeba do
25
+ enable
26
+ end
27
+ # --- validations
28
+ validates_presence_of :itemtype, :container
29
+ validates_length_of :itemtype, maximum: 30
30
+ validates_length_of :container, maximum: 30
31
+ validate :validate_conflict, on: :update
32
+ validates :content, liquid: { locales: true }, presence_default_locale: true
33
+
34
+ # --- content types supported
35
+ CONTENT_TYPES = [ 'Markdown', 'Textile', 'HTML' ]
36
+
37
+ #------------------------------------------------------------------------------
38
+ def original_updated_on
39
+ @original_updated_on || self.updated_on.to_f
40
+ end
41
+ attr_writer :original_updated_on
42
+
43
+ # Try to see if the record has been changed by someone while being edited by someone
44
+ # else. If original_updated_on is not set, then don't check - allows acts_as_list
45
+ # methods to update without causing a problem.
46
+ # [todo] still needed since we don't use acts_as_list anymore?
47
+ #------------------------------------------------------------------------------
48
+ def validate_conflict
49
+ if @conflict || (!@original_updated_on.nil? && self.updated_on.to_f > @original_updated_on.to_f)
50
+ @conflict = true
51
+ @original_updated_on = nil
52
+ errors.add :base, "This record was changed while you were editing."
53
+ changes.each do |attribute, values|
54
+ errors.add attribute, "was #{values.first}"
55
+ end
56
+ end
57
+ end
58
+
59
+ # Generate any data to pass when rendering with Liquid
60
+ #------------------------------------------------------------------------------
61
+ def to_liquid
62
+ cms_page.to_liquid
63
+ end
64
+
65
+ #------------------------------------------------------------------------------
66
+ def deep_clone(new_cms_page_id)
67
+ new_cms_contentitem = self.clone
68
+ new_cms_contentitem.cms_page_id = new_cms_page_id
69
+
70
+ DmCore::Language.language_array.each do |locale|
71
+ eval("new_cms_contentitem.content_#{locale[:lang]} = content_#{locale[:lang]} unless content_#{locale[:lang]}.nil?")
72
+ end
73
+ new_cms_contentitem.save
74
+ end
75
+
76
+ end
@@ -0,0 +1,227 @@
1
+ # Implementation Note: if the 'menutitle' is blank, that indicates the page should
2
+ # not be shown in menus. It can still be published and directly linked to, but
3
+ # it should not show up in any auto-generated menus. This gives the ability
4
+ # to have many pages in a section, with some of them 'hidden' from the main menu
5
+ # lists, but can still be linked to and shown.
6
+ #------------------------------------------------------------------------------
7
+ class CmsPage < ActiveRecord::Base
8
+ class Translation < ::Globalize::ActiveRecord::Translation
9
+ has_paper_trail
10
+ end
11
+
12
+ #--- NOTE: if you add any new fields, then update the duplicate_with_associations method
13
+
14
+ # --- globalize (don't use versioning: true, translations erased when updating regular model data. Maybe fixed in github version)
15
+ translates :title, :summary, :menutitle, :fallbacks_for_empty_translations => true #, :versioning => true
16
+ globalize_accessors :locales => DmCore::Language.language_array
17
+
18
+ # --- versioning - skip anything translated
19
+ has_paper_trail :skip => [:title, :menutitle]
20
+
21
+ # --- FriendlyId
22
+ extend FriendlyId
23
+ include DmCore::Concerns::FriendlyId
24
+
25
+ # --- associations
26
+ has_many :cms_contentitems, -> { order(:row_order) }, :dependent => :destroy
27
+ has_ancestry :cache_depth => true
28
+ before_save :cache_depth # fixes bug where depth not recalculated when subtree moved
29
+
30
+ include RankedModel
31
+ ranks :row_order, :with_same => [:account_id, :ancestry]
32
+
33
+ default_scope { where(account_id: Account.current.id).order("ancestry, row_order ASC") }
34
+
35
+ preference :show_social_buttons, :boolean, :default => false
36
+ preference :header_accent_color, :string
37
+
38
+ amoeba do
39
+ enable
40
+ end
41
+
42
+ # --- validations
43
+ validates_length_of :slug, :maximum => 50
44
+ validates_presence_of :slug
45
+ validates_uniqueness_of :slug, :scope => :account_id
46
+ validates_length_of :pagetype, :maximum => 20
47
+ validates_presence_of :pagetype
48
+ validates_length_of :template, :maximum => 50
49
+
50
+ # --- list of pagetypes
51
+ PAGETYPE = ['content', 'pagelink', 'controller/action', 'link', 'divider']
52
+
53
+ # Base the slug on the default locale
54
+ #------------------------------------------------------------------------------
55
+ def model_slug
56
+ send("title_#{Account.current.preferred_default_locale}")
57
+ end
58
+
59
+ # is the page published, based on the publish flag and the publish dates
60
+ #------------------------------------------------------------------------------
61
+ def is_published?
62
+ # --- {todo} need to hook in the publish dates
63
+ published
64
+ end
65
+
66
+ #------------------------------------------------------------------------------
67
+ def show_social_buttons?
68
+ preferred_show_social_buttons?
69
+ end
70
+
71
+ # is this a special divider page - which doesn't get rendered, it's for adding
72
+ # categories in a sub menu
73
+ #------------------------------------------------------------------------------
74
+ def divider?
75
+ pagetype == 'divider'
76
+ end
77
+
78
+ # Return the template name. If it's empty, the go to each parent until one
79
+ # is found.
80
+ # raise an exception if there is no page template - otherwise error is hidden
81
+ #------------------------------------------------------------------------------
82
+ def page_template
83
+ page = self
84
+ page = page.parent while page.template.blank? && !page.is_root?
85
+ raise "No template available for page #{self.slug}" if page.template.blank?
86
+ return page.template
87
+ end
88
+
89
+ # Return a list of published children pages
90
+ # => user, to check for permissions
91
+ # => include_blank_titles to true to include pages with blank titles.
92
+ # do not include by default
93
+ #------------------------------------------------------------------------------
94
+ def published_children(user, options = {include_blank_titles: false})
95
+ pages = []
96
+ if self.has_children?
97
+ self.children.each do |child|
98
+ if child.is_published? || (user && user.is_admin?)
99
+ pages << child unless child[:menutitle].blank? && !options[:include_blank_titles]
100
+ end
101
+ end
102
+ end
103
+ return pages
104
+ end
105
+
106
+ # Return the header image, or a default if not specified
107
+ #------------------------------------------------------------------------------
108
+ def header_image(default = nil)
109
+ self.attributes['header_image'] || default
110
+ end
111
+
112
+ #------------------------------------------------------------------------------
113
+ def header_accent_color(default = '')
114
+ self.preferred_header_accent_color || default
115
+ end
116
+
117
+ #------------------------------------------------------------------------------
118
+ def self.page_types
119
+ PAGETYPE
120
+ end
121
+
122
+ # Generate any data to pass when rendering with Liquid
123
+ #------------------------------------------------------------------------------
124
+ def to_liquid
125
+ { 'page' =>
126
+ {
127
+ 'title' => self.title,
128
+ 'menutitle' => self.menutitle,
129
+ 'slug' => self.slug
130
+ },
131
+ 'subscription' =>
132
+ {
133
+ 'trial?' => false,
134
+ 'active?' => true
135
+ }
136
+ }
137
+ end
138
+
139
+ # Check if this page has been cookied. If needed, we will set a cookie, using
140
+ # the page's slug, to a value of 1. This indicates that the page has
141
+ # been visited. This is only needed in cases where we want to ensure a page
142
+ # has been visited before enabling some other function.
143
+ #
144
+ # If cookie_hash is empty, then we don't care if the page has been visited or not,
145
+ # simply return true
146
+ #------------------------------------------------------------------------------
147
+ def visited?(cookie_hash)
148
+ return ((cookie_hash.empty? || cookie_hash[slug] == "1") ? true : false)
149
+ end
150
+
151
+ # Create a default site. Check if pages exists first, so we can add missing
152
+ # pages to already created sites.
153
+ #------------------------------------------------------------------------------
154
+ def self.create_default_site
155
+ #--- index page
156
+ unless (site = CmsPage.find_by_slug('index'))
157
+ site = CmsPage.create(:slug => 'index', :pagetype => 'content', :template => 'index',
158
+ :published => true, :title => 'Front Page')
159
+ end
160
+
161
+ unless (standard = CmsPage.find_by_slug('standard_pages'))
162
+ standard = site.children.create(slug: 'standard_pages', pagetype: 'pagelink',
163
+ published: false, title: 'Standard Pages')
164
+ end
165
+
166
+ unless CmsPage.find_by_slug('missing')
167
+ standard.children.create( :slug => 'missing', :pagetype => 'content', :template => '404',
168
+ :published => true, :title => 'Page Missing')
169
+ end
170
+
171
+ unless CmsPage.find_by_slug('coming_soon')
172
+ standard.children.create( :slug => 'coming_soon', :pagetype => 'content', :template => 'coming_soon',
173
+ :published => true, :title => 'Coming Soon')
174
+ end
175
+ unless CmsPage.find_by_slug('signup_success')
176
+ standard.children.create( :slug => 'signup_success', :pagetype => 'pagelink',
177
+ :link => 'index', :published => true, :title => 'Signup Success')
178
+ end
179
+ unless CmsPage.find_by_slug('confirmation_success')
180
+ standard.children.create( :slug => 'confirmation_success', :pagetype => 'pagelink',
181
+ :link => 'index', :published => true, :title => 'Confirmaton Success')
182
+ end
183
+ end
184
+
185
+ # {todo} currently, this mostly works from the console. However, when run
186
+ # from the browser it hangs in some type of infinite loop, inside amoeba_dup.
187
+ # Was unable to track it down, so this function is currently not called anywhere.
188
+ #------------------------------------------------------------------------------
189
+ def duplicate_with_associations
190
+ new_page = nil
191
+ new_slug = "duplicate-#{self.slug}"
192
+ if CmsPage.find_by_slug(new_slug)
193
+ #--- already a duplicate page, return nil
194
+ return nil
195
+ else
196
+ CmsPage.paper_trail_off!
197
+ CmsContentitem.paper_trail_off!
198
+ CmsPage::Translation.paper_trail_off!
199
+ CmsContentitem::Translation.paper_trail_off!
200
+ new_page = self.amoeba_dup
201
+ new_page.slug = new_slug
202
+ # new_page.without_versioning do
203
+ new_page.save
204
+ # end
205
+ CmsPage.paper_trail_on!
206
+ CmsContentitem.paper_trail_on!
207
+ CmsPage::Translation.paper_trail_on!
208
+ CmsContentitem::Translation.paper_trail_on!
209
+ # new_page = self.initialize_dup(self)
210
+ # new_page.slug = new_slug
211
+ #
212
+ # DmCore::Language.language_array.each do |locale|
213
+ # new_page.send("title_#{locale}=", self.send("title_#{locale}")) unless self.send("title_#{locale}").nil?
214
+ # new_page.send("menutitle_#{locale}=", self.send("menutitle_#{locale}")) unless self.send("menutitle_#{locale}").nil?
215
+ # new_page.save
216
+ # end
217
+ # # new_page.save
218
+ # new_page.reload
219
+ #
220
+ # # cms_contentitems.each do |content|
221
+ # # content.deep_clone(new_page.id)
222
+ # # end
223
+ end
224
+ return new_page
225
+ end
226
+
227
+ end