locomotive_cms 2.0.0.rc9 → 2.0.0.rc10
Sign up to get free protection for your applications and to get access to all the features.
- 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');
|