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
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require 'rails/generators'
4
2
  require 'thor'
5
3
 
@@ -24,8 +22,20 @@ module Slices
24
22
  copy_file "application.html.erb", "app/views/layouts/default.html.erb"
25
23
  end
26
24
 
25
+ def create_admin_nav_partials
26
+ create_file "app/views/admin/shared/_custom_navigation.html.erb", <<-END
27
+ <%# Place custom navbar controls here i.e. %>
28
+ <%#= admin_nav_link 'Example', example_path %>
29
+ END
30
+
31
+ create_file "app/views/admin/shared/_custom_links.html.erb", <<-END
32
+ <%# Place custom navbar links here i.e. %>
33
+ <%#= content_tag :li, link_to('Example', example_path) %>
34
+ END
35
+ end
36
+
27
37
  def optionally_create_mongoid_yaml
28
- copy_file "mongoid.yml", "config/mongoid.yml"
38
+ generate 'mongoid:config'
29
39
  end
30
40
 
31
41
  def delete_superfluous_files
@@ -3,9 +3,8 @@
3
3
  # avatar: '30x30#',
4
4
  # )
5
5
 
6
- # Configure the Google Apps domain to use for quick auth.
7
- # Press the '=' key on the admin sign-in screen to authenticate via
8
- # a Google Apps account within the domain configured here.
9
- # Slices::Config.google_apps_domain = 'example.com'
6
+ # Configure templates for new page fields and page actions
7
+ # Slices::Config.page_fields_template = 'slices/page_fields'
8
+ # Slices::Config.page_actions_template = 'slices/page_actions'
10
9
 
11
10
  ActionView::Base.send(:include, AssetsHelper)
data/lib/mongo_search.rb CHANGED
@@ -29,7 +29,7 @@ module MongoSearch
29
29
  self.search_fields = args
30
30
 
31
31
  field :_keywords, type: Array
32
- index :_keywords
32
+ index({ _keywords: 1 }, { background: true })
33
33
 
34
34
  before_save :set_keywords
35
35
  end
data/lib/slices.rb CHANGED
@@ -2,6 +2,7 @@ require 'devise'
2
2
  require 'devise/orm/mongoid'
3
3
  require 'mongoid'
4
4
  require 'mongoid_paperclip'
5
+ require 'will_paginate_mongoid'
5
6
  require 'RedCloth'
6
7
  require 'redcarpet'
7
8
  require 'stringex'
@@ -10,8 +11,6 @@ require 'slices/paperclip'
10
11
  require 'slices/version'
11
12
 
12
13
  require 'mongo_search'
13
- require 'ext/file_store_cache'
14
-
15
14
  module Slices
16
15
  autoload :Config, 'slices/config'
17
16
  autoload :CmsFormBuilder, 'slices/cms_form_builder'
@@ -20,6 +19,7 @@ module Slices
20
19
  autoload :GeneratorMacros, 'slices/generator_macros'
21
20
  autoload :HasSlices, 'slices/has_slices'
22
21
  autoload :HasAttachments, 'slices/has_attachments'
22
+ autoload :LocalizedFields, 'slices/localized_fields'
23
23
  autoload :PageAsJSON, 'slices/page_as_json'
24
24
  autoload :Renderer, 'slices/renderer'
25
25
  autoload :PositionHelper, 'slices/position_helper'
@@ -45,17 +45,10 @@ module Slices
45
45
  end
46
46
 
47
47
  require 'slices/engine' if defined?(Rails)
48
- require 'slices/i18n'
49
- require 'slices/will_paginate_mongoid'
50
48
  require 'slices/will_paginate'
51
- require 'set_link_renderer'
52
49
 
53
50
  Slices::Config.use_snippets!
54
51
 
55
- if Rails.env.test? || Rails.env.development?
56
- require 'standard_tree'
57
- end
58
-
59
52
  Mime::Type.register_alias 'text/plain', :hbs
