slices 1.0.5 → 2.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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +85 -17
  4. data/app/assets/images/slices/i18n.png +0 -0
  5. data/app/assets/images/slices/icon_collapse.png +0 -0
  6. data/app/assets/javascripts/slices/app/helpers/apply_defaults.js +9 -0
  7. data/app/assets/javascripts/slices/app/helpers/composer.js +2 -0
  8. data/app/assets/javascripts/slices/app/helpers/i18n.js +7 -0
  9. data/app/assets/javascripts/slices/app/helpers/markdown_cheat_sheet.js +50 -0
  10. data/app/assets/javascripts/slices/app/helpers/radio_field.js +21 -0
  11. data/app/assets/javascripts/slices/app/helpers/sitemap.js +82 -1
  12. data/app/assets/javascripts/slices/app/helpers/uploader.js +1 -1
  13. data/app/assets/javascripts/slices/app/helpers/url_field.js +17 -0
  14. data/app/assets/javascripts/slices/app/slices.js +14 -11
  15. data/app/assets/javascripts/slices/app/views/composer_view.js +16 -0
  16. data/app/assets/javascripts/slices/app/views/radio_field_view.js +67 -0
  17. data/app/assets/javascripts/slices/app/views/token_field_view.js +81 -24
  18. data/app/assets/javascripts/slices/app/views/url_field_view.js +44 -0
  19. data/app/assets/javascripts/slices/slices.js +1 -0
  20. data/app/assets/javascripts/slices/vendor/jquery.js +4 -2
  21. data/app/assets/stylesheets/slices/admin.css.erb +156 -31
  22. data/app/controllers/admin/admin_controller.rb +16 -1
  23. data/app/controllers/admin/assets_controller.rb +1 -1
  24. data/app/controllers/admin/entries_controller.rb +1 -1
  25. data/app/controllers/admin/pages_controller.rb +4 -13
  26. data/app/controllers/admin/site_maps_controller.rb +1 -2
  27. data/app/controllers/slices_controller.rb +12 -1
  28. data/app/helpers/admin/admin_helper.rb +8 -0
  29. data/app/helpers/admin/site_maps_helper.rb +41 -6
  30. data/app/helpers/navigation_helper.rb +8 -3
  31. data/app/helpers/pages_helper.rb +2 -2
  32. data/app/helpers/snippets_helper.rb +26 -0
  33. data/app/models/admin.rb +2 -3
  34. data/app/models/asset.rb +9 -20
  35. data/app/models/attachment.rb +10 -1
  36. data/app/models/page.rb +45 -34
  37. data/app/models/site_map.rb +1 -2
  38. data/app/models/slice.rb +46 -1
  39. data/app/models/snippet.rb +13 -4
  40. data/app/presenters/page_presenter.rb +8 -13
  41. data/app/views/admin/auth/sessions/_form.html.erb +3 -0
  42. data/app/views/admin/pages/_fields.html.erb +1 -0
  43. data/app/views/admin/pages/_slices.html.erb +8 -4
  44. data/app/views/admin/pages/new.html.erb +5 -1
  45. data/app/views/admin/pages/show.html.erb +30 -14
  46. data/app/views/admin/site_maps/_page_actions.html.erb +2 -0
  47. data/app/views/admin/site_maps/_page_li.html.erb +18 -7
  48. data/app/views/admin/site_maps/_set_page_li.html.erb +5 -5
  49. data/app/views/layouts/admin.html.erb +0 -17
  50. data/config/routes.rb +13 -16
  51. data/lib/generators/slice/templates/presenter.rb +11 -12
  52. data/lib/generators/slice/templates/set.html.erb +2 -2
  53. data/lib/generators/slices/install_generator.rb +13 -3
  54. data/lib/generators/slices/templates/slices.rb +3 -4
  55. data/lib/mongo_search.rb +1 -1
  56. data/lib/slices.rb +2 -9
  57. data/lib/slices/asset/maker.rb +2 -3
  58. data/lib/slices/available_slices.rb +8 -1
  59. data/lib/slices/config.rb +49 -8
  60. data/lib/slices/engine.rb +0 -4
  61. data/lib/slices/has_attachments.rb +25 -37
  62. data/lib/slices/has_slices.rb +15 -8
  63. data/lib/slices/localized_fields.rb +9 -0
  64. data/lib/slices/page_as_json.rb +7 -1
  65. data/lib/slices/renderer.rb +2 -2
  66. data/lib/slices/tree.rb +12 -3
  67. data/lib/slices/version.rb +1 -1
  68. data/lib/tasks/db.rake +6 -10
  69. data/lib/tasks/seeds.rake +1 -1
  70. data/public/slices/templates/page_main.hbs +1 -1
  71. data/public/slices/templates/page_meta.hbs +2 -2
  72. metadata +56 -84
  73. data/app/views/admin/shared/_custom_links.html.erb +0 -1
  74. data/app/views/admin/shared/_custom_navigation.html.erb +0 -1
  75. data/app/views/layouts/slices/application.html.erb +0 -14
  76. data/lib/ext/file_store_cache.rb +0 -18
  77. data/lib/generators/slices/templates/mongoid.yml +0 -12
  78. data/lib/generators/templates/slices.rb +0 -209
  79. data/lib/rack_utf8_fix.rb +0 -10
  80. data/lib/set_link_renderer.rb +0 -31
  81. data/lib/slices/i18n.rb +0 -6
  82. data/lib/slices/i18n/backend.rb +0 -32
  83. data/lib/slices/will_paginate_mongoid.rb +0 -45
  84. data/lib/standard_tree.rb +0 -193
