locomotive_cms 2.0.0.rc9 → 2.0.0.rc10
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/Gemfile +6 -5
- data/app/assets/javascripts/locomotive/inline_editor.js.coffee +1 -1
- data/app/assets/javascripts/locomotive/models/custom_field_select_option.js.coffee +3 -0
- data/app/assets/javascripts/locomotive/models/site.js.coffee +2 -1
- data/app/assets/javascripts/locomotive/views/content_entries/_form_view.js.coffee +27 -0
- data/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee +7 -1
- data/app/assets/javascripts/locomotive/views/content_types/_form_view.js.coffee +4 -1
- data/app/assets/javascripts/locomotive/views/content_types/select_options_view.js.coffee +5 -1
- data/app/assets/javascripts/locomotive/views/inline_editor/toolbar_view.js.coffee +0 -2
- data/app/assets/javascripts/locomotive/views/pages/edit_view.js.coffee +3 -0
- data/app/assets/javascripts/locomotive/views/shared/fields/select_view.js.coffee +83 -0
- data/app/assets/stylesheets/locomotive/backoffice/application.css.scss +13 -0
- data/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.scss +25 -95
- data/app/assets/stylesheets/locomotive/inline_editor/toolbar.css.scss +1 -1
- data/app/assets/stylesheets/locomotive/shared/_helpers.css.scss +98 -0
- data/app/assets/stylesheets/locomotive/shared/common.css.scss +1 -1
- data/app/controllers/locomotive/current_site_controller.rb +6 -0
- data/app/helpers/locomotive/base_helper.rb +14 -0
- data/app/models/locomotive/content_entry.rb +42 -3
- data/app/models/locomotive/content_type.rb +6 -1
- data/app/models/locomotive/editable_element.rb +9 -0
- data/app/models/locomotive/editable_short_text.rb +9 -0
- data/app/models/locomotive/extensions/page/tree.rb +3 -4
- data/app/presenters/locomotive/content_entry_presenter.rb +4 -2
- data/app/views/locomotive/content_entries/_form.html.haml +2 -1
- data/app/views/locomotive/custom_fields/_form.html.haml +4 -18
- data/app/views/locomotive/custom_fields/_select_templates.html.haml +16 -0
- data/app/views/locomotive/custom_fields/types/_has_many.html.haml +3 -3
- data/app/views/locomotive/custom_fields/types/_select.html.haml +30 -1
- data/app/views/locomotive/notifications/new_content_entry.html.haml +3 -1
- data/app/views/locomotive/public/pages/show_toolbar.html.haml +4 -1
- data/config/locales/admin_ui.de.yml +3 -4
- data/config/locales/admin_ui.en.yml +1 -1
- data/config/locales/admin_ui.fr.yml +4 -4
- data/config/locales/admin_ui.nb.yml +0 -1
- data/config/locales/admin_ui.ru.yml +0 -1
- data/lib/locomotive/custom_fields.rb +12 -0
- data/lib/locomotive/liquid/drops/content_entry.rb +2 -2
- data/lib/locomotive/liquid/drops/content_types.rb +2 -0
- data/lib/locomotive/liquid/tags/editable/short_text.rb +4 -0
- data/lib/locomotive/liquid/tags/inline_editor.rb +14 -12
- data/lib/locomotive/middlewares/inline_editor.rb +20 -15
- data/lib/locomotive/render.rb +94 -40
- data/lib/locomotive/version.rb +1 -1
- data/vendor/assets/javascripts/locomotive/form_submit_notification.js +1 -1
- data/vendor/assets/javascripts/locomotive/toggle.js +9 -8
- data/vendor/assets/stylesheets/locomotive/liquid_mode.css +3 -5
- data/vendor/assets/stylesheets/locomotive/toggle.css.scss +33 -10
- metadata +13 -12
- data/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.css +0 -0
@@ -20,7 +20,9 @@
|
|
20
20
|
- when 'string', 'text', 'boolean', 'date'
|
21
21
|
= value
|
22
22
|
- when 'file'
|
23
|
-
|
23
|
+
- url = value.guess_url
|
24
|
+
- url = url =~ /^http/ ? url : URI.join("http://#{@entry.site.domains.first}", url).to_s # Amazon S3 (http/https) or local files ?
|
25
|
+
= link_to File.basename(url), url
|
24
26
|
- when 'select'
|
25
27
|
= value
|
26
28
|
- when 'belongs_to'
|
@@ -11,6 +11,10 @@
|
|
11
11
|
%meta{ :name => 'key-param', :content => Rails.application.config.session_options[:key] }
|
12
12
|
%meta{ :name => 'key-token', :content => cookies[key] }
|
13
13
|
|
14
|
+
%script{ :type => 'text/javascript' }
|
15
|
+
:plain
|
16
|
+
window.Locomotive = { mounted_on: '#{Locomotive.mounted_on}' };
|
17
|
+
|
14
18
|
= stylesheet_link_tag 'locomotive/inline_editor', :media => 'screen'
|
15
19
|
= javascript_include_tag 'locomotive/inline_editor'
|
16
20
|
|
@@ -19,7 +23,6 @@
|
|
19
23
|
window.locale = '#{I18n.locale}';
|
20
24
|
window.content_locale = '#{::Mongoid::Fields::I18n.locale}';
|
21
25
|
|
22
|
-
Locomotive.mounted_on = '#{Locomotive.mounted_on}';
|
23
26
|
Locomotive.current_site = new Locomotive.Models.Site(#{j current_site.to_json.html_safe});
|
24
27
|
Locomotive.current_account = new Locomotive.Models.Account(#{j current_locomotive_account.to_json.html_safe});
|
25
28
|
|
@@ -9,7 +9,7 @@ de:
|
|
9
9
|
title: Seite nicht gefunden
|
10
10
|
notice: "Die angefragte Seite existiert nicht."
|
11
11
|
link: "→ Zurück zur Anwendung"
|
12
|
-
|
12
|
+
|
13
13
|
locales:
|
14
14
|
en: Englisch
|
15
15
|
de: Deutsch
|
@@ -20,7 +20,7 @@ de:
|
|
20
20
|
nb: Norwegisch
|
21
21
|
es: Spanisch
|
22
22
|
ru: Russisch
|
23
|
-
|
23
|
+
|
24
24
|
buttons:
|
25
25
|
login: Einloggen
|
26
26
|
send_password: Senden
|
@@ -91,7 +91,6 @@ de:
|
|
91
91
|
|
92
92
|
form:
|
93
93
|
required: Pflichtfeld
|
94
|
-
optional: Optional
|
95
94
|
default_label: Feldname
|
96
95
|
select_options:
|
97
96
|
ask_name: "Geben Sie den Namen der Auswahloption an."
|
@@ -295,7 +294,7 @@ de:
|
|
295
294
|
explanations: "Es ist fast geschafft. Bitte geben Sie Ihrer ersten Webseite einen Namen und wählen Sie eine Sprache aus."
|
296
295
|
default_site_locale: Sprachauswahl
|
297
296
|
default_site_locales_hints: Sie können später weitere Sprachen im Einstellungsdialog vornehmen.
|
298
|
-
next: Webseite erstellen
|
297
|
+
next: Webseite erstellen
|
299
298
|
back_to_default_template: "Klicken Sie <a href='#'>hier</a> um die Standardeinstellungen wieder herzustellen"
|
300
299
|
|
301
300
|
|
@@ -91,7 +91,6 @@ en:
|
|
91
91
|
|
92
92
|
form:
|
93
93
|
required: Required
|
94
|
-
optional: Optional
|
95
94
|
default_label: Field name
|
96
95
|
select_options:
|
97
96
|
ask_name: "Type the label of the option"
|
@@ -267,6 +266,7 @@ en:
|
|
267
266
|
edit:
|
268
267
|
title: '%{type} — editing entry'
|
269
268
|
form:
|
269
|
+
edit_select_options: edit options
|
270
270
|
has_many:
|
271
271
|
new_entry: New entry
|
272
272
|
|
@@ -85,11 +85,10 @@ fr:
|
|
85
85
|
empty: La liste est vide. Ajouter une entrée depuis la liste ci-dessous.
|
86
86
|
|
87
87
|
form:
|
88
|
-
required:
|
89
|
-
|
90
|
-
default_label: Field name
|
88
|
+
required: Requis
|
89
|
+
default_label: Nom du champ
|
91
90
|
select_options:
|
92
|
-
ask_name: "
|
91
|
+
ask_name: "Tapez le nom de l'option"
|
93
92
|
|
94
93
|
sessions:
|
95
94
|
new:
|
@@ -263,6 +262,7 @@ fr:
|
|
263
262
|
edit:
|
264
263
|
title: '%{type} — édition élément'
|
265
264
|
form:
|
265
|
+
edit_select_options: éditer options
|
266
266
|
has_many:
|
267
267
|
new_item: Nouvel élément
|
268
268
|
|
@@ -30,6 +30,18 @@ module CustomFields
|
|
30
30
|
"sites/#{model.site_id}/content_#{model.class.model_name.demodulize.underscore}/#{model.id}/files"
|
31
31
|
end
|
32
32
|
|
33
|
+
# In some situations, for instance, for the notification email when a content entry is created,
|
34
|
+
# we need to know the url of the file without breaking the upload process.
|
35
|
+
# Actually, the uploaded file will be written on the filesystem after the email is sent.
|
36
|
+
#
|
37
|
+
# @return [ String ] The url to the soon uploaded file
|
38
|
+
#
|
39
|
+
def guess_url
|
40
|
+
this = self.class.new(model, mounted_as)
|
41
|
+
this.retrieve_from_store!(model.read_uploader(mounted_as))
|
42
|
+
this.url.to_s
|
43
|
+
end
|
44
|
+
|
33
45
|
def cache_dir
|
34
46
|
"#{Rails.root}/tmp/uploads"
|
35
47
|
end
|
@@ -23,7 +23,7 @@ module Locomotive
|
|
23
23
|
# {% endif %}
|
24
24
|
#
|
25
25
|
def next
|
26
|
-
self._source.next.to_liquid
|
26
|
+
@next ||= self._source.next.to_liquid
|
27
27
|
end
|
28
28
|
|
29
29
|
# Returns the previous content for the parent content type.
|
@@ -36,7 +36,7 @@ module Locomotive
|
|
36
36
|
# {% endif %}
|
37
37
|
#
|
38
38
|
def previous
|
39
|
-
self._source.previous.to_liquid
|
39
|
+
@previous ||= self._source.previous.to_liquid
|
40
40
|
end
|
41
41
|
|
42
42
|
def before_method(meth)
|
@@ -31,6 +31,8 @@ module Locomotive
|
|
31
31
|
|
32
32
|
if (meth.to_s =~ /^group_by_(.+)$/) == 0
|
33
33
|
klass.send(:group_by_select_option, $1, @content_type.order_by_definition)
|
34
|
+
elsif (meth.to_s =~ /^(.+)_options$/) == 0
|
35
|
+
klass.send(:"#{$1}_options").map { |option| option['name'] }
|
34
36
|
else
|
35
37
|
Locomotive.log :warn, "[Liquid template] trying to call #{meth} on a content_type object"
|
36
38
|
end
|
@@ -28,6 +28,10 @@ module Locomotive
|
|
28
28
|
context.registers[:inline_editor] && (!element.fixed? || (element.fixed? && !element.from_parent?))
|
29
29
|
end
|
30
30
|
|
31
|
+
def default_element_attributes
|
32
|
+
super.merge(:content_from_default => self.render_default_content(nil))
|
33
|
+
end
|
34
|
+
|
31
35
|
end
|
32
36
|
|
33
37
|
::Liquid::Template.register_tag('editable_short_text', ShortText)
|
@@ -6,23 +6,25 @@ module Liquid
|
|
6
6
|
def render(context)
|
7
7
|
if context.registers[:current_locomotive_account] && context.registers[:inline_editor]
|
8
8
|
|
9
|
-
controller = context.registers[:controller]
|
10
|
-
|
11
9
|
plugins = 'common/format,common/table,common/list,common/link,common/highlighteditables,common/block,common/undo,common/contenthandler,common/paste,common/commands,common/abbr,common/align,common/horizontalruler,custom/locomotive_media'
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
controller = context.registers[:controller]
|
12
|
+
controller.instance_variable_set(:@plugins, plugins)
|
13
|
+
|
14
|
+
html = <<-HTML
|
15
|
+
%meta{ :content => true, :name => 'inline-editor' }
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
= stylesheet_link_tag 'aloha/css/aloha.css'
|
18
|
+
= javascript_include_tag 'locomotive/aloha', :'data-aloha-plugins' => @plugins
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
%script{ :type => 'text/javascript' }
|
21
|
+
:plain
|
22
|
+
Aloha.ready(function() \{
|
23
|
+
window.parent.application_view.set_page(#{controller.view_context.j context.registers[:page].to_presenter.as_json_for_html_view.to_json.html_safe});
|
24
|
+
\});
|
25
|
+
HTML
|
24
26
|
|
25
|
-
}
|
27
|
+
Haml::Engine.new(html.gsub(/\n+/, "\n").gsub(/^\s{14}/, ''), :escape_html => true).render(controller.view_context)
|
26
28
|
else
|
27
29
|
''
|
28
30
|
end
|
@@ -7,22 +7,27 @@ module Locomotive
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def call(env)
|
10
|
-
response = @app.call(env)
|
10
|
+
status, headers, response = @app.call(env)
|
11
11
|
|
12
|
-
unless
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
12
|
+
response = modify(response) unless headers['Editable'].blank?
|
13
|
+
|
14
|
+
[status, headers, response]
|
15
|
+
end
|
16
|
+
|
17
|
+
def modify(response)
|
18
|
+
[].tap do |parts|
|
19
|
+
response.each do |part|
|
20
|
+
parts << part.to_s.gsub('</body>', %(
|
21
|
+
<a href="_admin"
|
22
|
+
onmouseout="this.style.backgroundPosition='0px 0px'"
|
23
|
+
onmouseover="this.style.backgroundPosition='0px -45px'"
|
24
|
+
onmousedown="this.style.backgroundPosition='0px -90px'"
|
25
|
+
onmouseup="this.style.backgroundPosition='0px 0px'"
|
26
|
+
style="display: block;z-index: 1031;position: fixed;top: 10px; right: 10px;width: 48px; height: 45px;text-indent:-9999px;text-decoration:none;background: transparent url\('/assets/locomotive/icons/start.png'\) no-repeat 0 0;">
|
27
|
+
Admin</a>
|
28
|
+
</body>
|
29
|
+
))
|
30
|
+
end
|
26
31
|
end
|
27
32
|
end
|
28
33
|
|
data/lib/locomotive/render.rb
CHANGED
@@ -5,6 +5,9 @@ module Locomotive
|
|
5
5
|
|
6
6
|
protected
|
7
7
|
|
8
|
+
# Render a Locomotive page from the request fullpath and the current site.
|
9
|
+
# If the page corresponds to a redirect, then a 301 redirection is made.
|
10
|
+
#
|
8
11
|
def render_locomotive_page
|
9
12
|
if request.fullpath =~ /^\/#{Locomotive.mounted_on}\//
|
10
13
|
render :template => '/locomotive/errors/404', :layout => '/locomotive/layouts/not_logged_in', :status => :not_found
|
@@ -21,14 +24,69 @@ module Locomotive
|
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
27
|
+
# Render the page which tells that no page exists.
|
28
|
+
# This case should not happen since all the sites contains
|
29
|
+
# the "Page Not Found" page.
|
30
|
+
#
|
24
31
|
def render_no_page_error
|
25
32
|
render :template => '/locomotive/errors/no_page', :layout => false
|
26
33
|
end
|
27
34
|
|
35
|
+
# Prepare and set the response object for the Locomotive page retrieved
|
36
|
+
# from the path. The caching (with Varnish for instance) if defined is done here.
|
37
|
+
# It is also here that the content type of the request is set (html or json).
|
38
|
+
# Behind the scene, it just calls simply the Rails render method.
|
39
|
+
#
|
40
|
+
# @param [ String ] The rendered Locomotive page
|
41
|
+
#
|
42
|
+
def prepare_and_set_response(output)
|
43
|
+
flash.discard
|
44
|
+
|
45
|
+
response.headers['Content-Type'] = "#{@page.response_type}; charset=utf-8"
|
46
|
+
response.headers['Editable'] = 'true' unless self.editing_page? || current_locomotive_account.nil?
|
47
|
+
|
48
|
+
if @page.with_cache?
|
49
|
+
fresh_when :etag => @page, :last_modified => @page.updated_at.utc, :public => true
|
50
|
+
|
51
|
+
if @page.cache_strategy != 'simple' # varnish
|
52
|
+
response.headers['Editable'] = ''
|
53
|
+
response.cache_control[:max_age] = @page.cache_strategy
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
render :text => output, :layout => false, :status => page_status unless performed?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Tell if the current Locomotive page is being edited.
|
61
|
+
#
|
62
|
+
# @return [ Boolean ] True if being edited.
|
63
|
+
#
|
64
|
+
def editing_page?
|
65
|
+
!!@editing
|
66
|
+
end
|
67
|
+
|
68
|
+
# Get the symbol matching the status of the current Locomotive page.
|
69
|
+
# It can be either :ok or :not_found (404)
|
70
|
+
#
|
71
|
+
# @return [ Symbol ] :ok if the page is not the "Page not found" one.
|
72
|
+
#
|
73
|
+
def page_status
|
74
|
+
@page.not_found? ? :not_found : :ok
|
75
|
+
end
|
76
|
+
|
77
|
+
# Get the Locomotive page matching the request and scoped by the current Locomotive site
|
78
|
+
#
|
79
|
+
# @return [ Object ] The Locomotive::Page
|
80
|
+
#
|
28
81
|
def locomotive_page
|
29
82
|
current_site.fetch_page self.locomotive_page_path, current_locomotive_account.present?
|
30
83
|
end
|
31
84
|
|
85
|
+
# Build the path that can be understood by Locomotive in order to retrieve
|
86
|
+
# the matching Locomotive page (see the locomotive_page method)
|
87
|
+
#
|
88
|
+
# @return [ String ] The path to the Locomotive page
|
89
|
+
#
|
32
90
|
def locomotive_page_path
|
33
91
|
path = (params[:path] || params[:page_path] || request.fullpath).clone # TODO: params[:path] is more consistent
|
34
92
|
path = path.split('?').first # take everything before the query string or the lookup fails
|
@@ -40,9 +98,36 @@ module Locomotive
|
|
40
98
|
path
|
41
99
|
end
|
42
100
|
|
101
|
+
# Build the Liquid context used to render the Locomotive page. It
|
102
|
+
# stores both assigns and registers.
|
103
|
+
#
|
104
|
+
# @return [ Object ] A Liquid::Context object.
|
105
|
+
#
|
43
106
|
def locomotive_context
|
44
|
-
assigns =
|
45
|
-
|
107
|
+
assigns = self.locomotive_default_assigns
|
108
|
+
|
109
|
+
assigns.merge!(Locomotive.config.context_assign_extensions)
|
110
|
+
|
111
|
+
assigns.merge!(flash.to_hash.stringify_keys) # data from public submissions
|
112
|
+
|
113
|
+
if @page.templatized? # add instance from content type
|
114
|
+
content_entry = @page.content_entry.to_liquid
|
115
|
+
['content_entry', 'entry', @page.target_entry_name].each do |key|
|
116
|
+
assigns[key] = content_entry
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Tip: switch from false to true to enable the re-thrown exception flag
|
121
|
+
::Liquid::Context.new({}, assigns, self.locomotive_default_registers, false)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Return the default Liquid assigns used inside the Locomotive Liquid context
|
125
|
+
#
|
126
|
+
# @return [ Hash ] The default liquid assigns object
|
127
|
+
#
|
128
|
+
def locomotive_default_assigns
|
129
|
+
{
|
130
|
+
'site' => current_site.to_liquid,
|
46
131
|
'page' => @page,
|
47
132
|
'models' => Locomotive::Liquid::Drops::ContentTypes.new,
|
48
133
|
'contents' => Locomotive::Liquid::Drops::ContentTypes.new, # DEPRECATED
|
@@ -58,51 +143,20 @@ module Locomotive
|
|
58
143
|
'locales' => current_site.locales,
|
59
144
|
'current_user' => Locomotive::Liquid::Drops::CurrentUser.new(current_locomotive_account)
|
60
145
|
}
|
146
|
+
end
|
61
147
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
assigns[@page.target_entry_name] = @page.content_entry # just here to help to write readable liquid code
|
69
|
-
end
|
70
|
-
|
71
|
-
registers = {
|
148
|
+
# Return the default Liquid registers used inside the Locomotive Liquid context
|
149
|
+
#
|
150
|
+
# @return [ Hash ] The default liquid registers object
|
151
|
+
#
|
152
|
+
def locomotive_default_registers
|
153
|
+
{
|
72
154
|
:controller => self,
|
73
155
|
:site => current_site,
|
74
156
|
:page => @page,
|
75
157
|
:inline_editor => self.editing_page?,
|
76
158
|
:current_locomotive_account => current_locomotive_account
|
77
159
|
}
|
78
|
-
|
79
|
-
::Liquid::Context.new({}, assigns, registers, false) # switch from false to true to enable the re-thrown exception flag
|
80
|
-
end
|
81
|
-
|
82
|
-
def prepare_and_set_response(output)
|
83
|
-
flash.discard
|
84
|
-
|
85
|
-
response.headers['Content-Type'] = "#{@page.response_type}; charset=utf-8"
|
86
|
-
response.headers['Editable'] = 'true' unless self.editing_page? || current_locomotive_account.nil?
|
87
|
-
|
88
|
-
if @page.with_cache?
|
89
|
-
fresh_when :etag => @page, :last_modified => @page.updated_at.utc, :public => true
|
90
|
-
|
91
|
-
if @page.cache_strategy != 'simple' # varnish
|
92
|
-
response.headers['Editable'] = ''
|
93
|
-
response.cache_control[:max_age] = @page.cache_strategy
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
render :text => output, :layout => false, :status => page_status unless performed?
|
98
|
-
end
|
99
|
-
|
100
|
-
def editing_page?
|
101
|
-
!!@editing
|
102
|
-
end
|
103
|
-
|
104
|
-
def page_status
|
105
|
-
@page.not_found? ? :not_found : :ok
|
106
160
|
end
|
107
161
|
|
108
162
|
end
|
data/lib/locomotive/version.rb
CHANGED
@@ -22,7 +22,7 @@ $.fn.formSubmitNotification = function(settings) {
|
|
22
22
|
|
23
23
|
return this.each(function() {
|
24
24
|
var form = $(this);
|
25
|
-
var message = form.attr('data-sending-form-message');
|
25
|
+
var message = form.attr('data-sending-form-message') || form.attr('data-sending_form_message');
|
26
26
|
|
27
27
|
if (typeof(message) == 'undefined')
|
28
28
|
message = form.find('input[type=submit]').attr('data-sending-form-message');
|