alchemy_cms 2.4.beta2 → 2.4.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/.travis.yml +3 -1
- data/.yardopts +1 -1
- data/Gemfile +2 -1
- data/alchemy_cms.gemspec +18 -17
- data/app/assets/images/alchemy/ajax_loader.gif +0 -0
- data/app/assets/images/alchemy/alchemy-logo.png +0 -0
- data/app/assets/images/alchemy/icons.png +0 -0
- data/app/assets/images/alchemy/image_loader.gif +0 -0
- data/app/assets/images/alchemy/placeholder.png +0 -0
- data/app/assets/images/alchemy/shading.png +0 -0
- data/app/assets/images/alchemy/swfupload/browse_button.png +0 -0
- data/app/assets/images/alchemy/tabs.gif +0 -0
- data/app/assets/images/alchemy/ui-icons_666666_256x240.png +0 -0
- data/app/assets/images/sassy-ie-overlay.png +0 -0
- data/app/assets/javascripts/alchemy/alchemy.base.js +1 -3
- data/app/assets/javascripts/alchemy/alchemy.browser.js.coffee +28 -0
- data/app/assets/javascripts/alchemy/alchemy.jquery_loader.js +2 -2
- data/app/assets/javascripts/alchemy/alchemy.js +2 -0
- data/app/assets/javascripts/alchemy/alchemy.link_overlay.js.coffee +79 -47
- data/app/assets/javascripts/alchemy/alchemy.menubar.js +12 -4
- data/app/assets/javascripts/alchemy/alchemy.onload.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +103 -0
- data/app/assets/javascripts/alchemy/alchemy.swf_upload.js +1 -1
- data/app/assets/javascripts/alchemy/alchemy.uploader.js +4 -6
- data/app/assets/javascripts/alchemy/preview.js +1 -0
- data/app/assets/stylesheets/alchemy/admin.css.scss +25 -0
- data/app/assets/stylesheets/alchemy/{archive.css.scss → archive.scss} +0 -2
- data/app/assets/stylesheets/alchemy/{base.css.scss → base.scss} +1 -57
- data/app/assets/stylesheets/alchemy/{custom.css → custom.scss} +0 -0
- data/app/assets/stylesheets/alchemy/{dashboard.css.scss → dashboard.scss} +0 -2
- data/app/assets/stylesheets/alchemy/defaults.scss +5 -0
- data/app/assets/stylesheets/alchemy/{elements.css.scss → elements.scss} +24 -37
- data/app/assets/stylesheets/alchemy/{errors.css.scss → errors.scss} +0 -2
- data/app/assets/stylesheets/alchemy/{flash.css.scss → flash.scss} +0 -2
- data/app/assets/stylesheets/alchemy/{form_elements.css.scss → form_elements.scss} +39 -12
- data/app/assets/stylesheets/alchemy/{frame.css.scss → frame.scss} +0 -2
- data/app/assets/stylesheets/alchemy/{icons.css.scss → icons.scss} +20 -2
- data/app/assets/stylesheets/alchemy/{jquery-ui.alchemy.css.scss → jquery-ui.scss} +6 -3
- data/app/assets/stylesheets/alchemy/{login.css.scss → login.scss} +3 -3
- data/app/assets/stylesheets/alchemy/menubar.css.scss +0 -1
- data/app/assets/stylesheets/alchemy/{_defaults.scss → mixins.scss} +2 -39
- data/app/assets/stylesheets/alchemy/{modules.css.scss → modules.scss} +4 -2
- data/app/assets/stylesheets/alchemy/notices.scss +51 -0
- data/app/assets/stylesheets/alchemy/{pagination.css.scss → pagination.scss} +0 -2
- data/app/assets/stylesheets/alchemy/{print.css → print.css.scss} +3 -3
- data/app/assets/stylesheets/alchemy/search.scss +63 -0
- data/app/assets/stylesheets/alchemy/{sitemap.css.scss → sitemap.scss} +1 -2
- data/app/assets/stylesheets/alchemy/{tables.css.scss → tables.scss} +16 -3
- data/app/assets/stylesheets/alchemy/tinymce_content.css.scss +3 -0
- data/app/assets/stylesheets/alchemy/tinymce_dialog.css.scss +3 -0
- data/app/assets/stylesheets/alchemy/{upload.css.scss → upload.scss} +0 -2
- data/app/assets/stylesheets/alchemy/variables.scss +33 -0
- data/app/controllers/alchemy/admin/elements_controller.rb +1 -2
- data/app/controllers/alchemy/admin/tags_controller.rb +64 -0
- data/app/controllers/alchemy/base_controller.rb +8 -23
- data/app/controllers/alchemy/pages_controller.rb +5 -18
- data/app/helpers/alchemy/admin/base_helper.rb +1 -1
- data/app/helpers/alchemy/admin/elements_helper.rb +1 -0
- data/app/helpers/alchemy/elements_block_helper.rb +162 -0
- data/app/helpers/alchemy/elements_helper.rb +41 -3
- data/app/helpers/alchemy/pages_helper.rb +2 -1
- data/app/models/alchemy/attachment.rb +2 -1
- data/app/models/alchemy/element.rb +13 -10
- data/app/models/alchemy/essence_link.rb +11 -0
- data/app/models/alchemy/essence_picture.rb +15 -4
- data/app/models/alchemy/page.rb +23 -25
- data/app/models/alchemy/picture.rb +2 -2
- data/app/models/alchemy/tag.rb +16 -0
- data/app/models/alchemy/user.rb +3 -1
- data/app/views/alchemy/admin/attachments/_attachment.html.erb +12 -12
- data/app/views/alchemy/admin/attachments/edit.html.erb +10 -4
- data/app/views/alchemy/admin/elements/_element.html.erb +10 -13
- data/app/views/alchemy/admin/elements/_element_foot.html.erb +1 -1
- data/app/views/alchemy/admin/essence_files/edit.html.erb +12 -76
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +9 -4
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +1 -1
- data/app/views/alchemy/admin/layoutpages/index.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_external_link.html.erb +9 -4
- data/app/views/alchemy/admin/pages/configure.html.erb +22 -12
- data/app/views/alchemy/admin/pages/edit.html.erb +40 -40
- data/app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb +9 -0
- data/app/views/alchemy/admin/pictures/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +11 -2
- data/app/views/alchemy/admin/tags/_radio_tag.html.erb +6 -0
- data/app/views/alchemy/admin/tags/_tag.html.erb +29 -0
- data/app/views/alchemy/admin/tags/edit.html.erb +41 -0
- data/app/views/alchemy/admin/tags/index.html.erb +46 -0
- data/app/views/alchemy/admin/tags/new.html.erb +16 -0
- data/app/views/alchemy/admin/users/_table.html.erb +18 -10
- data/app/views/alchemy/admin/users/_user.html.erb +2 -1
- data/app/views/alchemy/admin/users/index.html.erb +2 -1
- data/app/views/alchemy/elements/_article_view.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_link_editor.html.erb +23 -0
- data/app/views/alchemy/essences/_essence_link_view.html.erb +0 -0
- data/app/views/alchemy/essences/_essence_picture_tools.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +1 -9
- data/app/views/alchemy/essences/_linkable_essence_tools.html.erb +19 -0
- data/app/views/layouts/alchemy/admin.html.erb +1 -1
- data/config/alchemy/elements.yml +2 -0
- data/config/alchemy/modules.yml +12 -0
- data/config/alchemy/page_layouts.yml +2 -0
- data/config/authorization_rules.rb +2 -0
- data/config/locales/alchemy.de.yml +36 -5
- data/config/locales/alchemy.en.yml +3 -0
- data/config/routes.rb +6 -4
- data/db/migrate/20121026100815_alchemy_two_point_three.rb +0 -36
- data/db/migrate/20121113115120_create_alchemy_essence_links.rb +13 -0
- data/db/migrate/20121115100736_add_cached_tag_list_to_elements_pages_and_users.rb +7 -0
- data/db/migrate/20121116140636_add_cached_tag_list_to_alchemy_attachments.rb +5 -0
- data/db/migrate/20121116141016_change_alchemy_pictures_tag_list_column.rb +9 -0
- data/lib/alchemy/engine.rb +1 -1
- data/lib/alchemy/resource.rb +1 -1
- data/lib/alchemy/resources_helper.rb +1 -1
- data/lib/alchemy/upgrader.rb +17 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +1 -0
- data/lib/rails/generators/alchemy/base.rb +41 -0
- data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +10 -3
- data/lib/rails/generators/alchemy/elements/elements_generator.rb +6 -14
- data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +8 -6
- data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +13 -0
- data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +13 -0
- data/lib/rails/generators/alchemy/elements/templates/view.html.erb +4 -4
- data/lib/rails/generators/alchemy/elements/templates/view.html.haml +15 -0
- data/lib/rails/generators/alchemy/elements/templates/view.html.slim +15 -0
- data/lib/rails/generators/alchemy/essence/essence_generator.rb +1 -1
- data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +2 -3
- data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +4 -13
- data/lib/rails/generators/alchemy/page_layouts/templates/layout.html.haml +1 -0
- data/lib/rails/generators/alchemy/page_layouts/templates/layout.html.slim +1 -0
- data/spec/controllers/pages_controller_spec.rb +41 -34
- data/spec/dummy/app/views/layouts/application.html.erb +51 -0
- data/spec/dummy/db/migrate/20121026100815_alchemy_two_point_three.rb +0 -36
- data/spec/dummy/db/migrate/20121113115120_create_alchemy_essence_links.rb +13 -0
- data/spec/dummy/db/migrate/20121115100736_add_cached_tag_list_to_elements_pages_and_users.rb +7 -0
- data/spec/dummy/db/migrate/20121116140636_add_cached_tag_list_to_alchemy_attachments.rb +5 -0
- data/spec/dummy/db/migrate/20121116141016_change_alchemy_pictures_tag_list_column.rb +9 -0
- data/spec/dummy/db/schema.rb +24 -45
- data/spec/helpers/elements_block_helper_spec.rb +135 -0
- data/spec/helpers/elements_helper_spec.rb +43 -5
- data/spec/integration/pages_controller_spec.rb +22 -18
- data/spec/integration/translation_integration_spec.rb +0 -15
- data/spec/models/element_spec.rb +44 -36
- data/spec/models/essence_picture_spec.rb +22 -6
- data/spec/models/page_spec.rb +28 -0
- data/spec/spec_helper.rb +8 -3
- data/spec/support/ci/install_phantomjs +6 -0
- metadata +82 -40
- data/app/assets/images/alchemy/gui/navi-tab.png +0 -0
- data/app/assets/images/alchemy/gui/shading_90.png +0 -0
- data/app/assets/images/alchemy/jquery-sb/select_arrow.gif +0 -0
- data/app/assets/images/alchemy/jquery-sb/select_arrow_bg.gif +0 -0
- data/app/assets/images/alchemy/jquery-sb/select_arrow_bg_hover.gif +0 -0
- data/app/assets/javascripts/alchemy/alchemy.preview.js +0 -98
- data/app/assets/stylesheets/alchemy/alchemy.css +0 -21
- data/app/controllers/alchemy/admin/essence_audios_controller.rb +0 -12
- data/app/controllers/alchemy/admin/essence_flashes_controller.rb +0 -12
- data/app/controllers/alchemy/admin/essence_videos_controller.rb +0 -12
- data/app/models/alchemy/essence_audio.rb +0 -14
- data/app/models/alchemy/essence_flash.rb +0 -12
- data/app/models/alchemy/essence_video.rb +0 -20
- data/app/views/alchemy/essences/_essence_audio_editor.html.erb +0 -1
- data/app/views/alchemy/essences/_essence_audio_view.html.erb +0 -33
- data/app/views/alchemy/essences/_essence_flash_editor.html.erb +0 -1
- data/app/views/alchemy/essences/_essence_flash_view.html.erb +0 -26
- data/app/views/alchemy/essences/_essence_video_editor.html.erb +0 -1
- data/app/views/alchemy/essences/_essence_video_view.html.erb +0 -35
@@ -125,33 +125,19 @@ module Alchemy
|
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
|
-
#
|
128
|
+
# Returns the layout to be used by the current page. This method is being
|
129
|
+
# used in PageController#show's invocation of #render.
|
129
130
|
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
134
|
-
#
|
135
|
-
# === Usage:
|
136
|
-
# 1. You can pass none or false as url parameter to avoid any layout rendering.
|
137
|
-
# 2. You can pass a layout name of any existing layout file in +app/views/layouts+ folder.
|
138
|
-
#
|
139
|
-
# If no layout name is given, Alchemy tries to render +app/views/layouts/application/+ layout.
|
140
|
-
# If that is not present, Alchemy tries to render +app/views/layouts/alchemy/pages+ layout.
|
131
|
+
# It allows you to request a specific page layout by passing a 'layout' parameter
|
132
|
+
# in a request. If this parameter is set to 'none' or 'false', no layout whatsoever
|
133
|
+
# will be used to render the page; otherwise, a layout by the given name
|
134
|
+
# will be applied.
|
141
135
|
#
|
142
136
|
def layout_for_page
|
143
137
|
if params[:layout] == 'none' || params[:layout] == 'false'
|
144
138
|
false
|
145
|
-
elsif !params[:layout].blank?
|
146
|
-
if File.exist?(Rails.root.join('app/views/layouts', "#{params[:layout]}.html.erb"))
|
147
|
-
params[:layout]
|
148
|
-
else
|
149
|
-
raise_not_found_error
|
150
|
-
end
|
151
|
-
elsif File.exist?(Rails.root.join('app/views/layouts', 'application.html.erb'))
|
152
|
-
'application'
|
153
139
|
else
|
154
|
-
'
|
140
|
+
params[:layout] || 'application'
|
155
141
|
end
|
156
142
|
end
|
157
143
|
|
@@ -159,8 +145,7 @@ module Alchemy
|
|
159
145
|
if exception
|
160
146
|
logger.info "Rendering 404: #{exception.message}"
|
161
147
|
end
|
162
|
-
|
163
|
-
render :file => Rails.root.join("public/404.html"), :status => 404, :layout => !@page.nil?
|
148
|
+
render :file => Rails.root.join("public/404.html"), :status => 404, :layout => false
|
164
149
|
end
|
165
150
|
|
166
151
|
# Enforce ssl for login and all admin modules.
|
@@ -53,7 +53,7 @@ module Alchemy
|
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
private
|
57
57
|
|
58
58
|
def load_page
|
59
59
|
# we need this, because of a dec_auth bug (it calls this method after the before_filter again).
|
@@ -136,25 +136,12 @@ module Alchemy
|
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
|
-
def find_first_public(page)
|
140
|
-
if page.public == true
|
141
|
-
return page
|
142
|
-
end
|
143
|
-
page.children.each do |child|
|
144
|
-
result = find_first_public(child)
|
145
|
-
if result != nil
|
146
|
-
return result
|
147
|
-
end
|
148
|
-
end
|
149
|
-
return nil
|
150
|
-
end
|
151
|
-
|
152
139
|
def redirect_to_public_child
|
153
|
-
@page =
|
154
|
-
if @page
|
155
|
-
raise_not_found_error
|
156
|
-
else
|
140
|
+
@page = @page.self_and_descendants.published.not_restricted.first
|
141
|
+
if @page
|
157
142
|
redirect_page
|
143
|
+
else
|
144
|
+
raise_not_found_error
|
158
145
|
end
|
159
146
|
end
|
160
147
|
|
@@ -0,0 +1,162 @@
|
|
1
|
+
module Alchemy
|
2
|
+
# Provides a collection of block-level helpers, allowing for a much more
|
3
|
+
# concise way of writing element view/editor partials.
|
4
|
+
#
|
5
|
+
module ElementsBlockHelper
|
6
|
+
# Base class for our block-level helpers.
|
7
|
+
#
|
8
|
+
class BlockHelper
|
9
|
+
def initialize(helpers, opts = {})
|
10
|
+
@helpers = helpers
|
11
|
+
@opts = opts
|
12
|
+
end
|
13
|
+
|
14
|
+
def opts
|
15
|
+
@opts
|
16
|
+
end
|
17
|
+
|
18
|
+
def element
|
19
|
+
opts[:element]
|
20
|
+
end
|
21
|
+
|
22
|
+
def helpers
|
23
|
+
@helpers
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Block-level helper class for element views.
|
28
|
+
#
|
29
|
+
class ElementViewHelper < BlockHelper
|
30
|
+
# Renders one of the element's contents.
|
31
|
+
#
|
32
|
+
def render(name, *args)
|
33
|
+
helpers.render_essence_view_by_name(element, name.to_s, *args)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns one of the element's contents (ie. essence instances).
|
37
|
+
#
|
38
|
+
def content(name)
|
39
|
+
element.content_by_name(name)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the ingredient of one of the element's contents.
|
43
|
+
#
|
44
|
+
def ingredient(name)
|
45
|
+
element.ingredient(name)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns true if the given content has been filled by the user.
|
49
|
+
#
|
50
|
+
def has?(name)
|
51
|
+
element.has_ingredient?(name)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Return's the given content's essence.
|
55
|
+
#
|
56
|
+
def essence(name)
|
57
|
+
content(name).try(:essence)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Block-level helper class for element editors.
|
62
|
+
#
|
63
|
+
class ElementEditorHelper < BlockHelper
|
64
|
+
def edit(name, *args)
|
65
|
+
helpers.render_essence_editor_by_name(element, name.to_s, *args)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Block-level helper for element views. Constructs a DOM element wrapping
|
70
|
+
# your content element and provides a block helper object you can use for
|
71
|
+
# concise access to Alchemy's various helpers.
|
72
|
+
#
|
73
|
+
# === Example:
|
74
|
+
#
|
75
|
+
# <%= element_view_for(element) do |el| %>
|
76
|
+
# <%= el.render :title %>
|
77
|
+
# <%= el.render :body %>
|
78
|
+
# <%= link_to "Go!", el.ingredient(:target_url) %>
|
79
|
+
# <% end %>
|
80
|
+
#
|
81
|
+
# You can override the tag, ID and class used for the generated DOM
|
82
|
+
# element:
|
83
|
+
#
|
84
|
+
# <%= element_view_for(element, tag: 'span', id: 'my_id', class: 'thing') do |el| %>
|
85
|
+
# <%- ... %>
|
86
|
+
# <% end %>
|
87
|
+
#
|
88
|
+
# If you don't want your view to be wrapped into an extra element, simply set
|
89
|
+
# `tag` to `false`:
|
90
|
+
#
|
91
|
+
# <%= element_view_for(element, tag: false) do |el| %>
|
92
|
+
# <%- ... %>
|
93
|
+
# <% end %>
|
94
|
+
#
|
95
|
+
# @param [Alchemy::Element] element
|
96
|
+
# The element to display.
|
97
|
+
# @param [Hash] options
|
98
|
+
# Additional options.
|
99
|
+
#
|
100
|
+
# @option options :tag (:div)
|
101
|
+
# The HTML tag to be used for the wrapping element.
|
102
|
+
# @option options :id (the element's ID)
|
103
|
+
# The wrapper tag's DOM ID.
|
104
|
+
# @option options :class (the element's essence name)
|
105
|
+
# The wrapper tag's DOM class.
|
106
|
+
# @option options :tags_formatter
|
107
|
+
# A lambda used for formatting the element's tags (see Alchemy::ElementsHelper::element_tags_attributes). Set to +false+ to not include tags in the wrapper element.
|
108
|
+
#
|
109
|
+
def element_view_for(element, options = {})
|
110
|
+
options = {
|
111
|
+
:tag => :div,
|
112
|
+
:id => element_dom_id(element),
|
113
|
+
:class => element.name,
|
114
|
+
:tags_formatter => lambda { |tags| tags.join(" ") }
|
115
|
+
}.merge(options)
|
116
|
+
|
117
|
+
# capture inner template block
|
118
|
+
output = capture do
|
119
|
+
yield ElementViewHelper.new(self, :element => element) if block_given?
|
120
|
+
end
|
121
|
+
|
122
|
+
# wrap output in a useful DOM element
|
123
|
+
if tag = options.delete(:tag)
|
124
|
+
# add preview attributes
|
125
|
+
options.merge!(element_preview_code_attributes(element))
|
126
|
+
|
127
|
+
# add tags
|
128
|
+
if tags_formatter = options.delete(:tags_formatter)
|
129
|
+
options.merge!(element_tags_attributes(element, formatter: tags_formatter))
|
130
|
+
end
|
131
|
+
|
132
|
+
output = content_tag(tag, output, options)
|
133
|
+
end
|
134
|
+
|
135
|
+
# that's it!
|
136
|
+
output
|
137
|
+
end
|
138
|
+
# Block-level helper for element editors. Provides a block helper object
|
139
|
+
# you can use for concise access to Alchemy's various helpers.
|
140
|
+
#
|
141
|
+
# === Example:
|
142
|
+
#
|
143
|
+
# <%= element_editor_for(element) do |el| %>
|
144
|
+
# <%= el.edit :title %>
|
145
|
+
# <%= el.edit :body %>
|
146
|
+
# <%= el.edit :target_url %>
|
147
|
+
# <% end %>
|
148
|
+
#
|
149
|
+
# @param [Alchemy::Element] element
|
150
|
+
# The element to display.
|
151
|
+
#
|
152
|
+
def element_editor_for(element, options = {})
|
153
|
+
options = {
|
154
|
+
# nothing here yet.
|
155
|
+
}.merge(options)
|
156
|
+
|
157
|
+
capture do
|
158
|
+
yield ElementEditorHelper.new(self, :element => element)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -160,10 +160,15 @@ module Alchemy
|
|
160
160
|
"#{element.name}_#{element.id}".html_safe
|
161
161
|
end
|
162
162
|
|
163
|
-
# Renders the
|
163
|
+
# Renders the HTML tag attributes required for preview mode.
|
164
164
|
def element_preview_code(element)
|
165
|
-
|
166
|
-
|
165
|
+
tag_options(element_preview_code_attributes(element))
|
166
|
+
end
|
167
|
+
|
168
|
+
# Returns a hash containing the HTML tag attributes required for preview mode.
|
169
|
+
def element_preview_code_attributes(element)
|
170
|
+
return {} unless element.present? && @preview_mode && element.page == @page
|
171
|
+
{ :'data-alchemy-element' => element.id }
|
167
172
|
end
|
168
173
|
|
169
174
|
# Returns the full url containing host, page and anchor for the given element
|
@@ -171,5 +176,38 @@ module Alchemy
|
|
171
176
|
"#{current_server}/#{element.page.urlname}##{element_dom_id(element)}"
|
172
177
|
end
|
173
178
|
|
179
|
+
# Returns the element's tags information as a string. Parameters and options
|
180
|
+
# are equivalent to {#element_tags_attributes}.
|
181
|
+
#
|
182
|
+
# @see #element_tags_attributes
|
183
|
+
#
|
184
|
+
# @return [String]
|
185
|
+
# HTML tag attributes containing the element's tag information.
|
186
|
+
#
|
187
|
+
def element_tags(element, options = {})
|
188
|
+
tag_options(element_tags_attributes(element, options))
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
# Returns the element's tags information as an attribute hash.
|
193
|
+
#
|
194
|
+
# @param [Alchemy::Element] element The element.
|
195
|
+
#
|
196
|
+
# @option options [Proc] :formatter
|
197
|
+
# ('lambda { |tags| tags.join(' ') }')
|
198
|
+
# Lambda converting array of tags to a string.
|
199
|
+
#
|
200
|
+
# @return [Hash]
|
201
|
+
# HTML tag attributes containing the element's tag information.
|
202
|
+
#
|
203
|
+
def element_tags_attributes(element, options = {})
|
204
|
+
options = {
|
205
|
+
formatter: lambda { |tags| tags.join(' ') }
|
206
|
+
}.merge(options)
|
207
|
+
|
208
|
+
return {} if !element.taggable? || element.tag_list.blank?
|
209
|
+
{ :'data-element-tags' => options[:formatter].call(element.tag_list) }
|
210
|
+
end
|
211
|
+
|
174
212
|
end
|
175
213
|
end
|
@@ -3,6 +3,7 @@ module Alchemy
|
|
3
3
|
|
4
4
|
include Alchemy::BaseHelper
|
5
5
|
include Alchemy::ElementsHelper
|
6
|
+
include Alchemy::ElementsBlockHelper
|
6
7
|
include Alchemy::UrlHelper
|
7
8
|
|
8
9
|
def render_classes(classes=[])
|
@@ -478,7 +479,7 @@ module Alchemy
|
|
478
479
|
Alchemy.loadAlchemyMenuBar({
|
479
480
|
page_id: #{@page.id},
|
480
481
|
route: '#{Alchemy.mount_point}',
|
481
|
-
locale: '#{current_user.language}'
|
482
|
+
locale: '#{current_user.language || ::I18n.default_locale}'
|
482
483
|
});
|
483
484
|
} catch(e) {
|
484
485
|
if(console){console.log(e)}
|
@@ -6,10 +6,11 @@ module Alchemy
|
|
6
6
|
has_many :elements, :through => :contents
|
7
7
|
has_many :pages, :through => :elements
|
8
8
|
|
9
|
-
attr_accessible :uploaded_data, :name, :filename
|
9
|
+
attr_accessible :uploaded_data, :name, :filename, :tag_list
|
10
10
|
|
11
11
|
stampable(:stamper_class_name => 'Alchemy::User')
|
12
12
|
|
13
|
+
acts_as_taggable
|
13
14
|
has_attachment(
|
14
15
|
:storage => :file_system,
|
15
16
|
:file_system_path => 'uploads/attachments',
|
@@ -1,7 +1,10 @@
|
|
1
1
|
module Alchemy
|
2
2
|
class Element < ActiveRecord::Base
|
3
3
|
|
4
|
-
FORBIDDEN_DEFINITION_ATTRIBUTES = %w(contents available_contents
|
4
|
+
FORBIDDEN_DEFINITION_ATTRIBUTES = %w(contents available_contents amount picture_gallery taggable)
|
5
|
+
SKIPPED_ATTRIBUTES_ON_COPY = %w(id position folded created_at updated_at creator_id updater_id cached_tag_list)
|
6
|
+
|
7
|
+
acts_as_taggable
|
5
8
|
|
6
9
|
attr_accessible(
|
7
10
|
:cell_id,
|
@@ -11,6 +14,7 @@ module Alchemy
|
|
11
14
|
:page_id,
|
12
15
|
:position,
|
13
16
|
:public,
|
17
|
+
:tag_list,
|
14
18
|
:unique
|
15
19
|
)
|
16
20
|
|
@@ -149,15 +153,9 @@ module Alchemy
|
|
149
153
|
# @copy.public? # => false
|
150
154
|
#
|
151
155
|
def copy(source, differences = {})
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
"folded",
|
156
|
-
"created_at",
|
157
|
-
"updated_at",
|
158
|
-
"creator_id",
|
159
|
-
"updater_id"
|
160
|
-
).merge(differences.stringify_keys)
|
156
|
+
source.attributes.stringify_keys!
|
157
|
+
differences.stringify_keys!
|
158
|
+
attributes = source.attributes.except(*SKIPPED_ATTRIBUTES_ON_COPY).merge(differences)
|
161
159
|
element = self.create!(attributes.merge(:create_contents_after_create => false))
|
162
160
|
source.contents.each do |content|
|
163
161
|
new_content = Content.copy(content, :element_id => element.id)
|
@@ -506,6 +504,11 @@ module Alchemy
|
|
506
504
|
page.restricted?
|
507
505
|
end
|
508
506
|
|
507
|
+
# Returns true if the definition of this element has a taggable true value.
|
508
|
+
def taggable?
|
509
|
+
description['taggable'] == true
|
510
|
+
end
|
511
|
+
|
509
512
|
private
|
510
513
|
|
511
514
|
# creates the contents for this element as described in the elements.yml
|
@@ -22,13 +22,24 @@ module Alchemy
|
|
22
22
|
)
|
23
23
|
|
24
24
|
belongs_to :picture
|
25
|
+
before_save :fix_crop_values
|
25
26
|
before_save :replace_newlines
|
26
|
-
before_save :fix_crop_from
|
27
27
|
|
28
|
-
|
28
|
+
private
|
29
29
|
|
30
|
-
def
|
31
|
-
|
30
|
+
def fix_crop_values
|
31
|
+
%w(crop_from crop_size).each do |crop_value|
|
32
|
+
write_attribute crop_value, normalize_crop_value(crop_value)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def normalize_crop_value(crop_value)
|
37
|
+
self.send(crop_value).to_s.split('x').map { |n| normalize_number(n) }.join('x')
|
38
|
+
end
|
39
|
+
|
40
|
+
def normalize_number(number)
|
41
|
+
number = number.to_f.round
|
42
|
+
number < 0 ? 0 : number
|
32
43
|
end
|
33
44
|
|
34
45
|
def replace_newlines
|