@@ -8,8 +8,6 @@ class SiteMap
8
8
  '{root}'
9
9
  end
10
10
 
11
- private
12
-
13
11
  def self.set_children_for(parent_id, data)
14
12
  parent = Page.find(parent_id)
15
13
  data.each_with_index do |child_data, i|
@@ -21,4 +19,5 @@ class SiteMap
21
19
  set_children_for(child_data['id'], child_data['children']) if child_data['children']
22
20
  end
23
21
  end
22
+ private_class_method :set_children_for
24
23
  end
data/app/models/slice.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  class Slice
2
2
  include Mongoid::Document
3
+ include Slices::LocalizedFields
3
4
  include Slices::PositionHelper
4
5
 
5
6
  field :container
@@ -51,6 +52,23 @@ class Slice
51
52
  [_type, id].join(':')
52
53
  end
53
54
 
55
+ # Print out the cache key. This will use the updated_at time of the
56
+ # page which this document is embedded in.
57
+ #
58
+ # This is usually called inside a cache() block
59
+ #
60
+ # @example Returns the cache key
61
+ # document.cache_key
62
+ #
63
+ # @return [ String ] the string with updated_at
64
+ def cache_key
65
+ if time = normal_or_set_page.try(:updated_at)
66
+ "#{model_key}/#{id}-#{time.to_s(:number)}"
67
+ else
68
+ super
69
+ end
70
+ end
71
+
54
72
  def client_id?
55
73
  attributes.include?('client_id')
56
74
  end
@@ -63,10 +81,38 @@ class Slice
63
81
  attributes.include?('_deleted')
64
82
  end
65
83
 
84
+ def write_attributes(attrs)
85
+ attrs = attrs.symbolize_keys
86
+ self.embedded_relations.each do |field, metadata|
87
+ field = field.to_sym
88
+ next unless attrs.has_key?(field)
89
+
90
+ attrs[field] = (attrs[field] || []).map do |embedded_attrs|
91
+ if embedded_attrs[:_id].present?
92
+ embedded_doc = send(field).find(embedded_attrs[:_id])
93
+ embedded_doc.write_attributes(embedded_attrs)
94
+ embedded_doc
95
+ else
96
+ metadata.class_name.constantize.new(embedded_attrs)
97
+ end
98
+ end
99
+ end
100
+
101
+ super
102
+ end
103
+
66
104
  def as_json(*args)
