alchemy_cms 2.6.0.rc5 → 2.6.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.
- data/.travis.yml +1 -1
- data/Gemfile +2 -1
- data/README.md +2 -4
- data/alchemy_cms.gemspec +1 -1
- data/app/assets/fonts/alchemy/icons.eot +0 -0
- data/app/assets/fonts/alchemy/icons.svg +71 -0
- data/app/assets/fonts/alchemy/icons.ttf +0 -0
- data/app/assets/fonts/alchemy/icons.woff +0 -0
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +6 -8
- data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +2 -3
- data/app/assets/javascripts/alchemy/alchemy.image_cropper.js.coffee +3 -8
- data/app/assets/javascripts/alchemy/alchemy.link_overlay.js.coffee +3 -3
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +19 -9
- data/app/assets/javascripts/tiny_mce/plugins/alchemy_link/editor_plugin.js +6 -7
- data/app/assets/stylesheets/alchemy/admin.css.scss +0 -1
- data/app/assets/stylesheets/alchemy/archive.scss +55 -7
- data/app/assets/stylesheets/alchemy/base.scss +8 -144
- data/app/assets/stylesheets/alchemy/defaults.scss +1 -1
- data/app/assets/stylesheets/alchemy/elements.scss +20 -16
- data/app/assets/stylesheets/alchemy/flash.scss +1 -1
- data/app/assets/stylesheets/alchemy/form_elements.scss +49 -42
- data/app/assets/stylesheets/alchemy/icon-font.css.scss +67 -0
- data/app/assets/stylesheets/alchemy/icons.scss +16 -4
- data/app/assets/stylesheets/alchemy/jquery-ui.scss +40 -26
- data/app/assets/stylesheets/alchemy/menubar.css.scss +1 -1
- data/app/assets/stylesheets/alchemy/notices.scss +6 -1
- data/app/assets/stylesheets/alchemy/search.scss +3 -2
- data/app/assets/stylesheets/alchemy/sitemap.scss +72 -13
- data/app/assets/stylesheets/alchemy/tables.scss +31 -24
- data/app/assets/stylesheets/alchemy/upload.scss +1 -1
- data/app/assets/stylesheets/alchemy/variables.scss +2 -1
- data/app/assets/stylesheets/tiny_mce/plugins/inlinepopups/skins/{alchemy → alchemy-tinymce-dialog}/window.css.scss +70 -65
- data/app/controllers/alchemy/admin/base_controller.rb +7 -4
- data/app/controllers/alchemy/admin/pictures_controller.rb +2 -0
- data/app/controllers/alchemy/admin/users_controller.rb +1 -1
- data/app/controllers/alchemy/user_sessions_controller.rb +1 -1
- data/app/helpers/alchemy/admin/base_helper.rb +161 -60
- data/app/helpers/alchemy/admin/pages_helper.rb +4 -1
- data/app/helpers/alchemy/elements_block_helper.rb +1 -1
- data/app/helpers/alchemy/elements_helper.rb +119 -31
- data/app/helpers/alchemy/pages_helper.rb +29 -72
- data/app/models/alchemy/attachment.rb +0 -2
- data/app/models/alchemy/content.rb +1 -1
- data/app/models/alchemy/language.rb +1 -0
- data/app/models/alchemy/page.rb +8 -8
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +3 -1
- data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +1 -1
- data/app/views/alchemy/admin/attachments/_tag_list.html.erb +25 -27
- data/app/views/alchemy/admin/attachments/index.html.erb +4 -1
- data/app/views/alchemy/admin/elements/_elements_select.html.erb +6 -6
- data/app/views/alchemy/admin/elements/list.js.erb +1 -1
- data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_page_for_links.html.erb +1 -1
- data/app/views/alchemy/admin/pages/edit.html.erb +4 -2
- data/app/views/alchemy/admin/pictures/_archive.html.erb +0 -1
- data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +2 -1
- data/app/views/alchemy/admin/pictures/_picture.html.erb +5 -0
- data/app/views/alchemy/admin/pictures/index.html.erb +1 -0
- data/app/views/alchemy/base/500.html.erb +26 -5
- data/app/views/alchemy/essences/_essence_picture_tools.html.erb +1 -1
- data/app/views/alchemy/essences/_linkable_essence_tools.html.erb +1 -1
- data/app/views/alchemy/language_links/_language.html.erb +12 -0
- data/app/views/alchemy/language_links/_spacer.html.erb +1 -0
- data/config/locales/alchemy.de.yml +7 -3
- data/config/locales/alchemy.en.yml +8 -3
- data/lib/alchemy/page_layout.rb +1 -1
- data/lib/alchemy/tinymce.rb +1 -1
- data/lib/alchemy/upgrader.rb +26 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +4 -1
- data/lib/tasks/ferret.rake +1 -0
- data/spec/controllers/admin/users_controller_spec.rb +5 -5
- data/spec/features/admin/pages_controller_spec.rb +1 -1
- data/spec/helpers/admin/pages_helper_spec.rb +31 -0
- data/spec/helpers/pages_helper_spec.rb +60 -72
- data/spec/models/content_spec.rb +2 -1
- data/spec/models/page_layout_spec.rb +29 -0
- data/spec/models/page_spec.rb +33 -1
- data/spec/support/alchemy/test_tweaks.rb +2 -6
- metadata +34 -12
- data/app/assets/fonts/alchemy-icons.eot +0 -0
- data/app/assets/fonts/alchemy-icons.svg +0 -54
- data/app/assets/fonts/alchemy-icons.ttf +0 -0
- data/app/assets/fonts/alchemy-icons.woff +0 -0
- data/app/assets/images/alchemy/placeholder.png +0 -0
- data/app/assets/stylesheets/alchemy/fonts.scss +0 -46
|
@@ -20,17 +20,20 @@ module Alchemy
|
|
|
20
20
|
def exception_handler(e)
|
|
21
21
|
exception_logger(e)
|
|
22
22
|
show_error_notice(e)
|
|
23
|
+
if defined?(Airbrake)
|
|
24
|
+
notify_airbrake(e) unless Rails.env.development? || Rails.env.test?
|
|
25
|
+
end
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
# Displays an error notice in the Alchemy backend.
|
|
26
29
|
def show_error_notice(e)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@
|
|
30
|
+
@error = e
|
|
31
|
+
# truncate the message, because very long error messages (i.e from mysql2) causes cookie overflow errors
|
|
32
|
+
@notice = e.message[0..255]
|
|
33
|
+
@trace = e.backtrace[0..35]
|
|
30
34
|
if request.xhr?
|
|
31
35
|
render :action => "error_notice", :layout => false
|
|
32
36
|
else
|
|
33
|
-
flash.now[:error] = @notice
|
|
34
37
|
render '500', :status => 500
|
|
35
38
|
end
|
|
36
39
|
end
|
|
@@ -17,6 +17,8 @@ module Alchemy
|
|
|
17
17
|
@pictures = @pictures.recent
|
|
18
18
|
when 'last_upload'
|
|
19
19
|
@pictures = @pictures.last_upload
|
|
20
|
+
when 'without_tag'
|
|
21
|
+
@pictures = @pictures.where("cached_tag_list IS NULL OR cached_tag_list = ''")
|
|
20
22
|
end
|
|
21
23
|
@pictures = @pictures.find_paginated(params, pictures_per_page_for_size(@size))
|
|
22
24
|
if in_overlay?
|
|
@@ -44,7 +44,7 @@ module Alchemy
|
|
|
44
44
|
|
|
45
45
|
def update
|
|
46
46
|
# User is fetched via before filter
|
|
47
|
-
params[:user].delete(:
|
|
47
|
+
params[:user].delete(:roles) unless permitted_to?(:update_roles)
|
|
48
48
|
if params[:user][:password].present?
|
|
49
49
|
@user.update_attributes(params[:user])
|
|
50
50
|
else
|
|
@@ -4,7 +4,7 @@ module Alchemy
|
|
|
4
4
|
include Alchemy::FerretSearch
|
|
5
5
|
helper 'Alchemy::Admin::Base', 'Alchemy::Pages'
|
|
6
6
|
|
|
7
|
-
before_filter { enforce_ssl if ssl_required? && !request.ssl? }
|
|
7
|
+
before_filter(except: 'destroy') { enforce_ssl if ssl_required? && !request.ssl? }
|
|
8
8
|
before_filter :set_translation
|
|
9
9
|
before_filter :check_user_count, :only => :new
|
|
10
10
|
|
|
@@ -5,26 +5,43 @@ module Alchemy
|
|
|
5
5
|
#
|
|
6
6
|
# The most important helpers for module developers are:
|
|
7
7
|
#
|
|
8
|
-
# * toolbar
|
|
9
|
-
# * toolbar_button
|
|
10
|
-
# * link_to_overlay_window
|
|
11
|
-
# * link_to_confirmation_window
|
|
8
|
+
# * {#toolbar}
|
|
9
|
+
# * {#toolbar_button}
|
|
10
|
+
# * {#link_to_overlay_window}
|
|
11
|
+
# * {#link_to_confirmation_window}
|
|
12
12
|
#
|
|
13
13
|
module BaseHelper
|
|
14
14
|
include Alchemy::BaseHelper
|
|
15
15
|
|
|
16
|
-
# This helper renders the link
|
|
16
|
+
# This helper renders the link to an overlay window.
|
|
17
17
|
#
|
|
18
18
|
# We use this for our fancy modal overlay windows in the Alchemy cockpit.
|
|
19
19
|
#
|
|
20
|
-
#
|
|
20
|
+
# == Example
|
|
21
21
|
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
22
|
+
# <%= link_to_overlay_window('Edit', edit_product_path, {size: '200x300'}, {class: 'icon_button'}) %>
|
|
23
|
+
#
|
|
24
|
+
# @param [String] content
|
|
25
|
+
# The string inside the link tag
|
|
26
|
+
# @param [String or Hash] url
|
|
27
|
+
# The url of the action displayed inside the overlay window.
|
|
28
|
+
# @param [Hash] options
|
|
29
|
+
# options for the overlay window.
|
|
30
|
+
# @param [Hash] html_options
|
|
31
|
+
# HTML options passed to the <tt>link_to</tt> helper
|
|
32
|
+
#
|
|
33
|
+
# @option options [String] :size
|
|
34
|
+
# String with format of "WidthxHeight". I.E. ("420x280")
|
|
35
|
+
# @option options [String] :title
|
|
36
|
+
# Text for the overlay title bar.
|
|
37
|
+
# @option options [Boolean] :overflow (false)
|
|
38
|
+
# Should the dialog have overlapping content. If not, it shows scrollbars. Good for select boxes.
|
|
39
|
+
# @option options [Boolean] :resizable (false)
|
|
40
|
+
# Is the dialog window resizable?
|
|
41
|
+
# @option options [Boolean] :modal (true)
|
|
42
|
+
# Show as modal window.
|
|
43
|
+
# @option options [Boolean] :overflow (true)
|
|
44
|
+
# Should the window show overflowing content?
|
|
28
45
|
#
|
|
29
46
|
def link_to_overlay_window(content, url, options={}, html_options={})
|
|
30
47
|
default_options = {
|
|
@@ -79,10 +96,30 @@ module Alchemy
|
|
|
79
96
|
end
|
|
80
97
|
end
|
|
81
98
|
|
|
82
|
-
#
|
|
99
|
+
# Returns a javascript driven live filter for lists.
|
|
100
|
+
#
|
|
101
|
+
# The items must have a html +name+ attribute that holds the filterable value.
|
|
102
|
+
#
|
|
103
|
+
# == Example
|
|
104
|
+
#
|
|
105
|
+
# Given a list of items:
|
|
106
|
+
#
|
|
107
|
+
# <%= js_filter_field('#products .product') %>
|
|
83
108
|
#
|
|
84
|
-
#
|
|
85
|
-
#
|
|
109
|
+
# <ul id="products">
|
|
110
|
+
# <li class="product" name="kat litter">Kat Litter</li>
|
|
111
|
+
# <li class="product" name="milk">Milk</li>
|
|
112
|
+
# </ul>
|
|
113
|
+
#
|
|
114
|
+
# @param [String] items
|
|
115
|
+
# A jquery compatible selector string that represents the items to filter
|
|
116
|
+
# @param [Hash] options
|
|
117
|
+
# HTML options passed to the input field
|
|
118
|
+
#
|
|
119
|
+
# @option options [String] :class ('js_filter_field')
|
|
120
|
+
# The css class of the <input> tag
|
|
121
|
+
# @option options [String or Hash] :data ({'alchemy-list-filter' => items})
|
|
122
|
+
# A HTML data attribute that holds the jQuery selector that represents the list to be filtered
|
|
86
123
|
#
|
|
87
124
|
def js_filter_field(items, options = {})
|
|
88
125
|
options = {
|
|
@@ -99,17 +136,28 @@ module Alchemy
|
|
|
99
136
|
|
|
100
137
|
# Returns a link that opens a modal confirmation to delete window.
|
|
101
138
|
#
|
|
102
|
-
# === Parameters:
|
|
103
|
-
#
|
|
104
|
-
# 1. The content inside the <a> tag
|
|
105
|
-
# 2. The message that is displayed in the overlay window
|
|
106
|
-
# 3. The url that gets opened after confirmation (Note: This is an Ajax request with a method of DELETE!)
|
|
107
|
-
# 4. html options get passed to the link
|
|
108
|
-
#
|
|
109
139
|
# === Example:
|
|
110
140
|
#
|
|
111
141
|
# <%= link_to_confirmation_window('delete', 'Do you really want to delete this comment?', '/admin/comments/1') %>
|
|
112
142
|
#
|
|
143
|
+
# @param [String] link_string
|
|
144
|
+
# The content inside the <a> tag
|
|
145
|
+
# @param [String] message
|
|
146
|
+
# The message that is displayed in the overlay window
|
|
147
|
+
# @param [String] url
|
|
148
|
+
# The url that gets opened after confirmation (Note: This is an Ajax request with a method of DELETE!)
|
|
149
|
+
# @param [Hash] html_options
|
|
150
|
+
# HTML options get passed to the link
|
|
151
|
+
#
|
|
152
|
+
# @option html_options [String] :title (_t(:please_confirm))
|
|
153
|
+
# The overlay title
|
|
154
|
+
# @option html_options [String] :message (message)
|
|
155
|
+
# The message displayed in the overlay
|
|
156
|
+
# @option html_options [String] :ok_label (_t("Yes"))
|
|
157
|
+
# The label for the ok button
|
|
158
|
+
# @option html_options [String] :cancel_label (_t("No"))
|
|
159
|
+
# The label for the cancel button
|
|
160
|
+
#
|
|
113
161
|
def link_to_confirmation_window(link_string = "", message = "", url = "", html_options = {})
|
|
114
162
|
link_to(link_string, url,
|
|
115
163
|
html_options.merge(
|
|
@@ -127,19 +175,21 @@ module Alchemy
|
|
|
127
175
|
#
|
|
128
176
|
# After confirmation it proceeds to send the form's action.
|
|
129
177
|
#
|
|
130
|
-
# === Parameters:
|
|
131
|
-
#
|
|
132
|
-
# 1. The content inside the <a> tag
|
|
133
|
-
# 2. The url that gets opened after confirmation
|
|
134
|
-
# 3. Options for the Alchemy confirm overlay (See: app/assets/javascripts/alchemy/alchemy.window.js#openConfirmWindow)
|
|
135
|
-
# 4. HTML options that get passed to the button_tag helper.
|
|
136
|
-
#
|
|
137
|
-
# NOTE: The method option in the html_options hash gets passed to the form_tag helper!
|
|
138
|
-
#
|
|
139
178
|
# === Example:
|
|
140
179
|
#
|
|
141
180
|
# <%= button_with_confirm('pay', '/admin/orders/1/pay', message: 'Do you really want to mark this order as payed?') %>
|
|
142
181
|
#
|
|
182
|
+
# @param [String] value
|
|
183
|
+
# The content inside the <tt><a></tt> tag
|
|
184
|
+
# @param [String] url
|
|
185
|
+
# The url that gets opened after confirmation
|
|
186
|
+
# @param [Hash] options
|
|
187
|
+
# Options for the Alchemy confirm overlay (see also +app/assets/javascripts/alchemy/alchemy.window.js#openConfirmWindow+)
|
|
188
|
+
# @param [Hash] html_options
|
|
189
|
+
# HTML options that get passed to the +button_tag+ helper.
|
|
190
|
+
#
|
|
191
|
+
# @note The method option in the <tt>html_options</tt> hash gets passed to the <tt>form_tag</tt> helper!
|
|
192
|
+
#
|
|
143
193
|
def button_with_confirm(value = "", url = "", options = {}, html_options = {})
|
|
144
194
|
options = {
|
|
145
195
|
message: _t(:confirm_to_proceed),
|
|
@@ -153,12 +203,15 @@ module Alchemy
|
|
|
153
203
|
end
|
|
154
204
|
|
|
155
205
|
# Returns an Array build for passing it to the options_for_select helper inside an essence editor partial.
|
|
156
|
-
# Usefull for the select_values options from the render_essence_editor helpers.
|
|
157
206
|
#
|
|
158
|
-
#
|
|
207
|
+
# Useful for the <tt>select_values</tt> options from the {Alchemy::Admin::EssencesHelper#render_essence_editor} helpers.
|
|
159
208
|
#
|
|
160
|
-
#
|
|
161
|
-
#
|
|
209
|
+
# @option options [String or Page] :from_page (nil)
|
|
210
|
+
# Return only elements from this page. You can either pass a Page instance, or a page_layout name
|
|
211
|
+
# @option options [Array or String] :elements_with_name (nil)
|
|
212
|
+
# Return only elements with this name(s).
|
|
213
|
+
# @option options [String] :prompt (_t('Please choose'))
|
|
214
|
+
# Prompt inside the select tag.
|
|
162
215
|
#
|
|
163
216
|
def elements_for_essence_editor_select(options={})
|
|
164
217
|
defaults = {
|
|
@@ -184,12 +237,14 @@ module Alchemy
|
|
|
184
237
|
|
|
185
238
|
# Returns all public pages from current language as an option tags string suitable or the Rails +select_tag+ helper.
|
|
186
239
|
#
|
|
187
|
-
#
|
|
188
|
-
#
|
|
189
|
-
#
|
|
190
|
-
#
|
|
191
|
-
#
|
|
192
|
-
#
|
|
240
|
+
# @param [Array]
|
|
241
|
+
# A collection of pages so it only returns these pages and does not query the database.
|
|
242
|
+
# @param [String]
|
|
243
|
+
# Pass a +Page#name+ or +Page#id+ as selected item to the +options_for_select+ helper.
|
|
244
|
+
# @param [String]
|
|
245
|
+
# Used as prompt message in the select tag
|
|
246
|
+
# @param [Symbol]
|
|
247
|
+
# Method that is called on the page object to get the value that is passed with the params of the form.
|
|
193
248
|
#
|
|
194
249
|
def pages_for_select(pages = nil, selected = nil, prompt = "", page_attribute = :id)
|
|
195
250
|
result = [[prompt.blank? ? _t('Choose page') : prompt, ""]]
|
|
@@ -223,6 +278,7 @@ module Alchemy
|
|
|
223
278
|
)
|
|
224
279
|
end
|
|
225
280
|
|
|
281
|
+
# Renders the admin main navigation
|
|
226
282
|
def admin_main_navigation
|
|
227
283
|
entries = ""
|
|
228
284
|
alchemy_modules.each do |alchemy_module|
|
|
@@ -231,10 +287,16 @@ module Alchemy
|
|
|
231
287
|
entries.html_safe
|
|
232
288
|
end
|
|
233
289
|
|
|
290
|
+
# Renders one admin main navigation entry
|
|
291
|
+
#
|
|
292
|
+
# @param [Hash] alchemy_module
|
|
293
|
+
# The Hash representing a Alchemy module
|
|
294
|
+
#
|
|
234
295
|
def alchemy_main_navigation_entry(alchemy_module)
|
|
235
296
|
render 'alchemy/admin/partials/main_navigation_entry', :alchemy_module => alchemy_module.stringify_keys, :navigation => alchemy_module['navigation'].stringify_keys
|
|
236
297
|
end
|
|
237
298
|
|
|
299
|
+
# Renders the subnavigation in the admin areas
|
|
238
300
|
def admin_subnavigation
|
|
239
301
|
alchemy_module = module_definition_for(:controller => params[:controller], :action => 'index')
|
|
240
302
|
unless alchemy_module.nil?
|
|
@@ -268,6 +330,7 @@ module Alchemy
|
|
|
268
330
|
end
|
|
269
331
|
end
|
|
270
332
|
|
|
333
|
+
# Returns true if the subnavigation entry is in the current params
|
|
271
334
|
def admin_sub_navigation_entry_active?(entry)
|
|
272
335
|
params[:controller] == entry["controller"].gsub(/^\//, '') && (params[:action] == entry["action"] || entry["nested_actions"] && entry["nested_actions"].include?(params[:action]))
|
|
273
336
|
end
|
|
@@ -351,18 +414,26 @@ module Alchemy
|
|
|
351
414
|
|
|
352
415
|
# Renders a toolbar button for the Alchemy toolbar
|
|
353
416
|
#
|
|
354
|
-
#
|
|
355
|
-
#
|
|
356
|
-
#
|
|
357
|
-
#
|
|
358
|
-
#
|
|
359
|
-
#
|
|
360
|
-
#
|
|
361
|
-
#
|
|
362
|
-
#
|
|
363
|
-
#
|
|
364
|
-
#
|
|
365
|
-
#
|
|
417
|
+
# @option options [String] :icon
|
|
418
|
+
# Icon class. See +app/assets/stylesheets/alchemy/icons.css.sccs+ for available icons, or make your own.
|
|
419
|
+
# @option options [String] :label
|
|
420
|
+
# Text for button label.
|
|
421
|
+
# @option options [String] :url
|
|
422
|
+
# Url for link.
|
|
423
|
+
# @option options [String] :title
|
|
424
|
+
# Text for title tag.
|
|
425
|
+
# @option options [String] :hotkey
|
|
426
|
+
# Keyboard shortcut for this button. I.E +alt-n+
|
|
427
|
+
# @option options [Boolean] :overlay (true)
|
|
428
|
+
# Open the link in a modal overlay window.
|
|
429
|
+
# @option options [Hash] :overlay_options
|
|
430
|
+
# Overlay options. See link_to_overlay_window helper.
|
|
431
|
+
# @option options [Array] :if_permitted_to ([:action, :controller])
|
|
432
|
+
# Check permission for button. Exactly how you defined the permission in your +authorization_rules.rb+. Defaults to controller and action from button url.
|
|
433
|
+
# @option options [Boolean] :skip_permission_check (false)
|
|
434
|
+
# Skip the permission check. NOT RECOMMENDED!
|
|
435
|
+
# @option options [Boolean] :loading_indicator (true)
|
|
436
|
+
# Shows the please wait overlay while loading. Only for buttons not opening an overlay window.
|
|
366
437
|
#
|
|
367
438
|
def toolbar_button(options = {})
|
|
368
439
|
options.symbolize_keys!
|
|
@@ -409,12 +480,32 @@ module Alchemy
|
|
|
409
480
|
end
|
|
410
481
|
end
|
|
411
482
|
|
|
412
|
-
# Renders the
|
|
483
|
+
# Renders the toolbar shown on top of the records.
|
|
413
484
|
#
|
|
414
|
-
# ==
|
|
485
|
+
# == Example
|
|
415
486
|
#
|
|
416
|
-
#
|
|
417
|
-
#
|
|
487
|
+
# <% label_title = _t("Create #{resource_name}", default: _t('Create')) %>
|
|
488
|
+
# <% toolbar(
|
|
489
|
+
# buttons: [
|
|
490
|
+
# {
|
|
491
|
+
# icon: 'create',
|
|
492
|
+
# label: label_title,
|
|
493
|
+
# url: new_resource_path,
|
|
494
|
+
# title: label_title,
|
|
495
|
+
# hotkey: 'alt-n',
|
|
496
|
+
# overlay_options: {
|
|
497
|
+
# title: label_title,
|
|
498
|
+
# size: "430x400"
|
|
499
|
+
# },
|
|
500
|
+
# if_permitted_to: [:new, resource_permission_scope]
|
|
501
|
+
# }
|
|
502
|
+
# ]
|
|
503
|
+
# ) %>
|
|
504
|
+
#
|
|
505
|
+
# @option options [Array] :buttons ([])
|
|
506
|
+
# Pass an Array with button options. They will be passed to {#toolbar_button} helper.
|
|
507
|
+
# @option options [Boolean] :search (true)
|
|
508
|
+
# Show searchfield.
|
|
418
509
|
#
|
|
419
510
|
def toolbar(options = {})
|
|
420
511
|
defaults = {
|
|
@@ -467,14 +558,24 @@ module Alchemy
|
|
|
467
558
|
|
|
468
559
|
# Renders a textfield ready to display a datepicker
|
|
469
560
|
#
|
|
470
|
-
# Uses a HTML5
|
|
471
|
-
#
|
|
472
|
-
# Pass a type as third option to override that. But old browsers hand this as text field anyway. So there is no need to override that.
|
|
561
|
+
# Uses a HTML5 <tt><input type="date"></tt> field.
|
|
473
562
|
#
|
|
474
563
|
# === Example
|
|
475
564
|
#
|
|
476
565
|
# <%= alchemy_datepicker(@person, :birthday) %>
|
|
477
566
|
#
|
|
567
|
+
# @param [ActiveModel::Base] object
|
|
568
|
+
# An instance of a model
|
|
569
|
+
# @param [String or Symbol] method
|
|
570
|
+
# The attribute method to be called for the date value
|
|
571
|
+
#
|
|
572
|
+
# @option html_options [String] :type ('date')
|
|
573
|
+
# The type of text field
|
|
574
|
+
# @option html_options [String] :class ('thin_border date')
|
|
575
|
+
# CSS classes of the input field
|
|
576
|
+
# @option html_options [String] :value (object.send(method.to_sym).nil? ? nil : l(object.send(method.to_sym), :format => :datepicker))
|
|
577
|
+
# The value the input displays
|
|
578
|
+
#
|
|
478
579
|
def alchemy_datepicker(object, method, html_options={})
|
|
479
580
|
text_field(object.class.name.underscore.to_sym, method.to_sym, {
|
|
480
581
|
:type => 'date',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
module Alchemy
|
|
2
2
|
module Admin
|
|
3
3
|
module PagesHelper
|
|
4
|
+
include Alchemy::BaseHelper
|
|
4
5
|
|
|
5
6
|
def tinymce_javascript_tags
|
|
6
7
|
init = Alchemy::Tinymce.init
|
|
@@ -99,7 +100,9 @@ module Alchemy
|
|
|
99
100
|
# Returns the translated explanation of the page´s status.
|
|
100
101
|
#
|
|
101
102
|
def combined_page_status(page)
|
|
102
|
-
|
|
103
|
+
page.status.map do |state, value|
|
|
104
|
+
page.status_title(state)
|
|
105
|
+
end.delete_if(&:blank?).join("<br>").html_safe
|
|
103
106
|
end
|
|
104
107
|
|
|
105
108
|
end
|
|
@@ -99,7 +99,7 @@ module Alchemy
|
|
|
99
99
|
#
|
|
100
100
|
# @option options :tag (:div)
|
|
101
101
|
# The HTML tag to be used for the wrapping element.
|
|
102
|
-
# @option options :id (the element's
|
|
102
|
+
# @option options :id (the element's dom_id)
|
|
103
103
|
# The wrapper tag's DOM ID.
|
|
104
104
|
# @option options :class (the element's essence name)
|
|
105
105
|
# The wrapper tag's DOM class.
|
|
@@ -1,30 +1,75 @@
|
|
|
1
1
|
module Alchemy
|
|
2
|
+
# This helpers are useful to render elements from pages.
|
|
3
|
+
#
|
|
4
|
+
# The most important helper for frontend developers is the {#render_elements} helper.
|
|
5
|
+
#
|
|
2
6
|
module ElementsHelper
|
|
3
|
-
|
|
4
7
|
include Alchemy::EssencesHelper
|
|
5
8
|
include Alchemy::UrlHelper
|
|
6
9
|
include Alchemy::ElementsBlockHelper
|
|
7
10
|
|
|
8
|
-
# Renders all elements from current page
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
# :
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
11
|
+
# Renders all elements from current page
|
|
12
|
+
#
|
|
13
|
+
# == Examples:
|
|
14
|
+
#
|
|
15
|
+
# === Render only certain elements:
|
|
16
|
+
#
|
|
17
|
+
# <header>
|
|
18
|
+
# <%= render_elements only: ['header', 'claim'] %>
|
|
19
|
+
# </header>
|
|
20
|
+
# <section id="content">
|
|
21
|
+
# <%= render_elements except: ['header', 'claim'] %>
|
|
22
|
+
# </section>
|
|
23
|
+
#
|
|
24
|
+
# === Render elements from global page:
|
|
25
|
+
#
|
|
26
|
+
# <footer>
|
|
27
|
+
# <%= render_elements from_page: 'footer' %>
|
|
28
|
+
# </footer>
|
|
29
|
+
#
|
|
30
|
+
# === Render elements from cell:
|
|
31
|
+
#
|
|
32
|
+
# <aside>
|
|
33
|
+
# <%= render_elements from_cell: 'sidebar' %>
|
|
34
|
+
# </aside>
|
|
35
|
+
#
|
|
36
|
+
# === Fallback to elements from global page:
|
|
37
|
+
#
|
|
38
|
+
# You can use the fallback option as an override for elements that are stored on another page.
|
|
39
|
+
# So you can take elements from a global page and only if the user adds an element on current page the
|
|
40
|
+
# local one gets rendered.
|
|
41
|
+
#
|
|
42
|
+
# 1. You have to pass the the name of the element the fallback is for as <tt>for</tt> key.
|
|
43
|
+
# 2. You have to pass a <tt>page_layout</tt> name or {Alchemy::Page} from where the fallback elements is taken from as <tt>from</tt> key.
|
|
44
|
+
# 3. You can pass the name of element to fallback with as <tt>with</tt> key. This is optional (the element name from the <tt>for</tt> key is taken as default).
|
|
45
|
+
#
|
|
46
|
+
# <%= render_elements(fallback: {
|
|
47
|
+
# for: 'contact_teaser',
|
|
48
|
+
# from: 'sidebar',
|
|
49
|
+
# with: 'contact_teaser'
|
|
50
|
+
# }) %>
|
|
51
|
+
#
|
|
52
|
+
# @param [Hash] options
|
|
53
|
+
# Additional options.
|
|
54
|
+
#
|
|
55
|
+
# @option options [Number] :count
|
|
56
|
+
# The amount of elements to be rendered (begins with first element found)
|
|
57
|
+
# @option options [Array or String] :except ([])
|
|
58
|
+
# A list of element names not to be rendered.
|
|
59
|
+
# @option options [Hash] :fallback
|
|
60
|
+
# Define elements that are rendered from another page.
|
|
61
|
+
# @option options [Alchemy::Cell or String] :from_cell
|
|
62
|
+
# The cell the elements are rendered from. You can pass a {Alchemy::Cell} name String or a {Alchemy::Cell} object.
|
|
63
|
+
# @option options [Alchemy::Page or String] :from_page (@page)
|
|
64
|
+
# The page the elements are rendered from. You can pass a page_layout String or a {Alchemy::Page} object.
|
|
65
|
+
# @option options [Array or String] :only ([])
|
|
66
|
+
# A list of element names only to be rendered.
|
|
67
|
+
# @option options [Boolean] :random
|
|
68
|
+
# Randomize the output of elements
|
|
69
|
+
# @option options [Boolean] :reverse
|
|
70
|
+
# Reverse the rendering order
|
|
71
|
+
# @option options [String] :sort_by
|
|
72
|
+
# The name of a {Alchemy::Content} to sort the elements by
|
|
28
73
|
#
|
|
29
74
|
def render_elements(options = {})
|
|
30
75
|
default_options = {
|
|
@@ -76,26 +121,69 @@ module Alchemy
|
|
|
76
121
|
end
|
|
77
122
|
end
|
|
78
123
|
|
|
79
|
-
# This helper renders
|
|
80
|
-
#
|
|
81
|
-
|
|
124
|
+
# This helper renders a {Alchemy::Element} partial.
|
|
125
|
+
#
|
|
126
|
+
# A element has always two partials:
|
|
127
|
+
#
|
|
128
|
+
# 1. A view partial (This is the view presented to the website visitor)
|
|
129
|
+
# 2. A editor partial (This is the form presented to the website editor while in page edit mode)
|
|
130
|
+
#
|
|
131
|
+
# The partials are located in <tt>app/views/alchemy/elements</tt>.
|
|
132
|
+
#
|
|
133
|
+
# == View partial naming
|
|
134
|
+
#
|
|
135
|
+
# The partials have to be named after the name of the element as defined in the <tt>elements.yml</tt> file and has to be suffixed with the partial part.
|
|
136
|
+
#
|
|
137
|
+
# === Example
|
|
138
|
+
#
|
|
139
|
+
# Given a headline element
|
|
140
|
+
#
|
|
141
|
+
# # elements.yml
|
|
142
|
+
# - name: headline
|
|
143
|
+
# contents:
|
|
144
|
+
# - name: text
|
|
145
|
+
# type: EssenceText
|
|
146
|
+
#
|
|
147
|
+
# Then your element view partials has to be named like:
|
|
148
|
+
#
|
|
149
|
+
# app/views/alchemy/elements/_headline_editor.html.erb
|
|
150
|
+
# app/views/alchemy/elements/_headline_view.html.erb
|
|
151
|
+
#
|
|
152
|
+
# === Element partials generator
|
|
153
|
+
#
|
|
154
|
+
# You can use this handy generator to let Alchemy generate the partials for you:
|
|
155
|
+
#
|
|
156
|
+
# $ rails generate alchemy:elements --skip
|
|
157
|
+
#
|
|
158
|
+
# == Usage
|
|
159
|
+
#
|
|
160
|
+
# <%= render_element(Alchemy::Element.published.named(:headline).first) %>
|
|
161
|
+
#
|
|
162
|
+
# @param [Alchemy::Element] element
|
|
163
|
+
# The element you want to render the view for
|
|
164
|
+
# @param [Symbol] part
|
|
165
|
+
# The type of element partial (<tt>:editor</tt> or <tt>:view</tt>) you want to render
|
|
166
|
+
# @param [Hash] options
|
|
167
|
+
# Additional options
|
|
168
|
+
# @param [Number] counter
|
|
169
|
+
# a counter
|
|
170
|
+
#
|
|
171
|
+
# @note If the view partial is not found <tt>alchemy/elements/_view_not_found.html.erb</tt> or <tt>alchemy/elements/_editor_not_found.html.erb</tt> gets rendered.
|
|
172
|
+
#
|
|
173
|
+
def render_element(element, part = :view, options = {}, counter = 1)
|
|
82
174
|
begin
|
|
83
175
|
if element.blank?
|
|
84
176
|
warning('Element is nil')
|
|
85
177
|
render :partial => "alchemy/elements/#{part}_not_found", :locals => {:name => 'nil'}
|
|
86
178
|
else
|
|
87
|
-
default_options = {
|
|
88
|
-
:shorten_to => nil
|
|
89
|
-
}
|
|
90
|
-
options = default_options.merge(options)
|
|
91
179
|
element.store_page(@page) if part == :view
|
|
92
180
|
locals = options.delete(:locals)
|
|
93
181
|
render(
|
|
94
182
|
:partial => "alchemy/elements/#{element.name.underscore}_#{part}",
|
|
95
183
|
:locals => {
|
|
96
184
|
:element => element,
|
|
97
|
-
:
|
|
98
|
-
:
|
|
185
|
+
:counter => counter,
|
|
186
|
+
:options => options
|
|
99
187
|
}.merge(locals || {})
|
|
100
188
|
)
|
|
101
189
|
end
|
|
@@ -189,7 +277,7 @@ module Alchemy
|
|
|
189
277
|
|
|
190
278
|
# Returns the element's tags information as an attribute hash.
|
|
191
279
|
#
|
|
192
|
-
# @param [Alchemy::Element] element The
|
|
280
|
+
# @param [Alchemy::Element] element The {Alchemy::Element} you want to render the tags from.
|
|
193
281
|
#
|
|
194
282
|
# @option options [Proc] :formatter
|
|
195
283
|
# ('lambda { |tags| tags.join(' ') }')
|