slices 1.0.0

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 (215) hide show
  1. data/CHANGELOG.md +3 -0
  2. data/README.md +51 -0
  3. data/Rakefile +9 -0
  4. data/app/assets/images/slices/ajax-loader.gif +0 -0
  5. data/app/assets/images/slices/asset-background.png +0 -0
  6. data/app/assets/images/slices/asset-spinner.gif +0 -0
  7. data/app/assets/images/slices/bg_header.gif +0 -0
  8. data/app/assets/images/slices/black-Linen.png +0 -0
  9. data/app/assets/images/slices/calendar.svg +68 -0
  10. data/app/assets/images/slices/chosen-sprite.png +0 -0
  11. data/app/assets/images/slices/drag-handle.svg +9 -0
  12. data/app/assets/images/slices/icon_admins.png +0 -0
  13. data/app/assets/images/slices/icon_app.png +0 -0
  14. data/app/assets/images/slices/icon_assets.png +0 -0
  15. data/app/assets/images/slices/icon_collapse.png +0 -0
  16. data/app/assets/images/slices/icon_drag.png +0 -0
  17. data/app/assets/images/slices/icon_files.png +0 -0
  18. data/app/assets/images/slices/icon_generic_file.png +0 -0
  19. data/app/assets/images/slices/icon_images.png +0 -0
  20. data/app/assets/images/slices/icon_padlock.png +0 -0
  21. data/app/assets/images/slices/icon_page.png +0 -0
  22. data/app/assets/images/slices/icon_search.png +0 -0
  23. data/app/assets/images/slices/icon_set-link.png +0 -0
  24. data/app/assets/images/slices/icon_set.png +0 -0
  25. data/app/assets/images/slices/icon_sitemap.png +0 -0
  26. data/app/assets/images/slices/icon_snippets.png +0 -0
  27. data/app/assets/images/slices/icon_template.jpg +0 -0
  28. data/app/assets/images/slices/icon_upload_happy.png +0 -0
  29. data/app/assets/images/slices/icon_upload_sad.png +0 -0
  30. data/app/assets/images/slices/icon_upload_thinking.png +0 -0
  31. data/app/assets/images/slices/noise.png +0 -0
  32. data/app/assets/images/slices/sitemap_icon_ghost.png +0 -0
  33. data/app/assets/images/slices/sitemap_icon_home.png +0 -0
  34. data/app/assets/images/slices/sitemap_icon_page.png +0 -0
  35. data/app/assets/images/slices/sitemap_icon_set_page.png +0 -0
  36. data/app/assets/images/slices/sitemap_icon_virtual_page.png +0 -0
  37. data/app/assets/images/slices/sitemap_overlay.png +0 -0
  38. data/app/assets/images/slices/spinner.gif +0 -0
  39. data/app/assets/images/slices/trash.png +0 -0
  40. data/app/assets/javascripts/admin.js.erb +18 -0
  41. data/app/assets/javascripts/slices/app/backbones/admins.js +114 -0
  42. data/app/assets/javascripts/slices/app/backbones/entries.js +172 -0
  43. data/app/assets/javascripts/slices/app/backbones/generic.js +101 -0
  44. data/app/assets/javascripts/slices/app/backbones/snippets.js +113 -0
  45. data/app/assets/javascripts/slices/app/helpers/assets.js +61 -0
  46. data/app/assets/javascripts/slices/app/helpers/breadcrumbs.js +30 -0
  47. data/app/assets/javascripts/slices/app/helpers/composer.js +26 -0
  48. data/app/assets/javascripts/slices/app/helpers/date_field.js +16 -0
  49. data/app/assets/javascripts/slices/app/helpers/get_value.js +31 -0
  50. data/app/assets/javascripts/slices/app/helpers/icon_upload_names.js.erb +5 -0
  51. data/app/assets/javascripts/slices/app/helpers/layout.js +20 -0
  52. data/app/assets/javascripts/slices/app/helpers/sitemap.js +150 -0
  53. data/app/assets/javascripts/slices/app/helpers/slice_preview.js +48 -0
  54. data/app/assets/javascripts/slices/app/helpers/tagging.js +73 -0
  55. data/app/assets/javascripts/slices/app/helpers/token_field.js +17 -0
  56. data/app/assets/javascripts/slices/app/helpers/upload_icons.js.erb +5 -0
  57. data/app/assets/javascripts/slices/app/helpers/uploader.js +127 -0
  58. data/app/assets/javascripts/slices/app/models/asset.js +29 -0
  59. data/app/assets/javascripts/slices/app/models/asset_collection.js +41 -0
  60. data/app/assets/javascripts/slices/app/models/attachment.js +29 -0
  61. data/app/assets/javascripts/slices/app/models/attachment_collection.js +7 -0
  62. data/app/assets/javascripts/slices/app/models/composer_item.js +1 -0
  63. data/app/assets/javascripts/slices/app/models/composer_item_collection.js +3 -0
  64. data/app/assets/javascripts/slices/app/models/file.js +103 -0
  65. data/app/assets/javascripts/slices/app/models/page.js +186 -0
  66. data/app/assets/javascripts/slices/app/models/s3_file.js +64 -0
  67. data/app/assets/javascripts/slices/app/slices.js +661 -0
  68. data/app/assets/javascripts/slices/app/views/asset_editor_view.js.erb +209 -0
  69. data/app/assets/javascripts/slices/app/views/asset_library_view.js +720 -0
  70. data/app/assets/javascripts/slices/app/views/asset_thumb_view.js.erb +191 -0
  71. data/app/assets/javascripts/slices/app/views/attachment_composer_view.js +350 -0
  72. data/app/assets/javascripts/slices/app/views/attachment_view.js +101 -0
  73. data/app/assets/javascripts/slices/app/views/calendar_view.js +198 -0
  74. data/app/assets/javascripts/slices/app/views/composer_item_view.js +54 -0
  75. data/app/assets/javascripts/slices/app/views/composer_view.js +130 -0
  76. data/app/assets/javascripts/slices/app/views/date_field_view.js +177 -0
  77. data/app/assets/javascripts/slices/app/views/file_view.js +142 -0
  78. data/app/assets/javascripts/slices/app/views/token_field_view.js +253 -0
  79. data/app/assets/javascripts/slices/lib/freeze.js +14 -0
  80. data/app/assets/javascripts/slices/lib/human_file_size.js +16 -0
  81. data/app/assets/javascripts/slices/lib/json_patch.js +9 -0
  82. data/app/assets/javascripts/slices/lib/moment.js +47 -0
  83. data/app/assets/javascripts/slices/lib/plugins.js +101 -0
  84. data/app/assets/javascripts/slices/lib/sortable.js +14 -0
  85. data/app/assets/javascripts/slices/slices.js +27 -0
  86. data/app/assets/javascripts/slices/vendor/autoscroll.js +188 -0
  87. data/app/assets/javascripts/slices/vendor/backbone.js +38 -0
  88. data/app/assets/javascripts/slices/vendor/handlebars.js +1920 -0
  89. data/app/assets/javascripts/slices/vendor/jqmodal.js +69 -0
  90. data/app/assets/javascripts/slices/vendor/jquery-ui.js +274 -0
  91. data/app/assets/javascripts/slices/vendor/jquery-ui_nested-sortable.js +357 -0
  92. data/app/assets/javascripts/slices/vendor/jquery.ajaxprogress.js +76 -0
  93. data/app/assets/javascripts/slices/vendor/jquery.js +2 -0
  94. data/app/assets/javascripts/slices/vendor/livefield.js +459 -0
  95. data/app/assets/javascripts/slices/vendor/moment.js +6 -0
  96. data/app/assets/javascripts/slices/vendor/rails.js +315 -0
  97. data/app/assets/javascripts/slices/vendor/underscore-string.js +1 -0
  98. data/app/assets/javascripts/slices/vendor/underscore.js +5 -0
  99. data/app/assets/stylesheets/admin.css +1 -0
  100. data/app/assets/stylesheets/slices/admin.css.erb +2237 -0
  101. data/app/assets/stylesheets/slices/reset_html5.css +106 -0
  102. data/app/assets/stylesheets/slices/slices.css +7 -0
  103. data/app/controllers/admin/admin_controller.rb +10 -0
  104. data/app/controllers/admin/admins_controller.rb +76 -0
  105. data/app/controllers/admin/assets_controller.rb +53 -0
  106. data/app/controllers/admin/auth/omniauth_callbacks_controller.rb +15 -0
  107. data/app/controllers/admin/auth/passwords_controller.rb +4 -0
  108. data/app/controllers/admin/auth/sessions_controller.rb +4 -0
  109. data/app/controllers/admin/entries_controller.rb +88 -0
  110. data/app/controllers/admin/page_search_controller.rb +12 -0
  111. data/app/controllers/admin/pages_controller.rb +103 -0
  112. data/app/controllers/admin/site_maps_controller.rb +15 -0
  113. data/app/controllers/admin/snippets_controller.rb +33 -0
  114. data/app/controllers/application_controller.rb +4 -0
  115. data/app/controllers/pages_controller.rb +45 -0
  116. data/app/controllers/slices_controller.rb +63 -0
  117. data/app/controllers/static_assets_controller.rb +52 -0
  118. data/app/helpers/admin/admin_helper.rb +63 -0
  119. data/app/helpers/admin/assets_helper.rb +36 -0
  120. data/app/helpers/admin/entries_helper.rb +13 -0
  121. data/app/helpers/admin/site_maps_helper.rb +104 -0
  122. data/app/helpers/assets_helper.rb +64 -0
  123. data/app/helpers/navigation_helper.rb +195 -0
  124. data/app/helpers/pages_helper.rb +119 -0
  125. data/app/models/admin.rb +34 -0
  126. data/app/models/asset.rb +211 -0
  127. data/app/models/attachment.rb +11 -0
  128. data/app/models/layout.rb +44 -0
  129. data/app/models/page.rb +214 -0
  130. data/app/models/placeholder_slice.rb +8 -0
  131. data/app/models/set_page.rb +12 -0
  132. data/app/models/set_slice.rb +57 -0
  133. data/app/models/site_map.rb +24 -0
  134. data/app/models/slice.rb +80 -0
  135. data/app/models/snippet.rb +21 -0
  136. data/app/observers/asset_observer.rb +6 -0
  137. data/app/observers/page_observer.rb +37 -0
  138. data/app/presenters/entry_presenter.rb +17 -0
  139. data/app/presenters/page_presenter.rb +67 -0
  140. data/app/presenters/presenter.rb +9 -0
  141. data/app/presenters/set_page_presenter.rb +2 -0
  142. data/app/views/admin/admins/index.html.erb +26 -0
  143. data/app/views/admin/admins/show.html.erb +27 -0
  144. data/app/views/admin/assets/index.html.erb +1 -0
  145. data/app/views/admin/auth/passwords/edit.html.erb +20 -0
  146. data/app/views/admin/auth/passwords/new.html.erb +14 -0
  147. data/app/views/admin/auth/sessions/_form.html.erb +35 -0
  148. data/app/views/admin/auth/sessions/new.html.erb +14 -0
  149. data/app/views/admin/entries/index.html.erb +32 -0
  150. data/app/views/admin/pages/_breadcrumbs.html.erb +32 -0
  151. data/app/views/admin/pages/_slices.html.erb +27 -0
  152. data/app/views/admin/pages/new.html.erb +14 -0
  153. data/app/views/admin/pages/show.html.erb +50 -0
  154. data/app/views/admin/shared/_asset_storage.html.erb +17 -0
  155. data/app/views/admin/shared/_custom_links.html.erb +1 -0
  156. data/app/views/admin/shared/_custom_navigation.html.erb +1 -0
  157. data/app/views/admin/shared/_navigation.html.erb +5 -0
  158. data/app/views/admin/site_maps/_page_li.html.erb +20 -0
  159. data/app/views/admin/site_maps/_set_page_li.html.erb +23 -0
  160. data/app/views/admin/site_maps/index.html.erb +29 -0
  161. data/app/views/admin/snippets/form.html.erb +12 -0
  162. data/app/views/admin/snippets/index.html.erb +20 -0
  163. data/app/views/admin/snippets/update.html.erb +0 -0
  164. data/app/views/layouts/admin.html.erb +72 -0
  165. data/lib/ext/file_store_cache.rb +18 -0
  166. data/lib/generators/humans/USAGE +8 -0
  167. data/lib/generators/humans/humans_generator.rb +10 -0
  168. data/lib/generators/humans/templates/humans.txt +6 -0
  169. data/lib/generators/slice/USAGE +28 -0
  170. data/lib/generators/slice/slice_generator.rb +123 -0
  171. data/lib/generators/slice/templates/main_fields.hbs +11 -0
  172. data/lib/generators/slice/templates/meta_fields.hbs +11 -0
  173. data/lib/generators/slice/templates/page.rb +19 -0
  174. data/lib/generators/slice/templates/presenter.rb +53 -0
  175. data/lib/generators/slice/templates/set.html.erb +8 -0
  176. data/lib/generators/slice/templates/set_slice.rb +14 -0
  177. data/lib/generators/slice/templates/set_slice_fields.hbs +5 -0
  178. data/lib/generators/slice/templates/show.html.erb +48 -0
  179. data/lib/generators/slice/templates/show_slice.rb +20 -0
  180. data/lib/generators/slice/templates/slice.rb +58 -0
  181. data/lib/generators/slice/templates/slice_fields.hbs +74 -0
  182. data/lib/generators/templates/slices.rb +211 -0
  183. data/lib/mongo_search.rb +84 -0
  184. data/lib/paperclip_validator.rb +5 -0
  185. data/lib/rack_utf8_fix.rb +10 -0
  186. data/lib/sRGB.icc +0 -0
  187. data/lib/set_link_renderer.rb +31 -0
  188. data/lib/slices.rb +68 -0
  189. data/lib/slices/asset/maker.rb +55 -0
  190. data/lib/slices/asset/rename.rb +67 -0
  191. data/lib/slices/available_slices.rb +43 -0
  192. data/lib/slices/cms_form_builder.rb +42 -0
  193. data/lib/slices/config.rb +93 -0
  194. data/lib/slices/container_parser.rb +70 -0
  195. data/lib/slices/generator_macros.rb +36 -0
  196. data/lib/slices/has_attachments.rb +111 -0
  197. data/lib/slices/has_slices.rb +88 -0
  198. data/lib/slices/i18n.rb +6 -0
  199. data/lib/slices/i18n/backend.rb +32 -0
  200. data/lib/slices/i18n_backend.rb +24 -0
  201. data/lib/slices/paperclip.rb +13 -0
  202. data/lib/slices/position_helper.rb +98 -0
  203. data/lib/slices/renderer.rb +52 -0
  204. data/lib/slices/slices_engine.rb +51 -0
  205. data/lib/slices/split_date_time_field.rb +14 -0
  206. data/lib/slices/tasks/assets.rake +35 -0
  207. data/lib/slices/tasks/db.rake +50 -0
  208. data/lib/slices/tasks/seeds.rake +93 -0
  209. data/lib/slices/tasks/validate.rake +62 -0
  210. data/lib/slices/tree.rb +306 -0
  211. data/lib/slices/version.rb +4 -0
  212. data/lib/slices/will_paginate.rb +12 -0
  213. data/lib/slices/will_paginate_mongoid.rb +45 -0
  214. data/lib/standard_tree.rb +193 -0
  215. metadata +483 -0
