slices 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +3 -0
- data/README.md +51 -0
- data/Rakefile +9 -0
- data/app/assets/images/slices/ajax-loader.gif +0 -0
- data/app/assets/images/slices/asset-background.png +0 -0
- data/app/assets/images/slices/asset-spinner.gif +0 -0
- data/app/assets/images/slices/bg_header.gif +0 -0
- data/app/assets/images/slices/black-Linen.png +0 -0
- data/app/assets/images/slices/calendar.svg +68 -0
- data/app/assets/images/slices/chosen-sprite.png +0 -0
- data/app/assets/images/slices/drag-handle.svg +9 -0
- data/app/assets/images/slices/icon_admins.png +0 -0
- data/app/assets/images/slices/icon_app.png +0 -0
- data/app/assets/images/slices/icon_assets.png +0 -0
- data/app/assets/images/slices/icon_collapse.png +0 -0
- data/app/assets/images/slices/icon_drag.png +0 -0
- data/app/assets/images/slices/icon_files.png +0 -0
- data/app/assets/images/slices/icon_generic_file.png +0 -0
- data/app/assets/images/slices/icon_images.png +0 -0
- data/app/assets/images/slices/icon_padlock.png +0 -0
- data/app/assets/images/slices/icon_page.png +0 -0
- data/app/assets/images/slices/icon_search.png +0 -0
- data/app/assets/images/slices/icon_set-link.png +0 -0
- data/app/assets/images/slices/icon_set.png +0 -0
- data/app/assets/images/slices/icon_sitemap.png +0 -0
- data/app/assets/images/slices/icon_snippets.png +0 -0
- data/app/assets/images/slices/icon_template.jpg +0 -0
- data/app/assets/images/slices/icon_upload_happy.png +0 -0
- data/app/assets/images/slices/icon_upload_sad.png +0 -0
- data/app/assets/images/slices/icon_upload_thinking.png +0 -0
- data/app/assets/images/slices/noise.png +0 -0
- data/app/assets/images/slices/sitemap_icon_ghost.png +0 -0
- data/app/assets/images/slices/sitemap_icon_home.png +0 -0
- data/app/assets/images/slices/sitemap_icon_page.png +0 -0
- data/app/assets/images/slices/sitemap_icon_set_page.png +0 -0
- data/app/assets/images/slices/sitemap_icon_virtual_page.png +0 -0
- data/app/assets/images/slices/sitemap_overlay.png +0 -0
- data/app/assets/images/slices/spinner.gif +0 -0
- data/app/assets/images/slices/trash.png +0 -0
- data/app/assets/javascripts/admin.js.erb +18 -0
- data/app/assets/javascripts/slices/app/backbones/admins.js +114 -0
- data/app/assets/javascripts/slices/app/backbones/entries.js +172 -0
- data/app/assets/javascripts/slices/app/backbones/generic.js +101 -0
- data/app/assets/javascripts/slices/app/backbones/snippets.js +113 -0
- data/app/assets/javascripts/slices/app/helpers/assets.js +61 -0
- data/app/assets/javascripts/slices/app/helpers/breadcrumbs.js +30 -0
- data/app/assets/javascripts/slices/app/helpers/composer.js +26 -0
- data/app/assets/javascripts/slices/app/helpers/date_field.js +16 -0
- data/app/assets/javascripts/slices/app/helpers/get_value.js +31 -0
- data/app/assets/javascripts/slices/app/helpers/icon_upload_names.js.erb +5 -0
- data/app/assets/javascripts/slices/app/helpers/layout.js +20 -0
- data/app/assets/javascripts/slices/app/helpers/sitemap.js +150 -0
- data/app/assets/javascripts/slices/app/helpers/slice_preview.js +48 -0
- data/app/assets/javascripts/slices/app/helpers/tagging.js +73 -0
- data/app/assets/javascripts/slices/app/helpers/token_field.js +17 -0
- data/app/assets/javascripts/slices/app/helpers/upload_icons.js.erb +5 -0
- data/app/assets/javascripts/slices/app/helpers/uploader.js +127 -0
- data/app/assets/javascripts/slices/app/models/asset.js +29 -0
- data/app/assets/javascripts/slices/app/models/asset_collection.js +41 -0
- data/app/assets/javascripts/slices/app/models/attachment.js +29 -0
- data/app/assets/javascripts/slices/app/models/attachment_collection.js +7 -0
- data/app/assets/javascripts/slices/app/models/composer_item.js +1 -0
- data/app/assets/javascripts/slices/app/models/composer_item_collection.js +3 -0
- data/app/assets/javascripts/slices/app/models/file.js +103 -0
- data/app/assets/javascripts/slices/app/models/page.js +186 -0
- data/app/assets/javascripts/slices/app/models/s3_file.js +64 -0
- data/app/assets/javascripts/slices/app/slices.js +661 -0
- data/app/assets/javascripts/slices/app/views/asset_editor_view.js.erb +209 -0
- data/app/assets/javascripts/slices/app/views/asset_library_view.js +720 -0
- data/app/assets/javascripts/slices/app/views/asset_thumb_view.js.erb +191 -0
- data/app/assets/javascripts/slices/app/views/attachment_composer_view.js +350 -0
- data/app/assets/javascripts/slices/app/views/attachment_view.js +101 -0
- data/app/assets/javascripts/slices/app/views/calendar_view.js +198 -0
- data/app/assets/javascripts/slices/app/views/composer_item_view.js +54 -0
- data/app/assets/javascripts/slices/app/views/composer_view.js +130 -0
- data/app/assets/javascripts/slices/app/views/date_field_view.js +177 -0
- data/app/assets/javascripts/slices/app/views/file_view.js +142 -0
- data/app/assets/javascripts/slices/app/views/token_field_view.js +253 -0
- data/app/assets/javascripts/slices/lib/freeze.js +14 -0
- data/app/assets/javascripts/slices/lib/human_file_size.js +16 -0
- data/app/assets/javascripts/slices/lib/json_patch.js +9 -0
- data/app/assets/javascripts/slices/lib/moment.js +47 -0
- data/app/assets/javascripts/slices/lib/plugins.js +101 -0
- data/app/assets/javascripts/slices/lib/sortable.js +14 -0
- data/app/assets/javascripts/slices/slices.js +27 -0
- data/app/assets/javascripts/slices/vendor/autoscroll.js +188 -0
- data/app/assets/javascripts/slices/vendor/backbone.js +38 -0
- data/app/assets/javascripts/slices/vendor/handlebars.js +1920 -0
- data/app/assets/javascripts/slices/vendor/jqmodal.js +69 -0
- data/app/assets/javascripts/slices/vendor/jquery-ui.js +274 -0
- data/app/assets/javascripts/slices/vendor/jquery-ui_nested-sortable.js +357 -0
- data/app/assets/javascripts/slices/vendor/jquery.ajaxprogress.js +76 -0
- data/app/assets/javascripts/slices/vendor/jquery.js +2 -0
- data/app/assets/javascripts/slices/vendor/livefield.js +459 -0
- data/app/assets/javascripts/slices/vendor/moment.js +6 -0
- data/app/assets/javascripts/slices/vendor/rails.js +315 -0
- data/app/assets/javascripts/slices/vendor/underscore-string.js +1 -0
- data/app/assets/javascripts/slices/vendor/underscore.js +5 -0
- data/app/assets/stylesheets/admin.css +1 -0
- data/app/assets/stylesheets/slices/admin.css.erb +2237 -0
- data/app/assets/stylesheets/slices/reset_html5.css +106 -0
- data/app/assets/stylesheets/slices/slices.css +7 -0
- data/app/controllers/admin/admin_controller.rb +10 -0
- data/app/controllers/admin/admins_controller.rb +76 -0
- data/app/controllers/admin/assets_controller.rb +53 -0
- data/app/controllers/admin/auth/omniauth_callbacks_controller.rb +15 -0
- data/app/controllers/admin/auth/passwords_controller.rb +4 -0
- data/app/controllers/admin/auth/sessions_controller.rb +4 -0
- data/app/controllers/admin/entries_controller.rb +88 -0
- data/app/controllers/admin/page_search_controller.rb +12 -0
- data/app/controllers/admin/pages_controller.rb +103 -0
- data/app/controllers/admin/site_maps_controller.rb +15 -0
- data/app/controllers/admin/snippets_controller.rb +33 -0
- data/app/controllers/application_controller.rb +4 -0
- data/app/controllers/pages_controller.rb +45 -0
- data/app/controllers/slices_controller.rb +63 -0
- data/app/controllers/static_assets_controller.rb +52 -0
- data/app/helpers/admin/admin_helper.rb +63 -0
- data/app/helpers/admin/assets_helper.rb +36 -0
- data/app/helpers/admin/entries_helper.rb +13 -0
- data/app/helpers/admin/site_maps_helper.rb +104 -0
- data/app/helpers/assets_helper.rb +64 -0
- data/app/helpers/navigation_helper.rb +195 -0
- data/app/helpers/pages_helper.rb +119 -0
- data/app/models/admin.rb +34 -0
- data/app/models/asset.rb +211 -0
- data/app/models/attachment.rb +11 -0
- data/app/models/layout.rb +44 -0
- data/app/models/page.rb +214 -0
- data/app/models/placeholder_slice.rb +8 -0
- data/app/models/set_page.rb +12 -0
- data/app/models/set_slice.rb +57 -0
- data/app/models/site_map.rb +24 -0
- data/app/models/slice.rb +80 -0
- data/app/models/snippet.rb +21 -0
- data/app/observers/asset_observer.rb +6 -0
- data/app/observers/page_observer.rb +37 -0
- data/app/presenters/entry_presenter.rb +17 -0
- data/app/presenters/page_presenter.rb +67 -0
- data/app/presenters/presenter.rb +9 -0
- data/app/presenters/set_page_presenter.rb +2 -0
- data/app/views/admin/admins/index.html.erb +26 -0
- data/app/views/admin/admins/show.html.erb +27 -0
- data/app/views/admin/assets/index.html.erb +1 -0
- data/app/views/admin/auth/passwords/edit.html.erb +20 -0
- data/app/views/admin/auth/passwords/new.html.erb +14 -0
- data/app/views/admin/auth/sessions/_form.html.erb +35 -0
- data/app/views/admin/auth/sessions/new.html.erb +14 -0
- data/app/views/admin/entries/index.html.erb +32 -0
- data/app/views/admin/pages/_breadcrumbs.html.erb +32 -0
- data/app/views/admin/pages/_slices.html.erb +27 -0
- data/app/views/admin/pages/new.html.erb +14 -0
- data/app/views/admin/pages/show.html.erb +50 -0
- data/app/views/admin/shared/_asset_storage.html.erb +17 -0
- data/app/views/admin/shared/_custom_links.html.erb +1 -0
- data/app/views/admin/shared/_custom_navigation.html.erb +1 -0
- data/app/views/admin/shared/_navigation.html.erb +5 -0
- data/app/views/admin/site_maps/_page_li.html.erb +20 -0
- data/app/views/admin/site_maps/_set_page_li.html.erb +23 -0
- data/app/views/admin/site_maps/index.html.erb +29 -0
- data/app/views/admin/snippets/form.html.erb +12 -0
- data/app/views/admin/snippets/index.html.erb +20 -0
- data/app/views/admin/snippets/update.html.erb +0 -0
- data/app/views/layouts/admin.html.erb +72 -0
- data/lib/ext/file_store_cache.rb +18 -0
- data/lib/generators/humans/USAGE +8 -0
- data/lib/generators/humans/humans_generator.rb +10 -0
- data/lib/generators/humans/templates/humans.txt +6 -0
- data/lib/generators/slice/USAGE +28 -0
- data/lib/generators/slice/slice_generator.rb +123 -0
- data/lib/generators/slice/templates/main_fields.hbs +11 -0
- data/lib/generators/slice/templates/meta_fields.hbs +11 -0
- data/lib/generators/slice/templates/page.rb +19 -0
- data/lib/generators/slice/templates/presenter.rb +53 -0
- data/lib/generators/slice/templates/set.html.erb +8 -0
- data/lib/generators/slice/templates/set_slice.rb +14 -0
- data/lib/generators/slice/templates/set_slice_fields.hbs +5 -0
- data/lib/generators/slice/templates/show.html.erb +48 -0
- data/lib/generators/slice/templates/show_slice.rb +20 -0
- data/lib/generators/slice/templates/slice.rb +58 -0
- data/lib/generators/slice/templates/slice_fields.hbs +74 -0
- data/lib/generators/templates/slices.rb +211 -0
- data/lib/mongo_search.rb +84 -0
- data/lib/paperclip_validator.rb +5 -0
- data/lib/rack_utf8_fix.rb +10 -0
- data/lib/sRGB.icc +0 -0
- data/lib/set_link_renderer.rb +31 -0
- data/lib/slices.rb +68 -0
- data/lib/slices/asset/maker.rb +55 -0
- data/lib/slices/asset/rename.rb +67 -0
- data/lib/slices/available_slices.rb +43 -0
- data/lib/slices/cms_form_builder.rb +42 -0
- data/lib/slices/config.rb +93 -0
- data/lib/slices/container_parser.rb +70 -0
- data/lib/slices/generator_macros.rb +36 -0
- data/lib/slices/has_attachments.rb +111 -0
- data/lib/slices/has_slices.rb +88 -0
- data/lib/slices/i18n.rb +6 -0
- data/lib/slices/i18n/backend.rb +32 -0
- data/lib/slices/i18n_backend.rb +24 -0
- data/lib/slices/paperclip.rb +13 -0
- data/lib/slices/position_helper.rb +98 -0
- data/lib/slices/renderer.rb +52 -0
- data/lib/slices/slices_engine.rb +51 -0
- data/lib/slices/split_date_time_field.rb +14 -0
- data/lib/slices/tasks/assets.rake +35 -0
- data/lib/slices/tasks/db.rake +50 -0
- data/lib/slices/tasks/seeds.rake +93 -0
- data/lib/slices/tasks/validate.rake +62 -0
- data/lib/slices/tree.rb +306 -0
- data/lib/slices/version.rb +4 -0
- data/lib/slices/will_paginate.rb +12 -0
- data/lib/slices/will_paginate_mongoid.rb +45 -0
- data/lib/standard_tree.rb +193 -0
- metadata +483 -0
data/lib/mongo_search.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module MongoSearch
|
2
|
+
class KeywordsExtractor
|
3
|
+
def self.extract(text)
|
4
|
+
if text.blank?
|
5
|
+
[]
|
6
|
+
else
|
7
|
+
text.mb_chars.normalize(:kd).to_s
|
8
|
+
.gsub(/[^\x00-\x7F]/,'')
|
9
|
+
.downcase
|
10
|
+
.split(/[\s\.\-_]+/)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Searchable
|
16
|
+
extend ActiveSupport::Concern
|
17
|
+
|
18
|
+
included do
|
19
|
+
cattr_accessor :search_fields, :match
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def text_search_in(*args)
|
24
|
+
options = args.pop if args.last.has_key?(:match)
|
25
|
+
self.match = options[:match]
|
26
|
+
rescue NoMethodError
|
27
|
+
ensure
|
28
|
+
self.match ||= :all
|
29
|
+
self.search_fields = args
|
30
|
+
|
31
|
+
field :_keywords, type: Array
|
32
|
+
index :_keywords
|
33
|
+
|
34
|
+
before_save :set_keywords
|
35
|
+
end
|
36
|
+
|
37
|
+
def search_in(*args)
|
38
|
+
warn('[DEPRECATION `search_in` is deprecated. Please use `text_search_in` instead.')
|
39
|
+
text_search_in(args)
|
40
|
+
end
|
41
|
+
|
42
|
+
def text_search(query)
|
43
|
+
words = KeywordsExtractor.extract(query).map { |word| /#{word}/ }
|
44
|
+
self.send("#{self.match}_in", _keywords: words)
|
45
|
+
end
|
46
|
+
|
47
|
+
def search(query)
|
48
|
+
warn("[DEPRECATION] `search` is deprecated. Please use `text_search` instead.")
|
49
|
+
text_search(query)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def set_keywords
|
55
|
+
self._keywords = []
|
56
|
+
search_fields.each do |field|
|
57
|
+
if field.respond_to?(:each)
|
58
|
+
field.each do |name, attribute|
|
59
|
+
extract_keywords_for_association(name, attribute)
|
60
|
+
end
|
61
|
+
elsif respond_to?(field)
|
62
|
+
extract_keywords(send(field))
|
63
|
+
else
|
64
|
+
extract_keywords(self[field])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
self._keywords.uniq!
|
68
|
+
end
|
69
|
+
|
70
|
+
def extract_keywords(text)
|
71
|
+
self._keywords += KeywordsExtractor.extract(text) unless text.nil?
|
72
|
+
end
|
73
|
+
|
74
|
+
def extract_keywords_for_association(name, attribute)
|
75
|
+
association = send(name)
|
76
|
+
return [] if association.nil?
|
77
|
+
if association.respond_to?(:each)
|
78
|
+
association.each { |doc| extract_keywords(doc[attribute]) }
|
79
|
+
else
|
80
|
+
extract_keywords(association[attribute])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/lib/sRGB.icc
ADDED
Binary file
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'will_paginate/view_helpers/action_view'
|
2
|
+
|
3
|
+
class SetLinkRenderer < WillPaginate::ViewHelpers::LinkRenderer
|
4
|
+
protected
|
5
|
+
# This method has been largely robbed from will_paginate's
|
6
|
+
# lib/will_paginate/view_helpers/action_view.rb file, whose
|
7
|
+
# implementation only differs in that it assumes that you're using
|
8
|
+
# controller: 'foo', action: 'bar' compatible routes.
|
9
|
+
#
|
10
|
+
def url(page)
|
11
|
+
@base_url_params ||= begin
|
12
|
+
url_params = base_url_params
|
13
|
+
merge_optional_params(url_params)
|
14
|
+
url_params
|
15
|
+
end
|
16
|
+
|
17
|
+
url_params = @base_url_params.dup
|
18
|
+
path = url_params.delete(:path)
|
19
|
+
add_current_page_param(url_params, page)
|
20
|
+
remove_unwanted_params(url_params)
|
21
|
+
if url_params.empty?
|
22
|
+
"/#{path}"
|
23
|
+
else
|
24
|
+
"/#{path}?" + url_params.map { |k, v| "#{k}=#{v}" }.join('&')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def remove_unwanted_params(url_params)
|
29
|
+
[:controller, :action, :escape].each { |p| url_params.delete(p) }
|
30
|
+
end
|
31
|
+
end
|
data/lib/slices.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'bson'
|
3
|
+
require 'devise'
|
4
|
+
require 'mongo'
|
5
|
+
require 'mongoid'
|
6
|
+
require 'mongoid_paperclip'
|
7
|
+
require 'RedCloth'
|
8
|
+
require 'redcarpet'
|
9
|
+
require 'stringex'
|
10
|
+
|
11
|
+
require 'slices/paperclip'
|
12
|
+
require 'slices/version'
|
13
|
+
|
14
|
+
require 'mongo_search'
|
15
|
+
require 'ext/file_store_cache'
|
16
|
+
|
17
|
+
module Slices
|
18
|
+
autoload :Config, 'slices/config'
|
19
|
+
autoload :CmsFormBuilder, 'slices/cms_form_builder'
|
20
|
+
autoload :AvailableSlices, 'slices/available_slices'
|
21
|
+
autoload :ContainerParser, 'slices/container_parser'
|
22
|
+
autoload :GeneratorMacros, 'slices/generator_macros'
|
23
|
+
autoload :HasSlices, 'slices/has_slices'
|
24
|
+
autoload :HasAttachments, 'slices/has_attachments'
|
25
|
+
autoload :Renderer, 'slices/renderer'
|
26
|
+
autoload :PositionHelper, 'slices/position_helper'
|
27
|
+
autoload :SplitDateTimeField, 'slices/split_date_time_field'
|
28
|
+
autoload :Tree, 'slices/tree'
|
29
|
+
|
30
|
+
module Asset
|
31
|
+
autoload :Maker, 'slices/asset/maker'
|
32
|
+
autoload :Rename, 'slices/asset/rename'
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.gem_path
|
36
|
+
File.expand_path('..', File.dirname(__FILE__))
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.load_slice_classes_into_object_space(root)
|
40
|
+
Dir.glob(File.join(root, 'app', 'slices', '**/*.rb')).each do |file|
|
41
|
+
constant = File.basename(file, '.rb').camelize
|
42
|
+
Object.const_get(constant)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.test_environment?
|
47
|
+
Rails.env.test? && Rails.root.to_s == Slices.gem_path
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'slices/slices_engine' if defined?(Rails)
|
53
|
+
require 'slices/i18n'
|
54
|
+
require 'slices/will_paginate_mongoid'
|
55
|
+
require 'slices/will_paginate'
|
56
|
+
require 'set_link_renderer'
|
57
|
+
|
58
|
+
if Rails.env.development?
|
59
|
+
Slices::Config.use_snippets!
|
60
|
+
end
|
61
|
+
if Rails.env.test? || Rails.env.development?
|
62
|
+
require 'standard_tree'
|
63
|
+
end
|
64
|
+
|
65
|
+
Mime::Type.register_alias 'text/plain', :hbs
|
66
|
+
Time::DATE_FORMATS.merge!(
|
67
|
+
day_month_year: '%d %B %Y'
|
68
|
+
)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Slices
|
2
|
+
module Asset
|
3
|
+
class Maker
|
4
|
+
|
5
|
+
attr_accessor :args, :new_asset
|
6
|
+
|
7
|
+
def self.run(args)
|
8
|
+
new(args).run
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(args)
|
12
|
+
self.args = args
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_new_asset
|
16
|
+
::Asset.create!(args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_matching_asset(new_asset)
|
20
|
+
::Asset.first(conditions: {
|
21
|
+
file_fingerprint: new_asset.file_fingerprint, :_id.ne => new_asset.id
|
22
|
+
})
|
23
|
+
end
|
24
|
+
|
25
|
+
def tempfile_stored_on_s3?
|
26
|
+
Slices::Config.s3_storage? &&
|
27
|
+
args[:file].is_a?(URI)
|
28
|
+
end
|
29
|
+
|
30
|
+
def s3_path
|
31
|
+
s3_path = args[:file].path
|
32
|
+
s3_path[s3_path.index(Slices::Config::S3_TEMPFILE_KEY_PREFIX) .. -1]
|
33
|
+
end
|
34
|
+
|
35
|
+
def delete_tempfile_from_s3
|
36
|
+
directory = new_asset.file.send(:directory)
|
37
|
+
directory.files.new(key: s3_path).destroy
|
38
|
+
end
|
39
|
+
|
40
|
+
def run
|
41
|
+
self.new_asset = create_new_asset
|
42
|
+
delete_tempfile_from_s3 if tempfile_stored_on_s3?
|
43
|
+
matching_asset = find_matching_asset(new_asset)
|
44
|
+
|
45
|
+
if matching_asset.present?
|
46
|
+
new_asset.destroy
|
47
|
+
matching_asset.soft_restore!
|
48
|
+
matching_asset
|
49
|
+
else
|
50
|
+
new_asset
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
module Slices
|
4
|
+
module Asset
|
5
|
+
module Rename
|
6
|
+
class UnsupportedStorage < ::StandardError; end
|
7
|
+
|
8
|
+
def self.run(file, new_file_name)
|
9
|
+
klass = ('Slices::Asset::Rename::' + file.options[:storage].to_s.classify).constantize
|
10
|
+
klass.new(file, new_file_name).run
|
11
|
+
rescue NameError
|
12
|
+
raise UnsupportedStorage,
|
13
|
+
"Renaming files with '#{file.options[:storage]}' is not supported"
|
14
|
+
end
|
15
|
+
|
16
|
+
class Base
|
17
|
+
attr_accessor :file, :new_file_name
|
18
|
+
|
19
|
+
def initialize(file, new_file_name)
|
20
|
+
self.file = file
|
21
|
+
self.new_file_name = new_file_name
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
(file.styles.keys + [:original]).each do |style|
|
26
|
+
next unless file.exists?(style)
|
27
|
+
rename(style)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def rename(style)
|
32
|
+
@old_path = file.path(style)
|
33
|
+
@new_path = File.join(File.dirname(@old_path), @new_file_name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Filesystem < Base
|
38
|
+
def rename(style)
|
39
|
+
super
|
40
|
+
File.rename(@old_path, @new_path)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Fog < Base
|
45
|
+
def new_path
|
46
|
+
@new_path[1 .. -1]
|
47
|
+
end
|
48
|
+
|
49
|
+
def rename(style)
|
50
|
+
super
|
51
|
+
file = directory.files.new(key: @old_path)
|
52
|
+
file.copy(
|
53
|
+
directory.key,
|
54
|
+
@new_path,
|
55
|
+
{'x-amz-acl' => 'public-read'}
|
56
|
+
)
|
57
|
+
file.destroy
|
58
|
+
end
|
59
|
+
|
60
|
+
def directory
|
61
|
+
@directory ||= file.send(:directory)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Slices
|
2
|
+
class AvailableSlices
|
3
|
+
|
4
|
+
def self.all
|
5
|
+
# We've memoized the slices so that we never try and load them all
|
6
|
+
# twice. If we iterate over ObjectSpace twice (see find_all_slices)
|
7
|
+
# we sometimes find that an incomplete set of slices objects is
|
8
|
+
# returned on subsequent calls.
|
9
|
+
@all ||= find_all_slices
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def self.find_all_slices
|
15
|
+
slices = []
|
16
|
+
|
17
|
+
Dir.glob(File.join(Rails.root, 'app/slices/**/*_slice.rb')).each do |path|
|
18
|
+
|
19
|
+
slice_name = File.basename(path, '.rb')
|
20
|
+
klass = slice_name.camelize.constantize
|
21
|
+
basename = File.basename(path, '_slice.rb')
|
22
|
+
folder = File.basename(File.dirname(path))
|
23
|
+
|
24
|
+
fields = {
|
25
|
+
'name' => basename.humanize.titleize,
|
26
|
+
'template' => File.join(folder, basename),
|
27
|
+
'restricted' => klass.restricted?
|
28
|
+
}
|
29
|
+
|
30
|
+
klass.fields.each do |name, field|
|
31
|
+
next if Slice.fields[name]
|
32
|
+
fields[name] = field.default
|
33
|
+
end
|
34
|
+
|
35
|
+
slices << [basename, fields]
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
Hash[*slices.sort.flatten]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Slices
|
2
|
+
class CmsFormBuilder < ActionView::Helpers::FormBuilder
|
3
|
+
|
4
|
+
FIELD_ERROR_PROC = proc do |html_tag, instance_tag|
|
5
|
+
html_tag
|
6
|
+
end
|
7
|
+
|
8
|
+
%w{email_field password_field select text_area text_field}.each do |selector|
|
9
|
+
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
|
10
|
+
def cms_#{selector}(attribute, options = {}) # def cms_text_field(attribute, options = {})
|
11
|
+
wrap_field(:#{selector}, attribute, options) # wrap_field(:text_field, attribute, options)
|
12
|
+
end # end
|
13
|
+
RUBY_EVAL
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def wrap_field(selector, attribute, options)
|
19
|
+
with_custom_field_error_proc do
|
20
|
+
content = send(selector, attribute, options)
|
21
|
+
options = {}
|
22
|
+
errors = @object.errors[attribute]
|
23
|
+
|
24
|
+
if errors.any?
|
25
|
+
options[:class] = 'error'
|
26
|
+
content << @template.send(:content_tag, :p, errors.join(' and '))
|
27
|
+
end
|
28
|
+
|
29
|
+
@template.content_tag(:li, label(attribute) + content, options)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def with_custom_field_error_proc(&block)
|
34
|
+
default_field_error_proc = ::ActionView::Base.field_error_proc
|
35
|
+
::ActionView::Base.field_error_proc = FIELD_ERROR_PROC
|
36
|
+
yield
|
37
|
+
ensure
|
38
|
+
::ActionView::Base.field_error_proc = default_field_error_proc
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
module Slices
|
2
|
+
class Config
|
3
|
+
S3_TEMPFILE_KEY_PREFIX = 'uploads'
|
4
|
+
|
5
|
+
# Set the asset styles for the app, this is a hash with the keys as the
|
6
|
+
# style names and Papcerlip resize options
|
7
|
+
#
|
8
|
+
# Slices::Config.add_asset_styles(
|
9
|
+
# :thumbnail => "220x146#",
|
10
|
+
# :full_width => "971x440#",
|
11
|
+
# :feature_full => "971x475#",
|
12
|
+
# :slideshow => "723x440>",
|
13
|
+
# )
|
14
|
+
#
|
15
|
+
# @param [Hash] options
|
16
|
+
def self.add_asset_styles(options = {})
|
17
|
+
@asset_styles = options.merge(admin_asset_styles)
|
18
|
+
end
|
19
|
+
|
20
|
+
# The list of asset styles in use
|
21
|
+
#
|
22
|
+
# @return [Hash]
|
23
|
+
def self.asset_styles
|
24
|
+
@asset_styles || add_asset_styles
|
25
|
+
end
|
26
|
+
|
27
|
+
# Enable snippets
|
28
|
+
def self.use_snippets!
|
29
|
+
@snippets = true
|
30
|
+
end
|
31
|
+
|
32
|
+
# Does this app use snippets?
|
33
|
+
# @return [Boolean]
|
34
|
+
def self.snippets?
|
35
|
+
@snippets || false
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.s3_storage?
|
39
|
+
Paperclip::Attachment.default_options[:storage].to_sym == :fog
|
40
|
+
end
|
41
|
+
|
42
|
+
# S3 credentaials taken from the papercip defaults
|
43
|
+
#
|
44
|
+
# {
|
45
|
+
# :bucket => 'slices-demo',
|
46
|
+
# :access_key_id => 'access key id',
|
47
|
+
# :secret_access_key => 'secret access key',
|
48
|
+
# }
|
49
|
+
#
|
50
|
+
# @return Hash
|
51
|
+
def self.s3_credentials
|
52
|
+
default_options = Paperclip::Attachment.default_options
|
53
|
+
{
|
54
|
+
bucket: default_options[:fog_directory],
|
55
|
+
access_key_id: default_options[:fog_credentials][:aws_access_key_id],
|
56
|
+
secret_access_key: default_options[:fog_credentials][:aws_secret_access_key],
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
# Google Apps domain for quick auth.
|
61
|
+
#
|
62
|
+
# @return [String] the domain
|
63
|
+
def self.google_apps_domain
|
64
|
+
@google_apps_domain
|
65
|
+
end
|
66
|
+
|
67
|
+
# Set Google Apps domain for quick auth.
|
68
|
+
#
|
69
|
+
# @param [String] the domain
|
70
|
+
def self.google_apps_domain=(domain)
|
71
|
+
@google_apps_domain = domain
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
def self.admin_asset_styles
|
76
|
+
{ admin: '180x180#' }
|
77
|
+
end
|
78
|
+
|
79
|
+
# Addition Paperclip convert options which are applied to all styles.
|
80
|
+
# This removes colour profiles, sets the dpi to 72 dpi (the image is not
|
81
|
+
# resampled). The colour depth is set to 8 bits per pixel
|
82
|
+
def self.asset_convert_options
|
83
|
+
Hash.new.tap do |options|
|
84
|
+
asset_styles.keys.each do |style|
|
85
|
+
next if style == :original
|
86
|
+
options[style] = "-strip -density 72x72 -depth 8"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|