60
53
  Time::DATE_FORMATS.merge!(
61
54
  day_month_year: '%d %B %Y'
@@ -17,9 +17,9 @@ module Slices
17
17
  end
18
18
 
19
19
  def find_matching_asset(new_asset)
20
- ::Asset.first(conditions: {
20
+ ::Asset.where({
21
21
  file_fingerprint: new_asset.file_fingerprint, :_id.ne => new_asset.id
22
- })
22
+ }).first
23
23
  end
24
24
 
25
25
  def tempfile_stored_on_s3?
@@ -44,7 +44,6 @@ module Slices
44
44
 
45
45
  if matching_asset.present?
46
46
  new_asset.destroy
47
- matching_asset.soft_restore!
48
47
  matching_asset
49
48
  else
50
49
  new_asset
@@ -29,7 +29,14 @@ module Slices
29
29
 
30
30
  klass.fields.each do |name, field|
31
31
  next if Slice.fields[name]
32
- fields[name] = field.default
32
+ fields[name] = field.default_val
33
+ end
34
+
35
+ if klass.respond_to?(:attachment_fields)
36
+ klass.attachment_fields.each do |name|
37
+ meta = klass.reflect_on_association(name)
38
+ fields[name.to_s] = meta.many? ? [] : nil
39
+ end
33
40
  end
34
41
 
35
42
  slices << [basename, fields]
data/lib/slices/config.rb CHANGED
@@ -35,6 +35,13 @@ module Slices
35
35
  @snippets || false
36
36
  end
37
37
 
38
+ def self.i18n?
39
+ !!(
40
+ I18n.available_locales.many? ||
41
+ Rails.application.config.i18n.available_locales.try(:many?)
42
+ )
43
+ end
44
+
38
45
  def self.s3_storage?
39
46
  Paperclip::Attachment.default_options[:storage].to_sym == :fog
40
47
  end
@@ -57,18 +64,52 @@ module Slices
57
64
  }
58
65
  end
59
66
 
60
- # Google Apps domain for quick auth.
67
+ # Page fields template path.
68
+ #
69
+ # @return [String] the path
70
+ def self.page_fields_template
71
+ @page_fields_template || 'admin/pages/fields'
72
+ end
73
+
74
+ # Set page fields template path.
75
+ #
76
+ # @param [String] the path
77
+ def self.page_fields_template=(path)
78
+ @page_fields_template = path
79
+ end
80
+
81
+ # Page actions template path.
61
82
  #
62
- # @return [String] the domain
63
- def self.google_apps_domain
64
- @google_apps_domain
83
+ # @return [String] the path
84
+ def self.page_actions_template
85
+ @page_actions_template || 'admin/site_maps/page_actions'
86
+ end
87
+
88
+ # Set page actions template path.
89
+ #
90
+ # @param [String] the path
91
+ def self.page_actions_template=(path)
92
+ @page_actions_template = path
93
+ end
94
+
95
+ # Options for devise_for.
96
+ #
97
+ # @return [Hash] the options
98
+ def self.devise_for_options
99
+ @devise_options ||= {
100
+ path: 'admin',
101
+ controllers: {
102
+ passwords: 'admin/auth/passwords',
103
+ sessions: 'admin/auth/sessions',
104
+ }
105
+ }
65
106
  end
66
107
 
67
- # Set Google Apps domain for quick auth.
108
+ # Set options for devise_for.
68
109
  #
69
- # @param [String] the domain
70
- def self.google_apps_domain=(domain)
71
- @google_apps_domain = domain
110
+ # @param [Hash] the options
111
+ def self.devise_for_options=(options = {})
112
+ @devise_options = options
72
113
  end
73
114
 
74
115
  private
data/lib/slices/engine.rb CHANGED
@@ -9,10 +9,6 @@ module Slices
9
9
  config.mongoid.observers.concat [:page_observer, :asset_observer]
10
10
  end
11
11
 
12
- initializer :slices_will_paginate_active_view, after: 'will_paginate.action_view' do
13
- load Slices.gem_path + '/lib/set_link_renderer.rb'
14
- end
15
-
16
12
  initializer :slices_precompile_hook do |app|
17
13
  app.config.assets.precompile += %w(slices/slices.css slices/slices.js)
18
14
  end
@@ -5,32 +5,8 @@ module Slices
5
5
  module ClassMethods
6
6
 