@@ -0,0 +1,15 @@
1
+ class Admin::SiteMapsController < Admin::AdminController
2
+ layout 'admin'
3
+
4
+ def index
5
+ @pages = [Page.home]
6
+ @virtuals = Page.virtual
7
+ end
8
+
9
+ def update
10
+ SiteMap.rebuild(params[:sitemap])
11
+ expire_fragment(/navigation/)
12
+ head status: :ok
13
+ end
14
+ end
15
+
@@ -0,0 +1,33 @@
1
+ class Admin::SnippetsController < Admin::AdminController
2
+ layout 'admin'
3
+ respond_to :json, :html
4
+
5
+ def index
6
+ respond_to do |format|
7
+ format.html {}
8
+ format.json do
9
+ params[:per_page] = 50 unless params.include?(:per_page)
10
+ @snippets = Snippet.by_key.paginate(params)
11
+ render json: @snippets.as_json
12
+ end
13
+ end
14
+ end
15
+
16
+ def edit
17
+ @snippet = Snippet.find(params[:id])
18
+ render action: :form, layout: !request.xhr?
19
+ end
20
+
21
+ def update
22
+ @snippet = Snippet.find(params[:id])
23
+ @snippet.update_attributes(params[:snippet])
24
+ respond_to do |format|
25
+ format.html {}
26
+ format.json do
27
+ render json: @snippet.as_json
28
+ end
29
+ end
30
+ end
31
+
32
+ end
33
+
@@ -0,0 +1,4 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
4
+
@@ -0,0 +1,45 @@
1
+ class PagesController < SlicesController
2
+
3
+ caches_page :virtual_error_pages
4
+
5
+ def virtual_error_pages
6
+ role = Page.role_for_status(params[:status])
7
+ if role
8
+ render_page(Page.find_virtual(role), 200) # page is only cached if status is 200
9
+ else
10
+ raise Page::NotFound.new(request.path)
11
+ end
12
+ end
13
+
14
+ def create
15
+ page = Page.find_by_path(request.path)
16
+ raise Page::NotFound unless page.active?
17
+ slice = post_slice(page)
18
+ if slice.handle_post(params)
19
+ slice.set_success_message(flash)
20
+ redirect_to(slice.redirect_url)
21
+ else
22
+ render_page(page)
23
+ end
24
+ end
25
+
26
+ def show
27
+ page = nil
28
+ benchmark 'Page.find_by_path' do
29
+ page = Page.find_by_path(request.path)
30
+ raise Page::NotFound unless page.active?
31
+ end
32
+ render_page(page)
33
+ end
34
+
35
+ private
36
+ def post_slice(page)
37
+ page.slices.detect { |s| s.respond_to?(:handle_post) }.tap do |slice|
38
+ slice.nil? && (raise RuntimeError.new("page can't handle POST data"))
39
+ slice.setup({
40
+ renderer: self,
41
+ current_page: page
42
+ })
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ class SlicesController < ActionController::Base
2
+ include ActiveSupport::Benchmarkable
3
+
4
+ protect_from_forgery
5
+
6
+ rescue_from Exception, with: :render_error
7
+ rescue_from Page::NotFound, with: :render_not_found
8
+
9
+ append_view_path(File.join(Rails.root, *%w[app slices]))
10
+
11
+ define_callbacks :render_page, terminator: "response_body"
12
+
13
+ def self.should_raise_exceptions?
14
+ ! Rails.env.production?
15
+ end
16
+
17
+ protected
18
+
19
+ def render_not_found(exception)
20
+ raise exception if self.class.should_raise_exceptions?
21
+ render_not_found!(exception)
22
+ end
23
+
24
+ def render_not_found!(exception)
25
+ logger.warn "404: #{request.path} :: #{request.params.inspect}"
26
+ render_page(Page.find_virtual('not_found'), 404)
27
+ end
28
+
29
+ def render_error(exception)
30
+ raise exception if self.class.should_raise_exceptions?
31
+ logger.warn "500: #{request.path} :: #{request.params.inspect}"
32
+ render_page(Page.find_virtual('error'), 500)
33
+ end
34
+
35
+ private
36
+
37
+ def render_page(page, status = 200)
38
+ @page = page
39
+
40
+ run_callbacks :render_page do
41
+ ordered_slices = nil
42
+ benchmark 'Page.ordered_slices' do
43
+ ordered_slices = page_or_parent_slices
44
+ end
45
+ @slice_renderer = Slices::Renderer.new(
46
+ controller: self,
47
+ current_page: @page,
48
+ params: params,
49
+ slices: ordered_slices
50
+ )
51
+ render text: '', layout: page_layout(@page), status: status
52
+ end
53
+ end
54
+
55
+ def page_or_parent_slices
56
+ @page.entry? ? @page.parent.ordered_set_slices : @page.ordered_slices
57
+ end
58
+
59
+ def page_layout(page)
60
+ page.layout
61
+ end
62
+ end
63
+
@@ -0,0 +1,52 @@
1
+ class StaticAssetsController < SlicesController
2
+ caches_page :slices
3
+ caches_page :templates
4
+
5
+ rescue_from ActionController::MissingFile, Errno::ENOENT, with: :render_not_found!
6
+
7
+ helper 'pages'
8
+
9
+ def templates
10
+ templates_root = params[:slice] ? slice_templates : shared_templates
11
+ path = File.join(templates_root, params[:name])
12
+ path_with_format = [path, params[:format]].join '.'
13
+ send_file_inline path_with_format, content_type: 'text/html; charset=utf-8'
14
+ end
15
+
16
+ private
17
+
18
+ def mime_type
19
+ if params[:asset_type] == 'images'
20
+ {
21
+ 'jpg' => 'image/jpeg',
22
+ 'png' => 'image/png',
23
+ 'gif' => 'image/gif',
24
+ 'svg' => 'image/svg+xml'
25
+ }[params[:format]]
26
+ else
27
+ {
28
+ 'stylesheets' => 'text/css',
29
+ 'javascripts' => 'application/javascript'
30
+ }[params[:asset_type]]
31
+ end
32
+ end
33
+
34
+ def slice_templates
35
+ File.join(Rails.root, 'app', 'slices', params[:slice], 'templates')
36
+ end
37
+
38
+ def shared_templates
39
+ File.join(Slices.gem_path, 'public', 'slices', 'templates')
40
+ end
41
+
42
+ def send_file_inline(path, options)
43
+ headers['Cache-Control'] = 'public'
44
+ headers['Expires'] = (Time.now + 60 * 60 * 24).utc.httpdate
45
+
46
+ options.merge!({
47
+ text: File.open(path).read,
48
+ })
49
+ render options
50
+ end
51
+ end
52
+
@@ -0,0 +1,63 @@
1
+ # This module provides common helper methods for the CMS admin interface
2
+ #
3
+ module Admin::AdminHelper
4
+ # A list of css classes for the admin layout's body tag
5
+ #
6
+ # @!visibility private
7
+ def body_class_from_controller
8
+ [controller.controller_name.dasherize].tap do |classes|
9
+ if controller.respond_to?(:devise_controller?) && controller.devise_controller?
10
+ classes << 'devise'
11
+ end
12
+ end.join(' ')
13
+ end
14
+
15
+ # The set type of the current page
16
+ #
17
+ # @!visibility private
18
+ def page_set_type(page)
19
+ page.sets.first.try(:entry_type)
20
+ end
21
+
22
+ # Render a navigation link in the top nav
23
+ #
24
+ # @!visibility private
25
+ def admin_nav_link(controller, url = false, selected_url = false)
26
+ controller_name = controller.gsub(/ /, "_").downcase.pluralize
27
+ url = "/admin/#{controller_name}" unless url
28
+
29
+ css = nil
30
+ if selected_url && request.env['REQUEST_URI'] =~ /#{selected_url}/
31
+ css = "active"
32
+ elsif request.env['REQUEST_URI'] =~ /#{url}/
33
+ css = "active"
34
+ end
35
+ content_tag(:li, link_to(controller, url), class: css, id: "admin-nav-#{controller_name.dasherize}")
36
+ end
37
+
38
+ # Render custom navigation if template exists
39
+ #
40
+ # @!visibility private
41
+ def render_custom_navigation
42
+ if lookup_context.template_exists?('admin/shared/_custom_navigation')
43
+ render 'admin/shared/custom_navigation'
44
+ end
45
+ end
46
+
47
+ # Render custom links if a template exists
48
+ #
49
+ # @!visibility private
50
+ def render_custom_links
51
+ if lookup_context.template_exists?('admin/shared/_custom_links')
52
+ render 'admin/shared/custom_links'
53
+ end
54
+ end
55
+
56
+ # The CMS admin page title, fall back to 'Slices CMS' if there is no @page
57
+ #
58
+ # @!visibility private
59
+ def cms_title
60
+ @page.try(:name) || "Slices CMS"
61
+ end
62
+
63
+ end
@@ -0,0 +1,36 @@
1
+ # This module provides helper methods for assets in the CMS admin.
2
+ # #
3
+ module Admin::AssetsHelper
4
+ include Admin::AdminHelper
5
+
6
+ # Sign policy with S3 credentials
7
+ #
8
+ # @!visibility private
9
+ def signature(options = {})
10
+ Base64.encode64(
11
+ OpenSSL::HMAC.digest(
12
+ OpenSSL::Digest::Digest.new('sha1'),
13
+ Slices::Config.s3_credentials[:secret_access_key],
14
+ policy({ secret_access_key: Slices::Config.s3_credentials[:secret_access_key] })
15
+ )
16
+ ).gsub(/\n/, '')
17
+ end
18
+
19
+ # Generate policy for uploading asset direct to S3
20
+ #
21
+ # @!visibility private
22
+ def policy(options = {})
23
+ Base64.encode64(
24
+ {
25
+ expiration: 30.minutes.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z'),
26
+ conditions: [
27
+ { bucket: Slices::Config.s3_credentials[:bucket] },
28
+ { acl: 'public-read' },
29
+ { success_action_status: '201' },
30
+ ['starts-with', '$key', ''],
31
+ ['starts-with', '$Content-Type', ''],
32
+ ]
33
+ }.to_json
34
+ ).gsub(/\n|\r/, '')
35
+ end
36
+ end
@@ -0,0 +1,13 @@
1
+ # This module provides helper methods for entries in the CMS admin.
2
+ #
3
+ module Admin::EntriesHelper
4
+ include Admin::AdminHelper
5
+
6
+ # Create a link for adding a new entry
7
+ #
8
+ # @!visibility private
9
+ def link_to_add_entry page
10
+ url = new_admin_page_path parent_id: @page.id, type: page_set_type(page)
11
+ raw link_to 'Add Entry', url, class: 'button add', id: 'add-entry'
12
+ end
13
+ end
@@ -0,0 +1,104 @@
1
+ # This module provides methods for the Site Map page.
2
+ #
3
+ module Admin::SiteMapsHelper
4
+ include Admin::AdminHelper
5
+
6
+ # Render a list of pages
7
+ #
8
+ # @!visibility private
9
+ def list_pages(pages)
10
+ pages.inject(''.html_safe) do |html, page|
11
+ html << render(partial: page_partial(page), locals: {page: page} )
12
+ end
13
+ end
14
+
15
+ # When partial to use when rendering a page
16
+ #
17
+ # @!visibility private
18
+ def page_partial(page)
19
+ page.set_page? ? 'set_page_li' : 'page_li'
20
+ end
21
+
22
+ # Is it possible to add entries to the set page?
23
+ #
24
+ # @!visibility private
25
+ def addable_entries?(page)
26
+ page.sets.first && page.sets.first.addable_entries?
27
+ end
28
+
29
+ # Is it possible to edit child entries of the set page?
30
+ #
31
+ # @!visibility private
32
+ def editable_entries?(page)
33
+ page.sets.first && page.sets.first.editable_entries?
34
+ end
35
+
36
+ # Create a link to add a child to the current page
37
+ #
38
+ # @!visibility private
39
+ def link_to_add_child(page)
40
+ url = new_admin_page_path parent_id: page.id
41
+ raw link_to 'Add Child', url, class: 'button add-child'
42
+ end
43
+
44
+ # Create a link to delete the current page
45
+ #
46
+ # @!visibility private
47
+ def link_to_delete(page)
48
+ raw link_to 'Delete', admin_page_path(page),
49
+ method: :delete,
50
+ class: 'delete button',
51
+ confirm: confirm_delete_message
52
+ end
53
+
54
+ # The message to display when confirming deletion of a page
55
+ #
56
+ # @!visibility private
57
+ def confirm_delete_message
58
+ <<-TEXT
59
+ Are you sure you want to delete this page,
60
+ all its children and all its slices and other content?
61
+ TEXT
62
+ end
63
+
64
+ # Create a link to add an entry to the current page
65
+ #
66
+ # @!visibility private
67
+ def link_to_add_entry(page)
68
+ url = new_admin_page_path parent_id: page.id, type: page_set_type(page)
69
+ raw link_to 'Add Entry', url, class: 'button add-child'
70
+ end
71
+
72
+ # Create a link to view all of the entries of the current page
73
+ #
74
+ # @!visibility private
75
+ def link_to_all_entries(page)
76
+ url = admin_page_entries_path page
77
+ link_to 'View All', url, class: 'button'
78
+ end
79
+
80
+ # Create a link to edit the index template of the current page
81
+ #
82
+ # @!visibility private
83
+ def link_to_edit_index_template(page)
84
+ url = admin_page_path page
85
+ link_to 'Edit Index Tempate', url, class: 'button'
86
+ end
87
+
88
+ # Create a link to edit the entry template of the current page
89
+ #
90
+ # @!visibility private
91
+ def link_to_edit_entry_template(page)
92
+ url = admin_page_path page, entries: 1
93
+ link_to 'Edit Entry Template', url, class: 'button'
94
+ end
95
+
96
+ # Create a link to view the current page on the live site
97
+ #
98
+ # @!visibility private
99
+ def link_to_view_page(page)
100
+ return unless page.active?
101
+ link_to 'View page on site', page.path,
102
+ class: 'view-page', target: '_blank'
103
+ end
104
+ end
@@ -0,0 +1,64 @@
1
+ # This module provides methods for rendering HTML that links views to assets.
2
+ #
3
+ # image_if_present(slice.image, :medium)
4
+ # # => <img alt="image" height="146" src="/system/50ca095/medium/image.jpg" width="220" />
5
+ #
6
+ module AssetsHelper
7
+
8
+ # Returns an image tag for image of the specified size. If the image is nil or
9
+ # not present then nothing is returned. The image can be an Asset or
10
+ # Attachment. The available sizes are defined by {Slices::Config.asset_styles}.
11
+ # The image tag will have width and height attributes.
12
+ #
13
+ # image_if_present(slice.image, :medium)
14
+ # # => <img alt="image" height="146" src="/system/50ca095/medium/image.jpg" width="220" />
15
+ #
16
+ # @param [Asset, Attachment] image Asset or Attachemnt
17
+ # @param [Symbol] size Size of image
18
+ # @param [Hash] options Optional options for the Rails image_tag
19
+ # @return [String] Image tag
20
+ #
21
+ def image_if_present(image, size, options = {})
22
+ if image.respond_to?(:asset)
23
+ image = image.asset
24
+ end
25
+
26
+ size = size.to_sym
27
+ if image.present? && Slices::Config.asset_styles.has_key?(size)
28
+ options.reverse_merge!(size: image.dimensions_for(size))
29
+ image_tag(image.url_for(size), options)
30
+ end
31
+ end
32
+
33
+ # Returns a link to an image of the specificed size. If the image is nil or not
34
+ # present then nothing is returned, and if the link is not present then only
35
+ # the image is returned. The image can be an {Asset} or {Attachment}. The sizes
36
+ # are defined by {Slices::Config.asset_styles}
37
+ #
38
+ # link_image_if_linkable(article.path, article.feature_image, :icon)
39
+ # # => <a href="/article">
40
+ # # => <img alt="image" height="146" src="/system/50ca095/icon/image.jpg" width="220" />
41
+ # # => </a>
42
+ #
43
+ # @param [Object] link Link to pass to link_to
44
+ # @param [Asset, Attachment] image Asset or Attachemnt
45
+ # @param [Symbol] size Size of image
46
+ # @param [Hash] options Options for the Rails image_tag,
47
+ # use +:image_options+ to pass
48
+ # options to the image_tag
49
+ # @return [String] Image wrapped with a link tag
50
+ #
51
+ def link_image_if_linkable(link, image, size, options = {})
52
+ image_options = options.has_key?(:image_options) ? options.delete(:image_options) : {}
53
+ image = image_if_present(image, size, image_options)
54
+ if image.present?
55
+ if link.present?
56
+ link_to(image, link, options)
57
+ else
58
+ image
59
+ end
60
+ end
61
+ end
62
+
63
+ end
64
+