alchemy_cms 3.0.0.rc7 → 3.0.0.rc8
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.
- checksums.yaml +4 -4
- data/Gemfile +2 -1
- data/README.md +1 -1
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +0 -2
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +26 -2
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +22 -0
- data/app/assets/stylesheets/alchemy/base.scss +1 -5
- data/app/assets/stylesheets/alchemy/elements.scss +11 -61
- data/app/assets/stylesheets/alchemy/frame.scss +1 -1
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +1 -1
- data/app/controllers/alchemy/admin/attachments_controller.rb +1 -1
- data/app/controllers/alchemy/admin/base_controller.rb +7 -13
- data/app/controllers/alchemy/admin/clipboard_controller.rb +15 -10
- data/app/controllers/alchemy/admin/elements_controller.rb +15 -11
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +8 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +95 -22
- data/app/controllers/alchemy/admin/tags_controller.rb +1 -1
- data/app/controllers/alchemy/pictures_controller.rb +33 -32
- data/app/helpers/alchemy/admin/base_helper.rb +3 -16
- data/app/models/alchemy/element.rb +1 -1
- data/app/models/alchemy/page/page_naming.rb +4 -2
- data/app/models/alchemy/page/page_natures.rb +1 -1
- data/app/models/alchemy/page.rb +20 -1
- data/app/models/alchemy/picture.rb +1 -0
- data/app/models/alchemy/tree_node.rb +4 -0
- data/app/views/alchemy/admin/contents/destroy.js.erb +4 -0
- data/app/views/alchemy/admin/dashboard/index.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_element.html.erb +11 -12
- data/app/views/alchemy/admin/elements/_new_element_form.html.erb +0 -3
- data/app/views/alchemy/admin/elements/create.js.erb +3 -3
- data/app/views/alchemy/admin/elements/index.html.erb +4 -19
- data/app/views/alchemy/admin/elements/new.html.erb +0 -3
- data/app/views/alchemy/admin/elements/trash.js.erb +12 -16
- data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/edit.html.erb +36 -30
- data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +1 -1
- data/app/views/alchemy/admin/trash/clear.js.erb +4 -0
- data/config/locales/alchemy.de.yml +56 -84
- data/config/locales/alchemy.en.yml +326 -105
- data/config/locales/alchemy.fr.yml +942 -0
- data/config/locales/alchemy.nl.yml +111 -137
- data/config/locales/simple_form.fr.yml +26 -0
- data/lib/alchemy/engine.rb +7 -1
- data/lib/alchemy/i18n.rb +7 -1
- data/lib/alchemy/middleware/rescue_old_cookies.rb +27 -0
- data/lib/alchemy/permissions.rb +1 -1
- data/lib/alchemy/version.rb +1 -1
- data/spec/controllers/admin/clipboard_controller_spec.rb +16 -19
- data/spec/controllers/admin/elements_controller_spec.rb +20 -23
- data/spec/controllers/admin/essence_pictures_controller_spec.rb +22 -6
- data/spec/controllers/admin/pages_controller_spec.rb +94 -5
- data/spec/controllers/pictures_controller_spec.rb +44 -3
- data/spec/features/admin/link_overlay_spec.rb +1 -0
- data/spec/features/admin/locale_select_feature_spec.rb +22 -0
- data/spec/libraries/i18n_spec.rb +30 -0
- data/spec/libraries/permissions_spec.rb +1 -1
- data/spec/models/element_spec.rb +5 -4
- data/spec/models/page_spec.rb +137 -8
- data/spec/spec_helper.rb +23 -19
- data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +9 -3
- metadata +12 -10
- data/app/models/alchemy/clipboard.rb +0 -74
- data/app/views/alchemy/admin/contents/destroy.js.coffee +0 -4
- data/app/views/alchemy/admin/elements/_add_element_button.html.erb +0 -18
- data/app/views/alchemy/admin/trash/clear.js.coffee +0 -4
- data/spec/models/clipboard_spec.rb +0 -111
- data/spec/support/phantomjs_mavericks_fix.rb +0 -32
@@ -75,7 +75,14 @@ module Alchemy
|
|
75
75
|
|
76
76
|
def sizes_from_essence
|
77
77
|
return if @essence_picture.render_size.blank?
|
78
|
-
@essence_picture.render_size.split('x')
|
78
|
+
size_x, size_y = @essence_picture.render_size.split('x').map(&:to_i)
|
79
|
+
if size_x.zero? || size_y.nil? || size_y.zero?
|
80
|
+
size_x_of_original = @essence_picture.picture.image_file_width
|
81
|
+
size_y_of_original = @essence_picture.picture.image_file_height
|
82
|
+
size_x = size_x_of_original * size_y / size_y_of_original if size_x.zero?
|
83
|
+
size_y = size_y_of_original * size_x / size_x_of_original if size_y.nil? || size_y.zero?
|
84
|
+
end
|
85
|
+
[size_x, size_y]
|
79
86
|
end
|
80
87
|
|
81
88
|
def sizes_string
|
@@ -40,7 +40,8 @@ module Alchemy
|
|
40
40
|
def new
|
41
41
|
@page = Page.new(layoutpage: params[:layoutpage] == 'true', parent_id: params[:parent_id])
|
42
42
|
@page_layouts = PageLayout.layouts_for_select(Language.current.id, @page.layoutpage?)
|
43
|
-
@
|
43
|
+
@clipboard = get_clipboard('pages')
|
44
|
+
@clipboard_items = Page.all_from_clipboard_for_select(@clipboard, Language.current.id, @page.layoutpage?)
|
44
45
|
end
|
45
46
|
|
46
47
|
def create
|
@@ -50,7 +51,8 @@ module Alchemy
|
|
50
51
|
do_redirect_to(redirect_path_after_create_page)
|
51
52
|
else
|
52
53
|
@page_layouts = PageLayout.layouts_for_select(Language.current.id, @page.layoutpage?)
|
53
|
-
@
|
54
|
+
@clipboard = get_clipboard('pages')
|
55
|
+
@clipboard_items = Page.all_from_clipboard_for_select(@clipboard, Language.current.id, @page.layoutpage?)
|
54
56
|
render :new
|
55
57
|
end
|
56
58
|
end
|
@@ -59,7 +61,7 @@ module Alchemy
|
|
59
61
|
def edit
|
60
62
|
# fetching page via before filter
|
61
63
|
if page_is_locked?
|
62
|
-
flash[:notice] = _t(
|
64
|
+
flash[:notice] = _t('This page is locked', name: @page.locker_name)
|
63
65
|
redirect_to admin_pages_path
|
64
66
|
else
|
65
67
|
@page.lock_to!(current_alchemy_user)
|
@@ -102,7 +104,8 @@ module Alchemy
|
|
102
104
|
format.js
|
103
105
|
end
|
104
106
|
# remove from clipboard
|
105
|
-
get_clipboard
|
107
|
+
@clipboard = get_clipboard('pages')
|
108
|
+
@clipboard.delete_if { |item| item['id'] == @page_id.to_s }
|
106
109
|
end
|
107
110
|
end
|
108
111
|
|
@@ -170,15 +173,17 @@ module Alchemy
|
|
170
173
|
@sorting = true
|
171
174
|
end
|
172
175
|
|
176
|
+
# Receives a JSON object representing a language tree to be ordered
|
177
|
+
# and updates all pages in that language structure to their correct indexes
|
173
178
|
def order
|
174
|
-
# Taken from https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop
|
175
179
|
neworder = JSON.parse(params[:set])
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
180
|
+
tree = create_tree(neworder, @page_root)
|
181
|
+
|
182
|
+
Alchemy::Page.transaction do
|
183
|
+
tree.each do |key, node|
|
184
|
+
dbitem = Page.find(key)
|
185
|
+
dbitem.update_node!(node)
|
186
|
+
end
|
182
187
|
end
|
183
188
|
|
184
189
|
flash[:notice] = _t("Pages order saved")
|
@@ -215,6 +220,85 @@ module Alchemy
|
|
215
220
|
Page.language_root_for(params[:languages][:old_lang_id])
|
216
221
|
end
|
217
222
|
|
223
|
+
# Returns the current left index and the aggregated hash of tree nodes indexed by page id visited so far
|
224
|
+
#
|
225
|
+
# Visits a batch of children nodes, assigns them the correct ordering indexes and spuns recursively the same
|
226
|
+
# procedure on their children, if any
|
227
|
+
#
|
228
|
+
# @param [Array]
|
229
|
+
# An array of children nodes to be visited
|
230
|
+
# @param [Integer]
|
231
|
+
# The lft attribute that should be given to the first node in the array
|
232
|
+
# @param [Integer]
|
233
|
+
# The page id of the parent of this batch of children nodes
|
234
|
+
# @param [Integer]
|
235
|
+
# The depth at which these children reside
|
236
|
+
# @param [Hash]
|
237
|
+
# A Hash of TreeNode's indexed by their page ids
|
238
|
+
# @param [String]
|
239
|
+
# The url for the parent node of these children
|
240
|
+
# @param [Boolean]
|
241
|
+
# Whether these children reside in a restricted branch according to their ancestors
|
242
|
+
#
|
243
|
+
def visit_nodes(nodes, my_left, parent, depth, tree, url, restricted)
|
244
|
+
nodes.each do |item|
|
245
|
+
my_right = my_left + 1
|
246
|
+
my_restricted = item['restricted'] || restricted
|
247
|
+
urls = process_url(url, item)
|
248
|
+
|
249
|
+
if item['children']
|
250
|
+
my_right, tree = visit_nodes(item['children'], my_left + 1, item['id'], depth + 1, tree, urls[:children_path], my_restricted)
|
251
|
+
end
|
252
|
+
|
253
|
+
tree[item['id']] = TreeNode.new(my_left, my_right, parent, depth, urls[:my_urlname], my_restricted)
|
254
|
+
my_left = my_right + 1
|
255
|
+
end
|
256
|
+
|
257
|
+
[my_left, tree]
|
258
|
+
end
|
259
|
+
|
260
|
+
# Returns a Hash of TreeNode's indexed by their page ids
|
261
|
+
#
|
262
|
+
# Grabs the array representing a tree structure of pages passed as a parameter,
|
263
|
+
# visits it and creates a map of TreeNodes indexed by page id featuring Nested Set
|
264
|
+
# ordering information consisting of the left, right, depth and parent_id indexes as
|
265
|
+
# well as a node's url and restricted status
|
266
|
+
#
|
267
|
+
# @param [Array]
|
268
|
+
# An Array representing a tree of Alchemy::Page's
|
269
|
+
# @param [Alchemy::Page]
|
270
|
+
# The root page for the language being ordered
|
271
|
+
#
|
272
|
+
def create_tree(items, rootpage)
|
273
|
+
_, tree = visit_nodes(items, rootpage.lft + 1, rootpage.id, rootpage.depth + 1, {}, "", rootpage.restricted)
|
274
|
+
tree
|
275
|
+
end
|
276
|
+
|
277
|
+
# Returns a pair, the path that a given tree node should take, and the path its children should take
|
278
|
+
#
|
279
|
+
# This function will add a node's own slug into their ancestor's path
|
280
|
+
# in order to create the full URL of a node
|
281
|
+
#
|
282
|
+
# NOTE: external and invisible pages are not part of the full path of their children
|
283
|
+
#
|
284
|
+
# @param [String]
|
285
|
+
# The node's ancestors path
|
286
|
+
# @param [Hash]
|
287
|
+
# A children node
|
288
|
+
#
|
289
|
+
def process_url(ancestors_path, item)
|
290
|
+
default_urlname = (ancestors_path.blank? ? "" : "#{ancestors_path}/") + item['slug']
|
291
|
+
|
292
|
+
pair = {my_urlname: default_urlname, children_path: default_urlname}
|
293
|
+
|
294
|
+
if item['external'] == true || item['visible'] == false
|
295
|
+
# children ignore an ancestor in their path if external or invisible
|
296
|
+
pair[:children_path] = ancestors_path
|
297
|
+
end
|
298
|
+
|
299
|
+
pair
|
300
|
+
end
|
301
|
+
|
218
302
|
def load_page
|
219
303
|
@page = Page.find(params[:id])
|
220
304
|
end
|
@@ -223,17 +307,6 @@ module Alchemy
|
|
223
307
|
request.raw_post.split('&').map { |i| i = {i.split('=')[0].gsub(/[^0-9]/, '') => i.split('=')[1]} }
|
224
308
|
end
|
225
309
|
|
226
|
-
# Taken from https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop
|
227
|
-
def sort_children(element, dbitem)
|
228
|
-
prevchild = nil
|
229
|
-
element['children'].each do |child|
|
230
|
-
childitem = Page.find(child['id'])
|
231
|
-
prevchild.nil? ? childitem.move_to_child_of(dbitem) : childitem.move_to_right_of(prevchild)
|
232
|
-
sort_children(child, childitem) unless child['children'].nil?
|
233
|
-
prevchild = childitem
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
310
|
def redirect_path_for_switch_language
|
238
311
|
if request.referer && request.referer.include?('admin/layoutpages')
|
239
312
|
admin_layoutpages_path
|
@@ -26,7 +26,7 @@ module Alchemy
|
|
26
26
|
if tag_params[:merge_to]
|
27
27
|
@new_tag = ActsAsTaggableOn::Tag.find(tag_params[:merge_to])
|
28
28
|
Tag.replace(@tag, @new_tag)
|
29
|
-
operation_text = _t('Replaced Tag
|
29
|
+
operation_text = _t('Replaced Tag') % {old_tag: @tag.name, new_tag: @new_tag.name}
|
30
30
|
@tag.destroy
|
31
31
|
else
|
32
32
|
@tag.update_attributes(tag_params)
|
@@ -45,68 +45,69 @@ module Alchemy
|
|
45
45
|
return false
|
46
46
|
end
|
47
47
|
|
48
|
-
def send_image(
|
48
|
+
def send_image(image, format)
|
49
49
|
ALLOWED_IMAGE_TYPES.each do |type|
|
50
50
|
format.send(type) do
|
51
51
|
if type == 'jpeg'
|
52
52
|
quality = params[:quality] || Config.get(:output_image_jpg_quality)
|
53
|
-
|
53
|
+
image = image.encode(type, "-quality #{quality}")
|
54
54
|
else
|
55
|
-
|
55
|
+
image = image.encode(type)
|
56
56
|
end
|
57
|
-
render text:
|
57
|
+
render text: image.data
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
# Return the processed image dependent of size and cropping parameters
|
63
63
|
def processed_image
|
64
|
-
|
65
|
-
if
|
64
|
+
@image = @picture.image_file
|
65
|
+
if @image.nil?
|
66
66
|
raise MissingImageFileError, "Missing image file for #{@picture.inspect}"
|
67
67
|
end
|
68
|
-
if
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
68
|
+
if @size.present?
|
69
|
+
if params[:crop_size].present? && params[:crop_from].present?
|
70
|
+
@image = @image.thumb xy_crop_geometry_string(params)
|
71
|
+
@image.thumb(resize_geometry_string)
|
72
|
+
elsif params[:crop]
|
73
|
+
@image.thumb(center_crop_geometry_string)
|
74
|
+
else
|
75
|
+
@image.thumb(resize_geometry_string)
|
76
|
+
end
|
76
77
|
else
|
77
|
-
|
78
|
+
@image
|
78
79
|
end
|
79
80
|
end
|
80
81
|
|
81
82
|
# Returns the Imagemagick geometry string for cropping the image.
|
82
|
-
def
|
83
|
+
def xy_crop_geometry_string(params)
|
83
84
|
crop_from_x, crop_from_y = params[:crop_from].split('x')
|
84
85
|
"#{params[:crop_size]}+#{crop_from_x}+#{crop_from_y}"
|
85
86
|
end
|
86
87
|
|
87
88
|
# Returns the Imagemagick geometry string used to resize the image.
|
89
|
+
#
|
90
|
+
# Prevents upscaling unless :upsample param is true.
|
88
91
|
def resize_geometry_string
|
89
|
-
@
|
90
|
-
params[:upsample] == 'true' ? @size.to_s : "#{@size}>"
|
91
|
-
end
|
92
|
+
params[:upsample] == 'true' ? @size : "#{@size}>"
|
92
93
|
end
|
93
94
|
|
94
|
-
# Returns
|
95
|
+
# Returns the Imagemagick geometry string used to crop the image.
|
95
96
|
#
|
96
|
-
# Prevents upscaling unless :upsample param is true
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
97
|
+
# Prevents upscaling unless :upsample param is true
|
98
|
+
def center_crop_geometry_string
|
99
|
+
params[:upsample] == 'true' ? "#{@size}#" : "#{normalized_sizes(*@size.split('x'))}#"
|
100
|
+
end
|
101
|
+
|
102
|
+
# Ensure we're not trying to scale the image up. Used only for cropping.
|
103
|
+
def normalized_sizes(width, height)
|
104
|
+
if width.to_i > @image.width
|
105
|
+
width = @image.width
|
104
106
|
end
|
105
|
-
if height >
|
106
|
-
height =
|
107
|
+
if height.to_i > @image.height
|
108
|
+
height = @image.height
|
107
109
|
end
|
108
|
-
|
110
|
+
"#{width}x#{height}"
|
109
111
|
end
|
110
|
-
|
111
112
|
end
|
112
113
|
end
|
@@ -34,12 +34,6 @@ module Alchemy
|
|
34
34
|
#
|
35
35
|
# <%= link_to_dialog('Edit', edit_product_path, {size: '200x300'}, {class: 'icon_button'}) %>
|
36
36
|
#
|
37
|
-
# Or you call it with a block
|
38
|
-
#
|
39
|
-
# <%= link_to_dialog edit_product_path, {size: 200x300} do %>
|
40
|
-
# <%= render_icon(:edit) %>
|
41
|
-
# <% end %>
|
42
|
-
#
|
43
37
|
# @param [String] content
|
44
38
|
# The string inside the link tag
|
45
39
|
# @param [String or Hash] url
|
@@ -56,18 +50,11 @@ module Alchemy
|
|
56
50
|
# @option options [Boolean] :modal (true)
|
57
51
|
# Show as modal window.
|
58
52
|
#
|
59
|
-
def link_to_dialog(content
|
60
|
-
html_options, options, url, content = options, url, content, block if block_given?
|
53
|
+
def link_to_dialog(content, url, options={}, html_options={})
|
61
54
|
default_options = {modal: true}
|
62
55
|
options = default_options.merge(options)
|
63
|
-
|
64
|
-
|
65
|
-
html_options.merge('data-alchemy-dialog' => options.to_json),
|
66
|
-
&block
|
67
|
-
else
|
68
|
-
link_to content, url,
|
69
|
-
html_options.merge('data-alchemy-dialog' => options.to_json)
|
70
|
-
end
|
56
|
+
link_to content, url,
|
57
|
+
html_options.merge('data-alchemy-dialog' => options.to_json)
|
71
58
|
end
|
72
59
|
|
73
60
|
# Used for translations selector in Alchemy cockpit user settings.
|
@@ -115,7 +115,7 @@ module Alchemy
|
|
115
115
|
|
116
116
|
def all_from_clipboard(clipboard)
|
117
117
|
return [] if clipboard.nil?
|
118
|
-
where(id: clipboard.collect { |e| e[
|
118
|
+
where(id: clipboard.collect { |e| e['id'] })
|
119
119
|
end
|
120
120
|
|
121
121
|
# All elements in clipboard that could be placed on page
|
@@ -16,8 +16,10 @@ module Alchemy
|
|
16
16
|
uniqueness: {scope: [:language_id, :layoutpage], if: 'urlname.present?'},
|
17
17
|
exclusion: {in: RESERVED_URLNAMES},
|
18
18
|
length: {minimum: 3, if: 'urlname.present?'},
|
19
|
-
format: {with: /\A[:\.\w\-+_\/\?&%;=]*\z/, if: :redirects_to_external?}
|
20
|
-
|
19
|
+
format: {with: /\A[:\.\w\-+_\/\?&%;=]*\z/, if: :redirects_to_external?}
|
20
|
+
validates :urlname,
|
21
|
+
on: :update,
|
22
|
+
presence: {if: :redirects_to_external?}
|
21
23
|
|
22
24
|
before_save :set_title, :if => 'title.blank?', :unless => proc { systempage? || redirects_to_external? }
|
23
25
|
after_update :update_descendants_urlnames,
|
@@ -27,7 +27,7 @@ module Alchemy
|
|
27
27
|
|
28
28
|
# Returns true or false if the pages layout_description for config/alchemy/page_layouts.yml contains redirects_to_external: true
|
29
29
|
def redirects_to_external?
|
30
|
-
definition["redirects_to_external"]
|
30
|
+
!!definition["redirects_to_external"]
|
31
31
|
end
|
32
32
|
|
33
33
|
def has_controller?
|
data/app/models/alchemy/page.rb
CHANGED
@@ -177,7 +177,7 @@ module Alchemy
|
|
177
177
|
|
178
178
|
def all_from_clipboard(clipboard)
|
179
179
|
return [] if clipboard.blank?
|
180
|
-
where(id: clipboard.collect { |p| p[
|
180
|
+
where(id: clipboard.collect { |p| p['id'] })
|
181
181
|
end
|
182
182
|
|
183
183
|
def all_from_clipboard_for_select(clipboard, language_id, layoutpage = false)
|
@@ -333,6 +333,25 @@ module Alchemy
|
|
333
333
|
update_columns(published_at: Time.now, public: true)
|
334
334
|
end
|
335
335
|
|
336
|
+
# Updates an Alchemy::Page based on a new ordering to be applied to it
|
337
|
+
#
|
338
|
+
# Note: Page's urls should not be updated (and a legacy URL created) if nesting is OFF
|
339
|
+
# or if a page is external or if the URL is the same
|
340
|
+
#
|
341
|
+
# @param [TreeNode]
|
342
|
+
# A tree node with new lft, rgt, depth, url, parent_id and restricted indexes to be updated
|
343
|
+
#
|
344
|
+
def update_node!(node)
|
345
|
+
hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted}
|
346
|
+
|
347
|
+
if Config.get(:url_nesting) && !self.redirects_to_external? && self.urlname != node.url
|
348
|
+
LegacyPageUrl.create(page_id: self.id, urlname: self.urlname)
|
349
|
+
hash.merge!(urlname: node.url)
|
350
|
+
end
|
351
|
+
|
352
|
+
update_columns(hash)
|
353
|
+
end
|
354
|
+
|
336
355
|
private
|
337
356
|
|
338
357
|
# Returns the next or previous page on the same level or nil.
|
@@ -1,24 +1,23 @@
|
|
1
1
|
<div class="element_editor<%= element.folded ? ' folded' : '' %> <%= defined?(draggable) && !draggable ? 'not-draggable' : 'draggable' %>" id="element_<%= element.id %>" data-element-id="<%= element.id %>">
|
2
|
-
<%=
|
3
|
-
|
4
|
-
|
2
|
+
<%= render :partial => "alchemy/admin/elements/element_head", :locals => {:element => element} %>
|
3
|
+
<% if !element.folded? %>
|
4
|
+
<%= form_for [:admin, element], :remote => true, :html => {:id => "element_#{element.id}_form"} do |f| %>
|
5
5
|
<div id="element_<%= element.id %>_errors" class="element_errors" style="display: none"></div>
|
6
6
|
<div id="element_<%= element.id %>_content" class="element_content">
|
7
7
|
<%= render_editor(element) %>
|
8
8
|
</div>
|
9
9
|
<% if element.has_validations? %>
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
<p class="validation_notice">
|
11
|
+
<span class="validation_indicator">*</span> <%= _t('Mandatory') %>
|
12
|
+
</p>
|
13
13
|
<% end %>
|
14
14
|
<% if element.taggable? %>
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
<div class="autocomplete_tag_list">
|
16
|
+
<%= f.label :tag_list %>
|
17
|
+
<%= render 'alchemy/admin/partials/autocomplete_tag_list', f: f %>
|
18
|
+
</div>
|
19
19
|
<% end %>
|
20
|
-
<%= render 'alchemy/admin/elements/element_foot',
|
20
|
+
<%= render :partial => 'alchemy/admin/elements/element_foot', :locals => {:element => element, :f => f} %>
|
21
21
|
<% end %>
|
22
22
|
<% end %>
|
23
|
-
<%= render 'alchemy/admin/elements/add_element_button', element_before: element %>
|
24
23
|
</div>
|