7
7
  def has_attachments(embed_name = :attachments, options = {})
8
- klass = if options.has_key?(:class_name)
9
- options[:class_name].constantize
10
- else
11
- Attachment
12
- end
13
-
14
- default = options[:default] || options[:singular] ? nil : []
15
- type = options[:singular] ? Hash : Array
16
-
17
- if options[:singular]
18
- define_method embed_name do
19
- if embed = read_attribute(embed_name)
20
- klass.new embed
21
- end
22
- end
23
- else
24
- define_method embed_name do
25
- (read_attribute(embed_name) || []).collect do |embed|
26
- klass.new embed
27
- end
28
- end
29
- end
30
-
31
8
  attachment_fields << embed_name
32
-
33
- field embed_name, type: type, default: default
9
+ embeds_many embed_name, {class_name: "Attachment", as: :object}.merge(options)
34
10
  end
35
11
 
36
12
  def attachment_fields
@@ -44,11 +20,10 @@ module Slices
44
20
  end
45
21
 
46
22
  module PageInstanceMethods
47
-
48
23
  def attachment_assets
49
24
  attachment_asset_ids.inject([]) do |memo, asset_id|
50
25
  begin
51
- memo << ::Asset.find(asset_id)
26
+ memo << ::Asset.find(asset_id.to_s)
52
27
  rescue Mongoid::Errors::DocumentNotFound
53
28
  end
54
29
  memo
@@ -68,6 +43,17 @@ module Slices
68
43
  end
69
44
  alias :attachment_asset_ids :slice_attachment_asset_ids
70
45
 
46
+ def remove_asset(asset)
47
+ remove_asset_from_slices(asset)
48
+ end
49
+
50
+ def remove_asset_from_slices(asset)
51
+ slices.each { |slice|
52
+ if slice.respond_to?(:remove_asset)
53
+ slice.remove_asset(asset)
54
+ end
55
+ }
56
+ end
71
57
  end
72
58
 
73
59
  def as_json options = nil
@@ -76,14 +62,7 @@ module Slices
76
62
 
77
63
  def attachments_as_json
78
64
  self.class.attachment_fields.inject({}) do |hash, name|
79
- value = send name
80
-
81
- hash[name] = if value.respond_to?(:map)
82
- value.map &:as_json
83
- else
84
- value.as_json
85
- end
86
-
65
+ hash[name] = send(name).map(&:as_json)
87
66
  hash
88
67
  end
89
68
  end
@@ -105,7 +84,16 @@ module Slices
105
84
  end.flat_map {|i| i }
106
85
  end
107
86
 
108
- end
87
+ def remove_asset(asset)
88
+ super if defined?(super)
109
89
 
110
- end
90
+ asset_id = asset.id
111
91
 
92
+ self.class.attachment_fields.each do |field_name|
93
+ send(field_name).each do |attachment|
94
+ attachment.destroy if attachment.asset_id == asset_id
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -27,15 +27,22 @@ module Slices
27
27
  end
28
28
 
29
29
  def update_attributes(attributes)
30
- [:slices, :set_slices].each do |type|
31
- next if attributes[type].nil?
30
+ [:slices, :set_slices].each do |embed_name|
31
+ next if attributes[embed_name].nil?
32
32
 