67
105
  attributes.symbolize_keys.except(:_id, :_type).tap do |result|
68
106
  result.merge!(id: id, type: type)
69
107
  result.merge!(client_id: client_id) if client_id? && new_record?
108
+
109
+ self.embedded_relations.each do |field, metadata|
110
+ result.merge!(field.to_sym => send(field).map(&:as_json))
111
+ end
112
+
113
+ localized_field_names.each do |name|
114
+ result.merge!(name => send(name))
115
+ end
70
116
  end
71
117
  end
72
118
 
@@ -77,4 +123,3 @@ class Slice
77
123
  text_fields.map { |field| self[field.name.to_sym] }.join(" ")
78
124
  end
79
125
  end
80
-
@@ -3,12 +3,21 @@ class Snippet
3
3
 
4
4
  field :key
5
5
  field :value
6
- index :key
6
+ index({ key: 1 })
7
7
 
8
- scope :by_key, ascending(:key)
8
+ scope :by_key, ->{ ascending(:key) }
9
9
 
10
- def self.find_value_by_key(key)
11
- find(:first, conditions: { key: key }).try(:value)
10
+ # Finds the value of a snippet as a html_safe string
11
+ #
12
+ # Snippet.find_for_key 'address'
13
+ # # => "54B Downham Road"
14
+ #
15
+ # @param [String] key Snippet key to lookup
16
+ # @return [String]
17
+ #
18
+ def self.find_for_key(key)
19
+ find_by(key: key).value.try(:html_safe)
20
+ rescue Mongoid::Errors::DocumentNotFound
12
21
  end
13
22
 
14
23
  def as_json(*args)
@@ -3,19 +3,6 @@ class PagePresenter < Presenter
3
3
  @source.id.to_s
4
4
  end
5
5
 
6
- def available_slices
7
- slices = {}
8
- ObjectSpace.each_object do |object|
9
- ActiveSupport::Deprecation.silence do
10
- if object.class == Class && object.name =~ /\w+Slice$/
11
- key = object.name.underscore.sub('_slice', '')
12
- slices[key] = key.humanize
13
- end
14
- end
15
- end
16
- slices
17
- end
18
-
19
6
  def name
20
7
  @source.name
21
8
  end
@@ -44,6 +31,14 @@ class PagePresenter < Presenter
44
31
  'page_meta_extra'
45
32
  end
46
33
 
34
+ def main_extra_templates
35
+ [main_extra_template]
36
+ end
37
+
38
+ def meta_extra_templates
39
+ [meta_extra_template]
40
+ end
41
+
47
42
  def breadcrumbs
48
43
  [@source] + @source.ancestors
49
44
  end
@@ -1,5 +1,8 @@
1
1
  <div class="login">
2
2
  <%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
3
+ <% if flash[:alert].present? %>
4
+ <p class="flash-message"><%= flash[:alert] %></p>
5
+ <% end %>
3
6
 
4
7
  <p>
5
8
  <%= f.label :email %><br />
@@ -0,0 +1 @@
1
+ <%= form.cms_select :layout, @layouts %>
@@ -9,16 +9,20 @@ $(function() {
9
9
  mainTemplate: '<%= @page.main_template %>',
10
10
  metaTemplate: '<%= @page.meta_template %>',
11
11
 
12
- mainExtraTemplate: '<%= @page.main_extra_template %>',
13
- metaExtraTemplate: '<%= @page.meta_extra_template %>',
12
+ mainExtraTemplates: <%= raw @page.main_extra_templates.to_json %>,
13
+ metaExtraTemplates: <%= raw @page.meta_extra_templates.to_json %>,
14
14
 
15
15
  super_user: <%= current_admin.super? %>,
16
+ i18n: <%= Slices::Config.i18n? %>,
17
+
18
+ loadPagePath: '/admin/pages/{{id}}.json?locale=<%= I18n.locale %>',
19
+ savePagePath: '/admin/pages/{{id}}.json?locale=<%= I18n.locale %>',
16
20
 
17
21
  <% if @page.editing_entry_content_slices?(params[:entries]) %>
18
22
  mainTemplate: 'set_page_entry_content_main',
19
23
  metaTemplate: 'set_page_entry_content_meta',
20
- loadPagePath: '/admin/pages/{{id}}?entries=1',
21
- savePagePath: '/admin/pages/{{id}}?entries=1'
24
+ loadPagePath: '/admin/pages/{{id}}?locale=<%= I18n.locale %>&entries=1',
25
+ savePagePath: '/admin/pages/{{id}}?locale=<%= I18n.locale %>&entries=1'
22
26
  <% end %>
23
27
  }
24
28
  );