33
- attributes[type] = attributes[type].map { |slice|
34
- slice = slice.symbolize_keys
35
- next if slice[:_destroy]
36
- slice.delete :_new
37
- klass = (slice[:type] + '_slice').camelize.constantize
38
- klass.new(slice)
33
+ attributes[embed_name] = attributes[embed_name].map { |slice_attributes|
34
+ slice_attributes = slice_attributes.symbolize_keys
35
+ next if slice_attributes[:_destroy]
36
+ slice_attributes.delete :_new
37
+
38
+ if slice_attributes[:id].present?
39
+ slice = slices_for(embed_name).find(slice_attributes[:id])
40
+ slice.write_attributes(slice_attributes)
41
+ else
42
+ class_name = slice_attributes[:type].to_s.camelize + 'Slice'
43
+ slice = class_name.constantize.new(slice_attributes)
44
+ end
45
+ slice
39
46
  }.compact
40
47
  end
41
48
 
@@ -0,0 +1,9 @@
1
+ module Slices
2
+ module LocalizedFields
3
+ def localized_field_names
4
+ fields.select { |name, field| field.localized? }.map do |name, field|
5
+ name.to_sym
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,10 +1,12 @@
1
1
  module Slices
2
2
  # We keep this method in here to facilate easier overriding when re-opening Page.
3
3
  module PageAsJSON
4
+ include Slices::LocalizedFields
5
+
4
6
  def as_json(options = {})
5
7
  options ||= {}
6
8
 
7
- hash = attributes.symbolize_keys.except(:_id, :_type, :_keywords, :set_slices, :site_id).merge(
9
+ hash = attributes.symbolize_keys.except(:_id, :_type, :_keywords, :set_slices).merge(
8
10
  id: id,
9
11
  permalink: permalink,
10
12
  slices: ordered_slices_for(options[:slice_embed]).map {|slice| slice.as_json },
@@ -12,6 +14,10 @@ module Slices
12
14
  author: author
13
15
  )
14
16
 
17
+ localized_field_names.each do |name|
18
+ hash.merge!(name => send(name))
19
+ end
20
+
15
21
  keys = options[:only]
16
22
  keys ? hash.slice(keys) : hash
17
23
  end
@@ -27,8 +27,8 @@ module Slices
27
27
  render_slices slices.where(container: container)
28
28
  end
29
29
 
30
- def render_to_string(*args)
31
- @controller.render_to_string(*args)
30
+ def render_to_string(template, options)
31
+ @controller.render_to_string(template, { layout: nil }.merge(options))
32
32
  end
33
33
 
34
34
  def fragment_exist?(cache_key)
data/lib/slices/tree.rb CHANGED
@@ -39,8 +39,8 @@ module Slices
39
39
  field :position, type: Integer
40
40
  field :show_in_nav, type: Boolean, default: false
41
41
 
42
- scope :minimal, only: %w(page_id path external_url name has_content)
43
- index :path
42
+ scope :minimal, ->{ only(%w(_type page_id path external_url name has_content)) }
43
+ index({ path: 1 }, { unique: true })
44
44
 
45
45
  belongs_to :page
46
46
 
@@ -66,7 +66,9 @@ module Slices
66
66
  # @return [Page]
67
67
  #
68
68
  def find_by_path(path)
69
- first(conditions: { path: path }) || (raise Page::NotFound.new(path))
69
+ find_by(path: path)
70
+ rescue Mongoid::Errors::DocumentNotFound
71
+ raise Page::NotFound.new(path)
70
72
  end
71
73
  alias :f :find_by_path
72
74
 
@@ -279,6 +281,13 @@ module Slices
279
281
  end
280
282
  end
281
283
 
284
+ # Don't store permalink
285
+ #
286
+ # @return nil
287
+ #
288
+ def permalink=(args)
289
+ end
290
+
282
291
  private
283
292
 
284
293
  # Make sure that a page's path is unique amoungst it's siblings, if there is
@@ -1,4 +1,4 @@
1
1
  module Slices
2
- VERSION = '1.0.5'
2
+ VERSION = '2.0.0'
3
3
  end
4
4
 
data/lib/tasks/db.rake CHANGED
@@ -1,16 +1,12 @@
1
1
  module Slices
2
2
  module Tasks
3
3
  def self.create_indexes
4
- [
5
- Slices.gem_path + '/app/models/**/*.rb',
6
- Rails.root.join('app/slices/**/*.rb')
7
- ].each do |pattern|
8
- Dir.glob(pattern).each do |file|
9
- model = determine_model(file)
10
- if model
11
- model.create_indexes
12
- Logger.new($stdout).info("Generated indexes for #{model}")
13
- end
4
+ pattern = Rails.root.join('app/slices/**/*.rb')
5
+ Dir.glob(pattern).each do |file|
6
+ model = determine_model(file)
7
+ if model
8
+ model.create_indexes
9
+ Logger.new($stdout).info("Generated indexes for #{model}")
14
10
  end
15
11
  end
16
12
  end