@@ -6,7 +6,11 @@
6
6
  <%= hidden_field_tag :type, params[:type] %>
7
7
  <% end %>
8
8
  <%= form.cms_text_field :name, required: false %>
9
- <%= form.cms_select :layout, @layouts %>
9
+
10
+ <%= render(
11
+ partial: Slices::Config.page_fields_template,
12
+ locals: { form: form }
13
+ ) %>
10
14
  </ul>
11
15
  <div class="bottom-toolbar">
12
16
  <%= form.submit value: "Create Page" %>
@@ -1,18 +1,34 @@
1
1
  <form id="slices-form">
2
- <div id="container-actions" class="toolbar">
3
- <nav>
4
- <ul>
5
- <li class="back"><%= link_to "Cancel editing (lose unsaved changes)", admin_site_maps_path %></li>
6
- </ul>
7
- </nav>
8
- <div class="actions">
9
- <ul>
10
- <li><a id="minimise" class="button">Minimise all slices</a></li>
11
- <li>
12
- <%= link_to "View page on site", @page.source.path, id: 'page-view-on-site', target: 'site', class: 'button standard' %>
13
- </li>
14
- <li><input type="submit" value="Save changes" id="save-changes" disabled></li>
15
- </ul>
2
+ <div id="container-actions">
3
+ <% if Slices::Config.i18n? %>
4
+ <div class="toolbar translations">
5
+ <nav>
6
+ Edit in
7
+ <ul>
8
+ <% I18n.available_locales.each do |locale| %>
9
+ <li>
10
+ <%= link_to_if locale != I18n.locale, t("locales.#{locale}", default: locale.to_s), admin_page_path(@page.source, locale: locale) %>
11
+ </li>
12
+ <% end %>
13
+ </ul>
14
+ </nav>
15
+ </div>
16
+ <% end %>
17
+ <div class="toolbar">
18
+ <nav>
19
+ <ul>
20
+ <li class="back"><%= link_to "Cancel editing (lose unsaved changes)", admin_site_maps_path %></li>
21
+ </ul>
22
+ </nav>
23
+ <div class="actions">
24
+ <ul>
25
+ <li><a id="minimise" class="button">Minimise all slices</a></li>
26
+ <li>
27
+ <%= link_to_view_page(@page.source, id: 'page-view-on-site', target: 'site', class: 'button standard') %>
28
+ </li>
29
+ <li><input type="submit" value="Save changes" id="save-changes" disabled></li>
30
+ </ul>
31
+ </div>
16
32
  </div>
17
33
  </div>
18
34
 
@@ -0,0 +1,2 @@
1
+ <%= link_to_add_child page %>
2
+ <%= link_to_view_page page %>
@@ -1,20 +1,31 @@
1
- <li class="page <%= "home" if page.home? %>" rel="<%= page.id %>">
2
- <div>
1
+ <li class="<%= page_classes(page) %>" rel="<%= page.id %>">
2
+ <div class="page-item">
3
3
  <h2><%= link_to(page.name, admin_page_path(page)) %></h2>
4
4
 
5
5
  <% unless page.virtual? %>
6
6
  <span class="item-actions primary">
7
- <%= link_to_add_child page %>
8
- <%= link_to_view_page page %>
7
+ <%= render(
8
+ partial: Slices::Config.page_actions_template,
9
+ locals: { page: page }
10
+ ) %>
9
11
  </span>
10
12
 
11
13
  <%= link_to_delete page unless page.home? %>
12
14
  <% end %>
15
+
16
+ <% if page.home? %>
17
+ <div class="toggle-actions">
18
+ <a class="hide-all-children button">Minimise all</a>
19
+ <a class="show-all-children button">Expand all</a>
20
+ </div>
21
+ <% elsif children.any? %>
22
+ <a class="toggle-children" href="#page-<%= page.id %>-children"></a>
23
+ <% end %>
13
24
  </div>
14
25
 
15
- <% if page.children.any? %>
16
- <ol>
17
- <%= list_pages(page.children) %>
26
+ <% if children.any? %>
27
+ <ol id="page-<%= page.id %>-children" class="page-children">
28
+ <%= list_pages(children) %>
18
29
  </ol>
19
30
  <% end %>
20
31
  </li>
@@ -1,5 +1,5 @@
1
- <li class="set-page" rel="<%= page.id %>">
2
- <div>
1
+ <li class="<%= page_classes(page) %>" rel="<%= page.id %>">
2
+ <div class="page-item">
3
3
  <h2><%= link_to page.name, admin_page_entries_path(page) %></h2>
4
4
 
5
5
  <span class="item-actions primary">
@@ -15,9 +15,9 @@
15
15
 
16
16
  </div>
17
17
 
18
- <% if page.page_children.any? %>
19
- <ol>
20
- <%= list_pages page.page_children %>
18
+ <% if children.any? %>
19
+ <ol class="page-children">
20
+ <%= list_pages children %>
21
21
  </ol>
22
22
  <% end %>
23
23
  </li>
@@ -6,7 +6,6 @@
6
6
  <title><%= cms_title %></title>
7
7
 
8
8
  <%= stylesheet_link_tag 'slices/slices' %>
9
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
10
9
  <%= javascript_include_tag 'slices/slices' %>
11
10
  <%= render "admin/shared/asset_storage" %>
12
11
 
@@ -52,21 +51,5 @@
52
51
  <span class="path">{{path}}</span>
53
52
  </li>
54
53
  </script>
55
-
56
- <% if Rails.env.production? %>
57
- <script type="text/javascript">
58
- var _gaq = _gaq || [];
59
- _gaq.push(['_setAccount', 'UA-298580-55']);
60
- _gaq.push(['_setDomainName', 'none']);
61
- _gaq.push(['_setAllowLinker', true]);
62
- _gaq.push(['_setCustomVar', 1, 'Slices Version', '<%= Slices::VERSION %>', 3]);
63
- _gaq.push(['_trackPageview']);
64
- (function() {
65
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
66
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
67
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
68
- })();
69
- </script>
70
- <% end -%>
71
54
  </body>
72
55
  </html>
data/config/routes.rb CHANGED
@@ -1,21 +1,18 @@
1
1
  class PageConstraints
2
2
  def matches?(request)
3
- !request.path.start_with?("/admin/auth")
3
+ !request.path.start_with?('/admin/auth')
4
4
  end
5
5
  end
6
6
 
7
7
  Rails.application.routes.draw do
8
8
 
9
- devise_for :admin, :path => "admin", :controllers => {
10
- :passwords => "admin/auth/passwords",
11
- :sessions => "admin/auth/sessions",
12
- }
9
+ devise_for :admin, Slices::Config.devise_for_options
13
10
 
14
11
  namespace :admin do
15
- match 'site_maps' => 'site_maps#index', :as => :root # Devise redirects here after sign in
16
- match 'site_maps' => 'site_maps#index'
17
- match 'site_maps/update' => 'site_maps#update'
18
- match 'pages/search' => 'page_search#show'
12
+ get 'site_maps' => 'site_maps#index', as: :root # Devise redirects here after sign in
13
+ get 'site_maps' => 'site_maps#index'
14
+ put 'site_maps/update' => 'site_maps#update'
15
+ get 'pages/search' => 'page_search#show'
19
16
  resources :pages, :except => [:index, :edit] do
20
17
  resources :entries, :only => [:index]
21
18
  end
@@ -23,18 +20,18 @@ Rails.application.routes.draw do
23
20
  resources :snippets
24
21
  resources :admins
25
22
  end
26
- match '/admin' => redirect('/admin/site_maps')
23
+ get '/admin' => redirect('/admin/site_maps')
27
24
 
28
- match 'slices/templates(/:slice)/:name.:format' => 'static_assets#templates'
29
- match ':action/:asset_type(/:folder)/*name.:format' => 'static_assets',
25
+ get 'slices/templates(/:slice)/:name.:format' => 'static_assets#templates'
26
+ get ':action/:asset_type(/:folder)/*name.:format' => 'static_assets',
30
27
  :constraints => {
31
28
  :asset_type => /(stylesheets|javascripts|images)/,
32
29
  :action => /(slices|sites)/
33
30
  }, :as => :static_assets
34
31
 
35
- match ':status.html' => 'pages#virtual_error_pages'
36
- match '*path' => 'pages#create', :via => :post
37
- match '*path' => 'pages#show', :as => :page, :constraints => PageConstraints.new
32
+ get ':status.html' => 'pages#virtual_error_pages'
33
+ post '*path' => 'pages#create'
34
+ get '*path' => 'pages#show', as: :page, :constraints => PageConstraints.new
38
35
 
39
- root :to => 'pages#show'
36
+ root to: 'pages#show'
40
37
  end
@@ -18,25 +18,24 @@ class <%= page_name.classify %>Presenter < PagePresenter
18
18
  end
19
19
 
20
20
  <%- if options.with_entry_templates? -%>
21
- def main_extra_template
22
- '<%= file_name %>/<%= page_name %>_main'
21
+ def main_extra_templates
22
+ super + ['<%= file_name %>/<%= page_name %>_main']
23
23
  end
24
24
 
25
- def meta_extra_template
26
- '<%= file_name %>/<%= page_name %>_meta'
25
+ def meta_extra_templates
26
+ super + ['<%= file_name %>/<%= page_name %>_meta']
27
27
  end
28
28
  <%- else -%>
29
- # If you want to display extra information while editing or creating a
30
- # page (i.e. in the admin UI's side bar) you'll need to define some
31
- # .hbs files, and then tell the CMS to use them by uncommenting these
32
- # methods.
29
+ # If you want to display extra information while editing a page you'll need
30
+ # to define some .hbs files, and then tell the CMS to use them by
31
+ # uncommenting these methods.
33
32
 
34
- # def main_extra_template
35
- # '<%= file_name %>/<%= page_name %>_main'
33
+ # def main_extra_templates
34
+ # super + ['<%= file_name %>/<%= page_name %>_main']
36
35
  # end
37
36
 
38
- # def meta_extra_template
39
- # '<%= file_name %>/<%= page_name %>_meta'
37
+ # def meta_extra_templates
38
+ # super + ['<%= file_name %>/<%= page_name %>_meta']
40
39
  # end
41
40
  <%- end -%>
42
41
 
@@ -1,8 +1,8 @@
1
- <%%= will_paginate slice.page_entries, renderer: SetLinkRenderer, class: 'pagination above' %>
1
+ <%%= will_paginate slice.page_entries, class: 'pagination above' %>
2
2
  <ul class="entries">
3
3
  <%% slice.page_entries.each do |entry| -%>
4
4
  <li><%%= link_to entry.name, entry.path %></li>
5
5
  <%% end -%>
6
6
  </ul>
7
- <%%= will_paginate slice.page_entries, renderer: SetLinkRenderer, class: 'pagination below' %>
7
+ <%%= will_paginate slice.page_entries, class: 'pagination below' %>
8
8