Compare commits

..

10 Commits

Author SHA1 Message Date
Mario Visic
177f1e6c82 Merge pull request #416 from miskander/wildcards
Merged master into wildcards
2012-05-24 03:45:35 -07:00
Marko Iskander
02ea6913e3 Merge branch 'master' into wildcards
Conflicts:
	Gemfile.lock
	app/assets/javascripts/locomotive/models/page.js.coffee
	app/assets/javascripts/locomotive/views/pages/_form_view.js.coffee
	app/models/locomotive/extensions/site/locales.rb
	app/models/locomotive/page.rb
	app/views/locomotive/pages/_form.html.haml
	config/initializers/haml.rb
	config/locales/default.ru.yml
	config/locales/formtastic.ru.yml
	doc/TODO
	lib/locomotive/haml.rb
	script/upgrade_v1.rb
	spec/dummy/config/initializers/haml.rb
2012-05-22 20:39:30 -04:00
Didier Lafforgue
62e2a5029d use the last version of FOG 2012-04-11 03:40:00 +02:00
Didier Lafforgue
63fd77f950 handle is unique within the scope of a site 2012-04-11 00:21:20 +02:00
Didier Lafforgue
14596a5443 fix a couple of annoying engine bugs + implement the first version of the find tag 2012-04-10 17:44:13 +02:00
did
4d1b986f1b fix broken tests + make the editing of locales more robust 2012-04-10 04:55:59 -07:00
Didier Lafforgue
e26febdaf6 refactoring (wip) 2012-04-06 12:23:11 +02:00
Didier Lafforgue
260f9ae4ef one way to avoid autosave 2012-04-05 18:02:16 +02:00
Didier Lafforgue
64ea41cbcd one way to avoid autosave 2012-04-05 18:01:16 +02:00
Didier Lafforgue
64168cad37 wip 2012-04-05 17:12:26 +02:00
168 changed files with 1305 additions and 3348 deletions

2
1 Normal file
View File

@ -0,0 +1,2 @@
Haml::Template.options[:format] = :html5
Haml::Template.options[:ugly] = true # improve performance in dev

11
Gemfile
View File

@ -8,6 +8,7 @@ gemspec # Include gemspec dependencies
# The rest of the dependencies are for use when in the locomotive development environment # The rest of the dependencies are for use when in the locomotive development environment
group :development do group :development do
# gem 'locomotive-mongoid-tree', :path => '../gems/custom_fields' # for Developers
# gem 'custom_fields', :path => '../gems/custom_fields' # for Developers # gem 'custom_fields', :path => '../gems/custom_fields' # for Developers
# gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git', :branch => '2.0.0.rc' # Branch on Github # gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git', :branch => '2.0.0.rc' # Branch on Github
@ -22,8 +23,9 @@ end
group :assets do group :assets do
gem 'sass-rails', '~> 3.2.4' gem 'sass-rails', '~> 3.2.4'
gem 'coffee-rails', '~> 3.2.2' gem 'coffee-rails', '~> 3.2.2'
gem 'uglifier', '~> 1.2.4' gem 'uglifier', '~> 1.2.3'
gem 'compass-rails' gem 'compass', :git => 'git://github.com/chriseppstein/compass.git', :branch => 'no_rails_integration'
gem 'compass-rails', :git => 'git://github.com/Compass/compass-rails.git'
end end
group :test do group :test do
@ -35,7 +37,6 @@ group :test do
# gem 'growl-glue' # gem 'growl-glue'
gem 'cucumber-rails', :require => false gem 'cucumber-rails', :require => false
gem 'poltergeist'
gem 'rspec-rails', '~> 2.8.0' gem 'rspec-rails', '~> 2.8.0'
gem 'shoulda-matchers' gem 'shoulda-matchers'
@ -50,6 +51,4 @@ group :test do
gem 'json_spec' gem 'json_spec'
gem 'database_cleaner' gem 'database_cleaner'
end
# gem 'debugger', :git => 'git://github.com/cldwalker/debugger.git'
end

View File

@ -1,25 +1,42 @@
GIT
remote: git://github.com/Compass/compass-rails.git
revision: 47d889ad8dabdab1e9f44da4447f94846c089c50
specs:
compass-rails (1.0.0.rc.3)
compass (~> 0.12.rc.0)
GIT
remote: git://github.com/chriseppstein/compass.git
revision: 0f96e881019c364aa6124845cbd83b1fd75c4ffe
branch: no_rails_integration
specs:
compass (0.12.rc.4.0f96e88)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
sass (~> 3.1)
PATH PATH
remote: . remote: .
specs: specs:
locomotive_cms (2.0.0.rc8) locomotive_cms (2.0.0.rc7)
RedCloth (~> 4.2.8) RedCloth (~> 4.2.8)
actionmailer-with-request (~> 0.3.0) actionmailer-with-request (~> 0.3.0)
bson_ext (~> 1.5.2) bson_ext (~> 1.5.2)
cancan (~> 1.6.7) cancan (~> 1.6.7)
carrierwave-mongoid (~> 0.2.1) carrierwave (~> 0.6.0)
carrierwave-mongoid (~> 0.1.3)
cells (~> 3.8.0) cells (~> 3.8.0)
codemirror-rails (~> 2.21) codemirror-rails (~> 2.21)
custom_fields (~> 2.0.0.rc12) custom_fields (~> 2.0.0.rc10)
devise (~> 2.1.0) devise (~> 1.5.3)
devise-encryptable (~> 0.1.1)
dragonfly (~> 0.9.8) dragonfly (~> 0.9.8)
flash_cookie_session (~> 1.1.1) flash_cookie_session (~> 1.1.1)
fog (~> 1.3.1) fog (~> 1.3.1)
formtastic (~> 2.0.2) formtastic (~> 2.0.2)
haml (~> 3.1.6) haml (~> 3.1.4)
highline (~> 1.6.2) highline (~> 1.6.2)
httparty (~> 0.8.1) httparty (~> 0.8.1)
jquery-rails (~> 1.0.19) jquery-rails (~> 1.0.16)
kaminari (~> 0.13.0) kaminari (~> 0.13.0)
locomotive-aloha-rails (~> 0.20.1.4) locomotive-aloha-rails (~> 0.20.1.4)
locomotive-mongoid-tree (~> 0.6.2) locomotive-mongoid-tree (~> 0.6.2)
@ -30,7 +47,7 @@ PATH
mongoid (~> 2.4.9) mongoid (~> 2.4.9)
multi_json (~> 1.3.4) multi_json (~> 1.3.4)
rack-cache (~> 1.1) rack-cache (~> 1.1)
rails (~> 3.2.5) rails (~> 3.2.3)
rails-backbone (~> 0.6.1) rails-backbone (~> 0.6.1)
rake (~> 0.9.2) rake (~> 0.9.2)
responders (~> 0.6.4) responders (~> 0.6.4)
@ -42,33 +59,33 @@ GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
RedCloth (4.2.9) RedCloth (4.2.9)
actionmailer (3.2.5) actionmailer (3.2.3)
actionpack (= 3.2.5) actionpack (= 3.2.3)
mail (~> 2.4.4) mail (~> 2.4.4)
actionmailer-with-request (0.3.0) actionmailer-with-request (0.3.0)
rails (>= 3) rails (>= 3)
actionpack (3.2.5) actionpack (3.2.3)
activemodel (= 3.2.5) activemodel (= 3.2.3)
activesupport (= 3.2.5) activesupport (= 3.2.3)
builder (~> 3.0.0) builder (~> 3.0.0)
erubis (~> 2.7.0) erubis (~> 2.7.0)
journey (~> 1.0.1) journey (~> 1.0.1)
rack (~> 1.4.0) rack (~> 1.4.0)
rack-cache (~> 1.2) rack-cache (~> 1.2)
rack-test (~> 0.6.1) rack-test (~> 0.6.1)
sprockets (~> 2.1.3) sprockets (~> 2.1.2)
activemodel (3.2.5) activemodel (3.2.3)
activesupport (= 3.2.5) activesupport (= 3.2.3)
builder (~> 3.0.0) builder (~> 3.0.0)
activerecord (3.2.5) activerecord (3.2.3)
activemodel (= 3.2.5) activemodel (= 3.2.3)
activesupport (= 3.2.5) activesupport (= 3.2.3)
arel (~> 3.0.2) arel (~> 3.0.2)
tzinfo (~> 0.3.29) tzinfo (~> 0.3.29)
activeresource (3.2.5) activeresource (3.2.3)
activemodel (= 3.2.5) activemodel (= 3.2.3)
activesupport (= 3.2.5) activesupport (= 3.2.3)
activesupport (3.2.5) activesupport (3.2.3)
i18n (~> 0.6) i18n (~> 0.6)
multi_json (~> 1.0) multi_json (~> 1.0)
addressable (2.2.8) addressable (2.2.8)
@ -89,10 +106,10 @@ GEM
carrierwave (0.6.2) carrierwave (0.6.2)
activemodel (>= 3.2.0) activemodel (>= 3.2.0)
activesupport (>= 3.2.0) activesupport (>= 3.2.0)
carrierwave-mongoid (0.2.1) carrierwave-mongoid (0.1.3)
carrierwave (~> 0.6.1) carrierwave (>= 0.5.6)
mongoid (~> 2.1) mongoid (~> 2.1)
cells (3.8.5) cells (3.8.3)
actionpack (~> 3.0) actionpack (~> 3.0)
railties (~> 3.0) railties (~> 3.0)
childprocess (0.3.2) childprocess (0.3.2)
@ -106,50 +123,39 @@ GEM
coffee-script (2.2.0) coffee-script (2.2.0)
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.3.3) coffee-script-source (1.3.1)
compass (0.12.1) cucumber (1.1.9)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
sass (~> 3.1)
compass-rails (1.0.2)
compass (>= 0.12.0, < 0.14)
cucumber (1.2.1)
builder (>= 2.1.2) builder (>= 2.1.2)
diff-lcs (>= 1.1.3) diff-lcs (>= 1.1.2)
gherkin (~> 2.11.0) gherkin (~> 2.9.0)
json (>= 1.4.6) json (>= 1.4.6)
term-ansicolor (>= 1.0.6)
cucumber-rails (1.3.0) cucumber-rails (1.3.0)
capybara (>= 1.1.2) capybara (>= 1.1.2)
cucumber (>= 1.1.8) cucumber (>= 1.1.8)
nokogiri (>= 1.5.0) nokogiri (>= 1.5.0)
custom_fields (2.0.0.rc12) custom_fields (2.0.0.rc10)
activesupport (~> 3.2.1) activesupport (~> 3.2.1)
carrierwave-mongoid (~> 0.2.1) carrierwave-mongoid (~> 0.1.3)
mongoid (~> 2.4.9) mongoid (~> 2.4.7)
database_cleaner (0.8.0) database_cleaner (0.7.2)
devise (2.1.0) devise (1.5.3)
bcrypt-ruby (~> 3.0) bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.7) orm_adapter (~> 0.0.3)
railties (~> 3.1) warden (~> 1.1)
warden (~> 1.1.1)
devise-encryptable (0.1.1)
devise (>= 2.1.0.rc)
diff-lcs (1.1.3) diff-lcs (1.1.3)
dragonfly (0.9.12) dragonfly (0.9.12)
rack rack
ejs (1.0.0) ejs (1.0.0)
erubis (2.7.0) erubis (2.7.0)
eventmachine (0.12.10)
excon (0.13.4) excon (0.13.4)
execjs (1.4.0) execjs (1.3.1)
multi_json (~> 1.0) multi_json (~> 1.0)
factory_girl (2.5.2) factory_girl (2.5.2)
activesupport (>= 2.3.9) activesupport (>= 2.3.9)
factory_girl_rails (1.6.0) factory_girl_rails (1.6.0)
factory_girl (~> 2.5.0) factory_girl (~> 2.5.0)
railties (>= 3.0.0) railties (>= 3.0.0)
faye-websocket (0.4.5)
eventmachine (>= 0.12.0)
ffi (1.0.11) ffi (1.0.11)
flash_cookie_session (1.1.3) flash_cookie_session (1.1.3)
rails (~> 3.0) rails (~> 3.0)
@ -163,16 +169,15 @@ GEM
net-ssh (>= 2.1.3) net-ssh (>= 2.1.3)
nokogiri (~> 1.5.0) nokogiri (~> 1.5.0)
ruby-hmac ruby-hmac
formatador (0.2.3) formatador (0.2.1)
formtastic (2.0.2) formtastic (2.0.2)
rails (~> 3.0) rails (~> 3.0)
fssm (0.2.9) fssm (0.2.9)
gherkin (2.11.0) gherkin (2.9.3)
json (>= 1.4.6) json (>= 1.4.6)
haml (3.1.6) haml (3.1.4)
highline (1.6.12) highline (1.6.11)
hike (1.2.1) hike (1.2.1)
http_parser.rb (0.5.3)
httparty (0.8.3) httparty (0.8.3)
multi_json (~> 1.0) multi_json (~> 1.0)
multi_xml multi_xml
@ -181,7 +186,7 @@ GEM
jquery-rails (1.0.19) jquery-rails (1.0.19)
railties (~> 3.0) railties (~> 3.0)
thor (~> 0.14) thor (~> 0.14)
json (1.7.3) json (1.7.0)
json_spec (1.0.3) json_spec (1.0.3)
multi_json (~> 1.0) multi_json (~> 1.0)
rspec (~> 2.0) rspec (~> 2.0)
@ -210,26 +215,20 @@ GEM
mocha (0.9.12) mocha (0.9.12)
mongo (1.5.2) mongo (1.5.2)
bson (= 1.5.2) bson (= 1.5.2)
mongoid (2.4.11) mongoid (2.4.9)
activemodel (~> 3.1) activemodel (~> 3.1)
mongo (<= 1.6.2) mongo (~> 1.3)
tzinfo (~> 0.3.22) tzinfo (~> 0.3.22)
multi_json (1.3.6) multi_json (1.3.4)
multi_xml (0.5.1) multi_xml (0.4.4)
net-scp (1.0.4) net-scp (1.0.4)
net-ssh (>= 1.99.1) net-ssh (>= 1.99.1)
net-ssh (2.5.2) net-ssh (2.3.0)
nokogiri (1.5.3) nokogiri (1.5.2)
orm_adapter (0.0.7) orm_adapter (0.0.7)
pickle (0.4.10) pickle (0.4.10)
cucumber (>= 0.8) cucumber (>= 0.8)
rake rake
poltergeist (0.6.0)
capybara (~> 1.0)
childprocess (~> 0.3)
faye-websocket (~> 0.4, >= 0.4.4)
http_parser.rb (~> 0.5.3)
multi_json (~> 1.0)
polyglot (0.3.3) polyglot (0.3.3)
rack (1.4.1) rack (1.4.1)
rack-cache (1.2) rack-cache (1.2)
@ -238,26 +237,26 @@ GEM
rack rack
rack-test (0.6.1) rack-test (0.6.1)
rack (>= 1.0) rack (>= 1.0)
rails (3.2.5) rails (3.2.3)
actionmailer (= 3.2.5) actionmailer (= 3.2.3)
actionpack (= 3.2.5) actionpack (= 3.2.3)
activerecord (= 3.2.5) activerecord (= 3.2.3)
activeresource (= 3.2.5) activeresource (= 3.2.3)
activesupport (= 3.2.5) activesupport (= 3.2.3)
bundler (~> 1.0) bundler (~> 1.0)
railties (= 3.2.5) railties (= 3.2.3)
rails-backbone (0.6.1) rails-backbone (0.6.1)
coffee-script (~> 2.2.0) coffee-script (~> 2.2.0)
ejs (~> 1.0.0) ejs (~> 1.0.0)
railties (>= 3.1.0) railties (>= 3.1.0)
railties (3.2.5) railties (3.2.3)
actionpack (= 3.2.5) actionpack (= 3.2.3)
activesupport (= 3.2.5) activesupport (= 3.2.3)
rack-ssl (~> 1.3.2) rack-ssl (~> 1.3.2)
rake (>= 0.8.7) rake (>= 0.8.7)
rdoc (~> 3.4) rdoc (~> 3.4)
thor (>= 0.14.6, < 2.0) thor (~> 0.14.6)
raindrops (0.9.0) raindrops (0.8.0)
rake (0.9.2.2) rake (0.9.2.2)
rdoc (3.12) rdoc (3.12)
json (~> 1.4) json (~> 1.4)
@ -284,12 +283,12 @@ GEM
rubyzip (0.9.8) rubyzip (0.9.8)
sanitize (2.0.3) sanitize (2.0.3)
nokogiri (>= 1.4.4, < 1.6) nokogiri (>= 1.4.4, < 1.6)
sass (3.1.19) sass (3.1.17)
sass-rails (3.2.5) sass-rails (3.2.5)
railties (~> 3.2.0) railties (~> 3.2.0)
sass (>= 3.1.10) sass (>= 3.1.10)
tilt (~> 1.3) tilt (~> 1.3)
selenium-webdriver (2.22.2) selenium-webdriver (2.21.2)
childprocess (>= 0.2.5) childprocess (>= 0.2.5)
ffi (~> 1.0) ffi (~> 1.0)
libwebsocket (~> 0.1.3) libwebsocket (~> 0.1.3)
@ -301,7 +300,8 @@ GEM
hike (~> 1.2) hike (~> 1.2)
rack (~> 1.0) rack (~> 1.0)
tilt (~> 1.1, != 1.3.0) tilt (~> 1.1, != 1.3.0)
thor (0.15.2) term-ansicolor (1.0.7)
thor (0.14.6)
tilt (1.3.3) tilt (1.3.3)
treetop (1.4.10) treetop (1.4.10)
polyglot polyglot
@ -326,7 +326,8 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
capybara capybara
coffee-rails (~> 3.2.2) coffee-rails (~> 3.2.2)
compass-rails compass!
compass-rails!
cucumber-rails cucumber-rails
database_cleaner database_cleaner
factory_girl_rails (~> 1.6.0) factory_girl_rails (~> 1.6.0)
@ -335,11 +336,10 @@ DEPENDENCIES
locomotive_cms! locomotive_cms!
mocha (= 0.9.12) mocha (= 0.9.12)
pickle pickle
poltergeist
rspec-cells rspec-cells
rspec-rails (~> 2.8.0) rspec-rails (~> 2.8.0)
sass-rails (~> 3.2.4) sass-rails (~> 3.2.4)
shoulda-matchers shoulda-matchers
uglifier (~> 1.2.4) uglifier (~> 1.2.3)
unicorn unicorn
xpath (~> 0.1.4) xpath (~> 0.1.4)

View File

@ -24,8 +24,8 @@ h2. Gems
Here is a short list of main gems / technologies used in the application. Here is a short list of main gems / technologies used in the application.
* Rails 3.2.5 * Rails 3.2.3
* Mongoid 2.4.9 (with MongoDB 2.0) * Mongoid 2.4.6 (with MongoDB 2.0)
* Liquid * Liquid
* Devise * Devise
* Carrierwave * Carrierwave
@ -46,7 +46,7 @@ h2. Community
* Get help or discuss locomotive CMS at the "LocomotiveCMS Google group":https://groups.google.com/forum/?fromgroups#!forum/locomotivecms or the "LocomotiveCMS Discussion Forums":http://locomotive.vanillaforums.com/ (deprecated) * Get help or discuss locomotive CMS at the "LocomotiveCMS Google group":https://groups.google.com/forum/?fromgroups#!forum/locomotivecms or the "LocomotiveCMS Discussion Forums":http://locomotive.vanillaforums.com/ (deprecated)
* Join us on IRC "#locomotivecms at irc.freenode.net!":http://webchat.freenode.net/ * Join us on IRC "#locomotivecms at irc.freenode.net!":http://webchat.freenode.net/
* "Follow us on twitter":http://twitter.com/locomotivecms * "Follow us on twitter":http://twitter.com/locomotiveapp
h2. Contributing to Locomotive h2. Contributing to Locomotive
@ -55,7 +55,6 @@ Locomotive CMS is an open source project, we encourage contributions. If you hav
* Install ruby and mongoDB * Install ruby and mongoDB
* Clone the project <code>git clone git@github.com:locomotivecms/engine.git</code> * Clone the project <code>git clone git@github.com:locomotivecms/engine.git</code>
* Setup a virtual host entry for <code>test.example.com</code> to point to localhost * Setup a virtual host entry for <code>test.example.com</code> to point to localhost
* Install PhantomJS (Required for the cucumber suite See: https://github.com/jonleighton/poltergeist)
* Run the tests <code>rake</code> * Run the tests <code>rake</code>
* Write your failing tests * Write your failing tests
* Make the tests pass * Make the tests pass

View File

Before

Width:  |  Height:  |  Size: 611 B

After

Width:  |  Height:  |  Size: 611 B

View File

@ -25,7 +25,7 @@ define(
picker.close(); picker.close();
} }
picker.fetch_assets(); picker.render()
}, },
/** /**

View File

@ -16,12 +16,9 @@ class Locomotive.Models.Page extends Backbone.Model
toJSON: -> toJSON: ->
_.tap super, (hash) => _.tap super, (hash) =>
_.each ['fullpath', 'localized_fullpaths', 'templatized_from_parent', 'target_klass_name_text', 'content_type_id_text', 'edit_url', 'parent_id_text', 'response_type_text'], (key) => delete hash[key] _.each ['fullpath', 'localized_fullpaths', 'edit_url', 'parent_id_text', 'response_type_text'], (key) => delete hash[key]
delete hash['editable_elements'] delete hash['editable_elements']
hash.editable_elements = @get('editable_elements').toJSONForSave() if @get('editable_elements')? && @get('editable_elements').length > 0 hash.editable_elements = @get('editable_elements').toJSONForSave() if @get('editable_elements')? && @get('editable_elements').length > 0
delete hash['target_klass_name'] class Locomotive.Models.PagesCollection extends Backbone.Collection
hash.target_klass_name = @get('target_klass_name') if @get('templatized') == true
class Locomotive.Models.PagesCollection extends Backbone.Collection

View File

@ -69,7 +69,5 @@
doc.head.appendChild(stylesheet); doc.head.appendChild(stylesheet);
} }
$.ui.dialog.prototype.overlayEl = function() { return this.overlay.$el; }
})(); })();

View File

@ -83,10 +83,3 @@ class Locomotive.Views.ApplicationView extends Backbone.View
locale = $(@).attr('data-locale') locale = $(@).attr('data-locale')
window.addParameterToURL 'content_locale', locale window.addParameterToURL 'content_locale', locale
unique_dialog_zindex: ->
# returns the number of jQuery UI modals created in order to set a valid zIndex for each of them.
# Each modal window should have a different zIndex, otherwise there will be conflicts between them.
window.Locomotive.jQueryModals ||= 0
998 + window.Locomotive.jQueryModals++

View File

@ -12,10 +12,7 @@ class Locomotive.Views.ContentAssets.PickerView extends Locomotive.Views.Shared.
ich.content_asset_picker ich.content_asset_picker
fetch_assets: -> fetch_assets: ->
@_reset() @collection.fetch()
@collection.fetch
success: () =>
@open()
build_uploader: (el, link) -> build_uploader: (el, link) ->
link.bind 'click', (event) -> link.bind 'click', (event) ->

View File

@ -50,13 +50,11 @@ class Locomotive.Views.ContentEntries.FormView extends Locomotive.Views.Shared.F
settings = _.extend {}, @tinyMCE_settings(), settings = _.extend {}, @tinyMCE_settings(),
oninit: ((editor) => oninit: ((editor) =>
$.cmd 'S', (() => $.cmd 'S', (() =>
editor.save() $(textarea).val(editor.getBody().innerHTML).trigger('change')
$(textarea).trigger('changeSilently')
@$('form').trigger('submit') @$('form').trigger('submit')
), [], ignoreCase: true, document: editor.dom.doc), ), [], ignoreCase: true, document: editor.dom.doc),
onchange_callback: (editor) => onchange_callback: (editor) =>
editor.save() $(textarea).val(editor.getBody().innerHTML).trigger('change')
$(textarea).trigger('changeSilently')
$(textarea).tinymce(settings) $(textarea).tinymce(settings)

View File

@ -26,9 +26,11 @@ class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.Con
@dialog = $(@el).dialog @dialog = $(@el).dialog
autoOpen: false autoOpen: false
modal: true modal: true
zIndex: window.application_view.unique_dialog_zindex() zIndex: 998
width: 770, width: 770,
create: (event, ui) => create: (event, ui) =>
$('.ui-widget-overlay').bind 'click', => @close()
$(@el).prev().find('.ui-dialog-title').html(@$('h2').html()) $(@el).prev().find('.ui-dialog-title').html(@$('h2').html())
@$('h2').remove() @$('h2').remove()
actions = @$('.dialog-actions').appendTo($(@el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix') actions = @$('.dialog-actions').appendTo($(@el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix')
@ -37,7 +39,6 @@ class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.Con
actions.find('input[type=submit]').click (event) => @save(event) actions.find('input[type=submit]').click (event) => @save(event)
open: (event, ui, extra) => open: (event, ui, extra) =>
$(@el).dialog('overlayEl').bind 'click', => @close()
# nothing to do # nothing to do
open: -> open: ->
@ -56,7 +57,6 @@ class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.Con
close: (event) -> close: (event) ->
event.stopPropagation() & event.preventDefault() if event? event.stopPropagation() & event.preventDefault() if event?
@clear_errors() @clear_errors()
$(@el).dialog('overlayEl').unbind('click')
$(@el).dialog('close') $(@el).dialog('close')
center: -> center: ->
@ -71,9 +71,6 @@ class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.Con
else else
@refresh() @refresh()
slugify_label_field: ->
# disabled in a popup form
enable_has_many_fields: -> enable_has_many_fields: ->
# disabled in a popup form # disabled in a popup form

View File

@ -12,6 +12,8 @@ class Locomotive.Views.ContentTypes.FormView extends Locomotive.Views.Shared.For
initialize: -> initialize: ->
@model = new Locomotive.Models.ContentType(@options.content_type) @model = new Locomotive.Models.ContentType(@options.content_type)
window.foo = @model
Backbone.ModelBinding.bind @ Backbone.ModelBinding.bind @
render: -> render: ->

View File

@ -58,18 +58,11 @@ class Locomotive.Views.ContentTypes.CustomFieldEntryView extends Backbone.View
fetch_inverse_of_list: -> fetch_inverse_of_list: ->
@$('li.input.inverse-of select option').remove() @$('li.input.inverse-of select option').remove()
list = @inverse_of_list[@model.get('type')] || [] _.each @inverse_of_list[@model.get('type')], (data) =>
_.each list, (data) =>
if data.class_name == @model.get('class_name') if data.class_name == @model.get('class_name')
option = new Option(data.label, data.name, data.name == @model.get('inverse_of') || list.length == 1) option = new Option(data.label, data.name, data.class_name == @model.get('inverse_of') || @inverse_of_list.length == 1)
@$('li.input.inverse-of select').append(option) @$('li.input.inverse-of select').append(option)
# by default, select the first option
if !@model.get('inverse_of')? && list.length > 0
@model.set
inverse_of: list[0].name
render_select_options_view: -> render_select_options_view: ->
@select_options_view = new Locomotive.Views.ContentTypes.SelectOptionsView @select_options_view = new Locomotive.Views.ContentTypes.SelectOptionsView
model: @model model: @model

View File

@ -15,6 +15,8 @@ class Locomotive.Views.CurrentSite.EditView extends Locomotive.Views.Shared.Form
Backbone.ModelBinding.bind @, checkbox: 'class' Backbone.ModelBinding.bind @, checkbox: 'class'
window.foo = @model
render: -> render: ->
super() super()
@ -55,16 +57,15 @@ class Locomotive.Views.CurrentSite.EditView extends Locomotive.Views.Shared.Form
@$('#site_memberships_input').append(@memberships_view.render().el) @$('#site_memberships_input').append(@memberships_view.render().el)
enable_liquid_editing: -> enable_liquid_editing: ->
if($('#site_robots_txt').length) input = @$('#site_robots_txt')
input = @$('#site_robots_txt') @editor = CodeMirror.fromTextArea input.get()[0],
@editor = CodeMirror.fromTextArea input.get()[0], mode: 'liquid'
mode: 'liquid' autoMatchParens: false
autoMatchParens: false lineNumbers: false
lineNumbers: false passDelay: 50
passDelay: 50 tabMode: 'shift'
tabMode: 'shift' theme: 'default'
theme: 'default' onChange: (editor) => @model.set(robots_txt: editor.getValue())
onChange: (editor) => @model.set(robots_txt: editor.getValue())
save: (event) -> save: (event) ->
if @model.includes_domain(window.location.host) if @model.includes_domain(window.location.host)

View File

@ -24,8 +24,6 @@ class Locomotive.Views.InlineEditor.ApplicationView extends Backbone.View
@toolbar_view.render() @toolbar_view.render()
@content_assets_picker_view.render()
enable_iframe_autoheight: -> enable_iframe_autoheight: ->
iframe = @iframe iframe = @iframe
@ -91,13 +89,6 @@ class Locomotive.Views.InlineEditor.ApplicationView extends Backbone.View
toolbar_view.show_status 'loading' toolbar_view.show_status 'loading'
window.history.pushState('Object', 'Title', link.attr('href').replace('_edit', '_admin')) window.history.pushState('Object', 'Title', link.attr('href').replace('_edit', '_admin'))
unique_dialog_zindex: ->
# returns the number of jQuery UI modals created in order to set a valid zIndex for each of them.
# Each modal window should have a different zIndex, otherwise there will be conflicts between them.
window.Locomotive.jQueryModals ||= 0
1050 + window.Locomotive.jQueryModals++
_$: (selector) -> _$: (selector) ->
$(selector, @iframe[0].contentWindow.document) $(selector, @iframe[0].contentWindow.document)

View File

@ -16,14 +16,14 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
@model = new Locomotive.Models.Page(@options.page) @model = new Locomotive.Models.Page(@options.page)
window.foo = @model
@touched_url = false @touched_url = false
@image_picker_view = new Locomotive.Views.ThemeAssets.ImagePickerView @image_picker_view = new Locomotive.Views.ThemeAssets.ImagePickerView
collection: new Locomotive.Models.ThemeAssetsCollection() collection: new Locomotive.Models.ThemeAssetsCollection()
on_select: @insert_image on_select: @insert_image
@image_picker_view.render()
Backbone.ModelBinding.bind @ Backbone.ModelBinding.bind @
@editable_elements_view = new Locomotive.Views.EditableElements.EditAllView(collection: @model.get('editable_elements')) @editable_elements_view = new Locomotive.Views.EditableElements.EditAllView(collection: @model.get('editable_elements'))
@ -41,7 +41,7 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
@enable_response_type_select() @enable_response_type_select()
# enable check boxes # enable check boxes
@enable_templatized_checkbox() @enable_wildcard_checkbox()
@enable_redirect_checkbox() @enable_redirect_checkbox()
@ -58,7 +58,7 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
open_image_picker: (event) -> open_image_picker: (event) ->
event.stopPropagation() & event.preventDefault() event.stopPropagation() & event.preventDefault()
@image_picker_view.editor = @editor @image_picker_view.editor = @editor
@image_picker_view.fetch_assets() @image_picker_view.render()
insert_image: (path) -> insert_image: (path) ->
text = "{{ '#{path}' | theme_image_url }}" text = "{{ '#{path}' | theme_image_url }}"
@ -72,7 +72,7 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
@editor = CodeMirror.fromTextArea input.get()[0], @editor = CodeMirror.fromTextArea input.get()[0],
mode: 'liquid' mode: 'liquid'
autoMatchParens: false autoMatchParens: false
lineNumbers: false lineNumbers: true
passDelay: 50 passDelay: 50
tabMode: 'shift' tabMode: 'shift'
theme: 'default' theme: 'default'
@ -109,14 +109,9 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
url: @$('#page_slug').attr('data-url') url: @$('#page_slug').attr('data-url')
type: 'get' type: 'get'
dataType: 'json' dataType: 'json'
data: { parent_id: @$('#page_parent_id').val(), slug: @$('#page_slug').val() } data: { parent_id: @$('#page_parent_id').val(), slug: @$('#page_slug').val(), wildcard: @model.get('wildcard') }
success: (data) => success: (data) =>
@$('#page_slug_input .inline-hints').html(data.url).effect('highlight') @$('#page_slug_input .inline-hints').html(data.url).effect('highlight')
if data.templatized_parent
@$('li#page_slug_input').show()
@$('li#page_templatized_input, li#page_target_klass_name_input').hide()
else
@$('li#page_templatized_input').show() unless @model.get('redirect')
enable_response_type_select: -> enable_response_type_select: ->
@$('li#page_response_type_input').change (event) => @$('li#page_response_type_input').change (event) =>
@ -126,19 +121,13 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
@model.set redirect: false @model.set redirect: false
@$('li#page_redirect_input, li#page_redirect_url_input').hide() @$('li#page_redirect_input, li#page_redirect_url_input').hide()
enable_templatized_checkbox: -> enable_wildcard_checkbox: ->
@_enable_checkbox 'templatized', @_enable_checkbox 'wildcard',
features: ['slug', 'redirect', 'listed'] features: ['redirect', 'listed']
on_callback: =>
@$('li#page_target_klass_name_input').show()
off_callback: =>
@$('li#page_target_klass_name_input').hide()
@$('li#page_templatized_input').hide() if @model.get('templatized_from_parent') == true
enable_redirect_checkbox: -> enable_redirect_checkbox: ->
@_enable_checkbox 'redirect', @_enable_checkbox 'redirect',
features: ['templatized', 'cache_strategy'] features: ['wildcard', 'cache_strategy']
on_callback: => on_callback: =>
@$('li#page_redirect_url_input').show() @$('li#page_redirect_url_input').show()
off_callback: => off_callback: =>
@ -146,4 +135,4 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
enable_other_checkboxes: -> enable_other_checkboxes: ->
_.each ['published', 'listed'], (exp) => _.each ['published', 'listed'], (exp) =>
@$('li#page_' + exp + '_input input[type=checkbox]').checkToggle() @$('li#page_' + exp + '_input input[type=checkbox]').checkToggle()

View File

@ -11,9 +11,11 @@ class Locomotive.Views.Shared.AssetPickerView extends Backbone.View
@collection.bind('remove', @remove_asset) @collection.bind('remove', @remove_asset)
render: -> render: ->
@_reset()
$(@el).html(@template()()) $(@el).html(@template()())
@create_dialog() @fetch_assets()
return @ return @
@ -27,32 +29,33 @@ class Locomotive.Views.Shared.AssetPickerView extends Backbone.View
# please overide build_uploader # please overide build_uploader
create_dialog: -> create_dialog: ->
@dialog ||= $(@el).dialog @dialog = $(@el).dialog
autoOpen: false
modal: true modal: true
zIndex: window.application_view.unique_dialog_zindex() zIndex: 998
width: 650, width: 650,
create: (event, ui) => create: (event, ui) =>
$('.ui-widget-overlay').bind 'click', => @close()
$(@el).prev().find('.ui-dialog-title').html(@$('h2').html()) $(@el).prev().find('.ui-dialog-title').html(@$('h2').html())
@$('h2').remove() @$('h2').remove()
actions = @$('.dialog-actions').appendTo($(@el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix') actions = @$('.dialog-actions').appendTo($(@el).parent()).addClass('ui-dialog-buttonpane ui-widget-content ui-helper-clearfix')
actions.find('#close-link').click (event) => @close(event) actions.find('#close-link').click (event) => @close(event)
input = actions.find('input[type=file]')
link = actions.find('#upload-link')
@build_uploader(input, link)
open: (event, ui, extra) => open: (event, ui, extra) =>
$(@el).dialog('overlayEl').bind 'click', => @close() actions = $(@el).parent().find('.ui-dialog-buttonpane')
el = actions.find('input[type=file]')
link = actions.find('#upload-link')
@build_uploader(el, link)
@open()
open: -> open: ->
$(@el).dialog('open') $(@el).dialog('open')
close: (event) -> close: (event) ->
event.stopPropagation() & event.preventDefault() if event? event.stopPropagation() & event.preventDefault() if event?
$(@el).dialog('overlayEl').unbind('click')
$(@el).dialog('close') $(@el).dialog('close')
shake: -> shake: ->
@ -67,6 +70,8 @@ class Locomotive.Views.Shared.AssetPickerView extends Backbone.View
@_refresh() @_refresh()
setTimeout (=> @create_dialog()), 30 # disable flickering
add_asset: (asset, first) -> add_asset: (asset, first) ->
# please overide add_asset (the 'first' param is to know if it comes from the first collection fetch) # please overide add_asset (the 'first' param is to know if it comes from the first collection fetch)
@ -89,4 +94,6 @@ class Locomotive.Views.Shared.AssetPickerView extends Backbone.View
_on_refresh: -> _on_refresh: ->
_reset: -> _reset: ->
# for nothing to do $('.ui-widget-overlay').unbind 'click'
@$('.actions input[type=file]').remove()
@dialog.dialog('destroy') if @dialog?

View File

@ -36,8 +36,7 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
previous_attributes = _.clone @model.attributes previous_attributes = _.clone @model.attributes
@model.save {}, @model.save {},
headers: options.headers headers: options.headers
silent: true # since we pass an empty hash above, no need to trigger the callbacks
success: (model, response, xhr) => success: (model, response, xhr) =>
form.trigger('ajax:complete') form.trigger('ajax:complete')

View File

@ -19,8 +19,6 @@ class Locomotive.Views.Snippets.FormView extends Locomotive.Views.Shared.FormVie
collection: new Locomotive.Models.ThemeAssetsCollection() collection: new Locomotive.Models.ThemeAssetsCollection()
on_select: @insert_image on_select: @insert_image
@image_picker_view.render()
Backbone.ModelBinding.bind @ Backbone.ModelBinding.bind @
render: -> render: ->
@ -40,7 +38,7 @@ class Locomotive.Views.Snippets.FormView extends Locomotive.Views.Shared.FormVie
open_image_picker: (event) -> open_image_picker: (event) ->
event.stopPropagation() & event.preventDefault() event.stopPropagation() & event.preventDefault()
@image_picker_view.editor = @editor @image_picker_view.editor = @editor
@image_picker_view.fetch_assets() @image_picker_view.render()
insert_image: (path) -> insert_image: (path) ->
text = "{{ '#{path}' | theme_image_url }}" text = "{{ '#{path}' | theme_image_url }}"

View File

@ -15,9 +15,9 @@ class Locomotive.Views.ThemeAssets.FormView extends Locomotive.Views.Shared.Form
@model = new Locomotive.Models.ThemeAsset(@options.theme_asset) @model = new Locomotive.Models.ThemeAsset(@options.theme_asset)
@image_picker_view = new Locomotive.Views.ThemeAssets.ImagePickerView on_select: @insert_image window.foo = @model
@image_picker_view.render() @image_picker_view = new Locomotive.Views.ThemeAssets.ImagePickerView on_select: @insert_image
Backbone.ModelBinding.bind @ Backbone.ModelBinding.bind @
@ -72,10 +72,10 @@ class Locomotive.Views.ThemeAssets.FormView extends Locomotive.Views.Shared.Form
open_image_picker: (event) -> open_image_picker: (event) ->
event.stopPropagation() & event.preventDefault() event.stopPropagation() & event.preventDefault()
@image_picker_view.editor = @editor @image_picker_view.editor = @editor
@image_picker_view.fetch_assets() @image_picker_view.render()
insert_image: (path) -> insert_image: (path) ->
text = "'#{path}'" text = "{{ '#{path}' | theme_image_url }}"
@editor.replaceSelection(text) @editor.replaceSelection(text)
@image_picker_view.close() @image_picker_view.close()

View File

@ -15,12 +15,7 @@ class Locomotive.Views.ThemeAssets.ImagePickerView extends Locomotive.Views.Shar
ich.theme_image_picker ich.theme_image_picker
fetch_assets: -> fetch_assets: ->
@_reset() @collection.fetch data: { content_type: 'image' }
@collection.fetch
data:
content_type: 'image'
success: () =>
@open()
build_uploader: (el, link) -> build_uploader: (el, link) ->
link.bind 'click', (event) -> link.bind 'click', (event) ->
@ -42,7 +37,4 @@ class Locomotive.Views.ThemeAssets.ImagePickerView extends Locomotive.Views.Shar
add_asset: (asset) -> add_asset: (asset) ->
@$('ul.list').append(ich.theme_asset(asset.toJSON())) @$('ul.list').append(ich.theme_asset(asset.toJSON()))
@_refresh() @_refresh()
_reset: ->
@$('ul.list').empty()

View File

@ -43,16 +43,13 @@
'collection': new Locomotive.Models.ContentAssetsCollection() 'collection': new Locomotive.Models.ContentAssetsCollection()
}); });
view.render();
// Register commands // Register commands
ed.addCommand('locomotiveMedia', function() { ed.addCommand('locomotiveMedia', function() {
view.options.on_select = function(asset) { view.options.on_select = function(asset) {
insertImage(ed, asset); insertImage(ed, asset);
view.close(); view.close();
} }
view.render();
view.fetch_assets();
}); });
// Register buttons // Register buttons

View File

@ -271,7 +271,7 @@ ul.list {
cursor: move; cursor: move;
} }
&.templatized > .inner > a { &.wildcard > .inner > a {
padding-right: 24px; padding-right: 24px;
background: transparent image-url("locomotive/list/icons/template.png") no-repeat right 2px; background: transparent image-url("locomotive/list/icons/template.png") no-repeat right 2px;
} }

View File

@ -7,7 +7,6 @@
font-size: 13px; font-size: 13px;
font-weight: normal; font-weight: normal;
line-height: 15px;
@include background-image(linear-gradient(top, #f0f0f0, #f9f9f9 4px, #f9f9f9 4px, #ffffff 12px, #ffffff)); @include background-image(linear-gradient(top, #f0f0f0, #f9f9f9 4px, #f9f9f9 4px, #ffffff 12px, #ffffff));

View File

@ -60,7 +60,7 @@
.ui-dialog-content { .ui-dialog-content {
position: relative; position: relative;
z-index: 1200; z-index: 999;
text-align: left; text-align: left;
@ -124,14 +124,14 @@
top: 8px; top: 8px;
right: 10px; right: 10px;
z-index: 1203; z-index: 1003;
a, input[type=submit] { a, input[type=submit] {
@include light-button; @include light-button;
} }
input[type=file] { input[type=file] {
z-index: 1203; z-index: 1003;
} }
} // .button-wrapper } // .button-wrapper

View File

@ -421,10 +421,8 @@ form.formtastic {
} }
&.no-label { &.no-label {
padding-top: 12px;
> textarea, .CodeMirror, .CodeMirror-scroll { > textarea, .CodeMirror, .CodeMirror-scroll {
margin-top: 0px; margin-top: 12px;
width: 868px; width: 868px;
} }
} }

View File

@ -24,7 +24,7 @@ module Locomotive
add :switch, :url => '#', :id => 'sites-picker-link' add :switch, :url => '#', :id => 'sites-picker-link'
end end
add :help, :url => 'http://doc.locomotivecms.com/templates/basics', :class => 'tutorial', :id => 'help' add :help, :url => '#', :class => 'tutorial', :id => 'help'
add :logout, :url => destroy_locomotive_session_url, :confirm => t('locomotive.messages.confirm'), :method => :delete add :logout, :url => destroy_locomotive_session_url, :confirm => t('locomotive.messages.confirm'), :method => :delete
end end

View File

@ -7,13 +7,15 @@ module Locomotive
skip_before_filter :verify_authenticity_token skip_before_filter :verify_authenticity_token
skip_load_and_authorize_resource
before_filter :require_account before_filter :require_account
before_filter :require_site before_filter :require_site
before_filter :set_locale before_filter :set_locale
before_filter :set_current_thread_variables # before_filter :validate_site_membership
self.responder = Locomotive::ActionController::Responder # custom responder self.responder = Locomotive::ActionController::Responder # custom responder
@ -21,11 +23,6 @@ module Locomotive
protected protected
def set_current_thread_variables
Thread.current[:account] = current_locomotive_account
Thread.current[:site] = current_site
end
def current_ability def current_ability
@current_ability ||= Ability.new(current_locomotive_account, current_site) @current_ability ||= Ability.new(current_locomotive_account, current_site)
end end
@ -43,4 +40,4 @@ module Locomotive
end end
end end
end end

View File

@ -2,18 +2,11 @@ module Locomotive
module Api module Api
class ContentAssetsController < BaseController class ContentAssetsController < BaseController
load_and_authorize_resource :class => Locomotive::ContentAsset
def index def index
@content_assets = current_site.content_assets @content_assets = current_site.content_assets
respond_with(@content_assets) respond_with(@content_assets)
end end
def show
@content_asset = current_site.content_assets.find(params[:id])
respond_with(@content_asset)
end
def create def create
@content_asset = current_site.content_assets.create(params[:content_asset]) @content_asset = current_site.content_assets.create(params[:content_asset])
respond_with @content_asset, :location => main_app.locomotive_api_content_assets_url respond_with @content_asset, :location => main_app.locomotive_api_content_assets_url
@ -25,12 +18,6 @@ module Locomotive
respond_with @content_asset, :location => main_app.locomotive_api_content_assets_url respond_with @content_asset, :location => main_app.locomotive_api_content_assets_url
end end
def destroy
@content_asset = current_site.content_assets.find(params[:id])
@content_asset.destroy
respond_with @content_asset
end
end end
end end
end end

View File

@ -2,18 +2,11 @@ module Locomotive
module Api module Api
class ContentTypesController < BaseController class ContentTypesController < BaseController
load_and_authorize_resource :class => Locomotive::ContentType
def index def index
@content_types = current_site.content_types.order_by([[:name, :asc]]) @content_types = current_site.content_types
respond_with(@content_types) respond_with(@content_types)
end end
def show
@content_type = current_site.content_types.find(params[:id])
respond_with @content_type
end
def create def create
@content_type = current_site.content_types.create(params[:content_type]) @content_type = current_site.content_types.create(params[:content_type])
respond_with @content_type, :location => main_app.locomotive_api_content_types_url respond_with @content_type, :location => main_app.locomotive_api_content_types_url
@ -25,12 +18,6 @@ module Locomotive
respond_with @content_type, :location => main_app.locomotive_api_content_types_url respond_with @content_type, :location => main_app.locomotive_api_content_types_url
end end
def destroy
@content_type = current_site.content_types.find(params[:id])
@content_type.destroy
respond_with @content_type
end
end end
end end
end end

View File

@ -3,9 +3,7 @@ module Locomotive
class CurrentSiteController < BaseController class CurrentSiteController < BaseController
def show def show
@site = current_site respond_with(current_site)
authorize! :show, @site
respond_with(@site)
end end
end end

View File

@ -1,49 +0,0 @@
module Locomotive
module Api
class MembershipsController < BaseController
# It's an embedded document, so we'll just load manually
before_filter :load_membership, :only => [ :show, :update, :destroy ]
before_filter :load_memberships, :only => [ :index ]
authorize_resource :class => Locomotive::Membership
def index
respond_with(@memberships)
end
def show
respond_with(@membership)
end
def create
build_params = params[:membership].merge({ :role => 'author' }) # force author by default
@membership = current_site.memberships.create(build_params)
respond_with(@membership)
end
def update
@membership.update_attributes(params[:membership])
respond_with(@membership)
end
def destroy
@membership.destroy
respond_with(@membership)
end
protected
def load_membership
@membership ||= load_memberships.find(params[:id])
end
def load_memberships
@memberships ||= current_site.memberships
end
end
end
end

View File

@ -2,18 +2,11 @@ module Locomotive
module Api module Api
class PagesController < BaseController class PagesController < BaseController
load_and_authorize_resource :class => Locomotive::Page
def index def index
@pages = current_site.pages.order_by([[:depth, :asc], [:position, :asc]]) @pages = current_site.pages.all
respond_with(@pages) respond_with(@pages)
end end
def show
@page = current_site.pages.find(params[:id])
respond_with(@page)
end
def create def create
@page = current_site.pages.create(params[:page]) @page = current_site.pages.create(params[:page])
respond_with @page, :location => main_app.locomotive_api_pages_url respond_with @page, :location => main_app.locomotive_api_pages_url
@ -25,12 +18,6 @@ module Locomotive
respond_with @page, :location => main_app.locomotive_api_pages_url respond_with @page, :location => main_app.locomotive_api_pages_url
end end
def destroy
@page = current_site.pages.find(params[:id])
@page.destroy
respond_with @page
end
end end
end end

View File

@ -1,44 +0,0 @@
module Locomotive
module Api
class SitesController < BaseController
load_and_authorize_resource :class => Locomotive::Site
# FIXME: the auto-loaded site won't pass authorization for show, update, or destroy
skip_load_and_authorize_resource :only => [ :show, :update, :destroy ]
def index
@sites = Locomotive::Site.all
respond_with(@sites)
end
def show
@site = Locomotive::Site.find(params[:id])
authorize! :show, @site
respond_with(@site)
end
def create
@site = Locomotive::Site.create(params[:site])
respond_with(@site)
end
def update
@site = Locomotive::Site.find(params[:id])
authorize! :update, @site
@site.update_attributes(params[:site])
respond_with @site
end
def destroy
@site = Locomotive::Site.find(params[:id])
authorize! :destroy, @site
@site.destroy
respond_with @site
end
end
end
end

View File

@ -2,18 +2,11 @@ module Locomotive
module Api module Api
class SnippetsController < BaseController class SnippetsController < BaseController
load_and_authorize_resource :class => Locomotive::Snippet
def index def index
@snippets = current_site.snippets.order_by([[:name, :asc]]) @snippets = current_site.snippets.all
respond_with(@snippets) respond_with(@snippets)
end end
def show
@snippet = current_site.snippets.find(params[:id])
respond_with @snippet
end
def create def create
@snippet = current_site.snippets.create(params[:snippet]) @snippet = current_site.snippets.create(params[:snippet])
respond_with @snippet, :location => main_app.locomotive_api_snippets_url respond_with @snippet, :location => main_app.locomotive_api_snippets_url
@ -25,12 +18,6 @@ module Locomotive
respond_with @snippet, :location => main_app.locomotive_api_snippets_url respond_with @snippet, :location => main_app.locomotive_api_snippets_url
end end
def destroy
@snippet = current_site.snippets.find(params[:id])
@snippet.destroy
respond_with @snippet
end
end end
end end
end end

View File

@ -2,18 +2,11 @@ module Locomotive
module Api module Api
class ThemeAssetsController < BaseController class ThemeAssetsController < BaseController
load_and_authorize_resource :class => Locomotive::ThemeAsset
def index def index
@theme_assets = current_site.theme_assets.all @theme_assets = current_site.theme_assets.all
respond_with(@theme_assets) respond_with(@theme_assets)
end end
def show
@theme_asset = current_site.theme_assets.find(params[:id])
respond_with @theme_asset
end
def create def create
@theme_asset = current_site.theme_assets.create(params[:theme_asset]) @theme_asset = current_site.theme_assets.create(params[:theme_asset])
respond_with @theme_asset, :location => main_app.locomotive_api_theme_assets_url respond_with @theme_asset, :location => main_app.locomotive_api_theme_assets_url
@ -25,12 +18,6 @@ module Locomotive
respond_with @theme_asset, :location => main_app.locomotive_api_theme_assets_url respond_with @theme_asset, :location => main_app.locomotive_api_theme_assets_url
end end
def destroy
@theme_asset = current_site.theme_assets.find(params[:id])
@theme_asset.destroy
respond_with @theme_asset
end
end end
end end
end end

View File

@ -53,10 +53,10 @@ module Locomotive
end end
def get_path def get_path
page = current_site.pages.build(:parent => current_site.pages.find(params[:parent_id]), :slug => params[:slug].permalink).tap do |p| page = current_site.pages.build(:parent => current_site.pages.find(params[:parent_id]), :slug => params[:slug].permalink, :wildcard => params[:wildcard]).tap do |p|
p.valid?; p.send(:build_fullpath) p.valid?; p.send(:build_fullpath)
end end
render :json => { :url => public_page_url(page), :slug => page.slug, :templatized_parent => page.templatized_from_parent? } render :json => { :url => public_page_url(page), :slug => page.slug }
end end
end end

View File

@ -6,6 +6,8 @@ module Locomotive
before_filter :sanitize_entry_params, :only => :create before_filter :sanitize_entry_params, :only => :create
skip_before_filter :verify_authenticity_token
skip_load_and_authorize_resource skip_load_and_authorize_resource
self.responder = Locomotive::ActionController::PublicResponder # custom responder self.responder = Locomotive::ActionController::PublicResponder # custom responder
@ -15,6 +17,7 @@ module Locomotive
def create def create
@entry = @content_type.entries.create(params[:entry] || params[:content]) @entry = @content_type.entries.create(params[:entry] || params[:content])
flash[@content_type.slug.singularize] = @entry.to_presenter(:include_errors => true).as_json flash[@content_type.slug.singularize] = @entry.to_presenter(:include_errors => true).as_json
Rails.logger.debug @entry.to_presenter(:include_errors => true).as_json
respond_with @entry, :location => self.callback_url respond_with @entry, :location => self.callback_url
end end
@ -45,13 +48,6 @@ module Locomotive
end end
end end
def handle_unverified_request
if Locomotive.config.csrf_protection
reset_session
redirect_to '/', :status => 302
end
end
end end
end end
end end

View File

@ -99,13 +99,13 @@ module Locomotive
Locomotive.config.multi_sites? Locomotive.config.multi_sites?
end end
def public_page_url(page, options = {}) # def public_page_url(page, options = {})
if content = options.delete(:content) # if content = options.delete(:content)
File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug) # File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug)
else # else
File.join(current_site_public_url, page.fullpath) # File.join(current_site_public_url, page.fullpath)
end # end
end # end
# memberships # memberships

View File

@ -2,7 +2,7 @@ module Locomotive
module PagesHelper module PagesHelper
def css_for_page(page) def css_for_page(page)
%w(index not_found templatized redirect).inject([]) do |memo, state| %w(index not_found wildcard redirect).inject([]) do |memo, state|
memo << state.dasherize if page.send(:"#{state}?") memo << state.dasherize if page.send(:"#{state}?")
memo memo
end.join(' ') end.join(' ')
@ -32,13 +32,6 @@ module Locomotive
list list
end end
def options_for_target_klass_name
base_models = current_site.content_types.map do |type|
[type.name.humanize, type.klass_with_custom_fields(:entries)]
end
base_models + Locomotive.config.models_for_templatization.map { |name| [name.underscore.humanize, name] }
end
def options_for_page_cache_strategy def options_for_page_cache_strategy
[ [
[t('.cache_strategy.none'), 'none'], [t('.cache_strategy.none'), 'none'],

View File

@ -37,8 +37,6 @@ module Locomotive
can :touch, Site do |site| can :touch, Site do |site|
site == @site site == @site
end end
can :read, ContentType
end end
def setup_designer_permissions! def setup_designer_permissions!

View File

@ -5,20 +5,6 @@ module Locomotive
devise *Locomotive.config.devise_modules devise *Locomotive.config.devise_modules
## devise fields (need to be declared since 2.x) ##
field :remember_created_at, :type => Time
field :email, :type => String, :null => false
field :encrypted_password, :type => String, :null => false
field :authentication_token, :type => String
field :reset_password_token, :type => String
field :reset_password_sent_at, :type => Time
field :password_salt, :type => String
field :sign_in_count, :type => Integer
field :current_sign_in_at, :type => Time
field :last_sign_in_at, :type => Time
field :current_sign_in_ip, :type => String
field :last_sign_in_ip, :type => String
## attributes ## ## attributes ##
field :name field :name
field :locale, :default => Locomotive.config.default_locale.to_s or 'en' field :locale, :default => Locomotive.config.default_locale.to_s or 'en'

View File

@ -45,11 +45,9 @@ module Locomotive
self.send((type || self.content_type).label_field_name.to_sym) self.send((type || self.content_type).label_field_name.to_sym)
end end
value.respond_to?(:to_label) ? value.to_label : value.to_s value.respond_to?(:to_label) ? value.to_label : value
end end
alias :to_label :_label
def translated? def translated?
if self.respond_to?(:"#{self._label_field_name}_translations") if self.respond_to?(:"#{self._label_field_name}_translations")
self.send(:"#{self._label_field_name}_translations").key?(::Mongoid::Fields::I18n.locale.to_s) #rescue false self.send(:"#{self._label_field_name}_translations").key?(::Mongoid::Fields::I18n.locale.to_s) #rescue false

View File

@ -84,13 +84,6 @@ module Locomotive
self.class.class_name_to_content_type(class_name, self.site) self.class.class_name_to_content_type(class_name, self.site)
end end
def label_field_id=(value)
# update the label_field_name if the label_field_id is changed
new_label_field_name = self.entries_custom_fields.where(:_id => value).first.try(:name)
self.label_field_name = new_label_field_name
super(value)
end
def label_field_name=(value) def label_field_name=(value)
# mandatory if we allow the API to set the label field name without an id of the field # mandatory if we allow the API to set the label field name without an id of the field
@new_label_field_name = value unless value.blank? @new_label_field_name = value unless value.blank?

View File

@ -0,0 +1,196 @@
module Locomotive
module Extensions
module Page
module Fullpath
extend ActiveSupport::Concern
included do
## fields ##
field :fullpath, :localize => true
field :wildcard, :type => Boolean, :default => false
field :wildcards, :type => Array
## callbacks ##
before_validation :get_wildcards_from_parent
before_validation :add_slug_to_wildcards
before_save :build_fullpath
after_update :propagate_fullpath_changes
# before_save :set_children_autosave
# before_rearrange :foo #propagate_fullpath_changes
# after_save :propagate_fullpath_changes
# after_save { |p| puts "[after_save] #{p.fullpath} / #{p.wildcards.inspect} / #{p.wildcard?}" }
## scopes ##
# scope :fullpath, lambda { |fullpath| { :where => { :fullpath => fullpath } } } # used ?
## virtual attributes ##
attr_accessor :wildcards_hash
end
# def foo
# Rails.logger.debug "----> rearranging #{self.slug}.......\n\n"
# puts "[rearranging]"
# end
# This method returns true if the fullpath is enhanced
# by wildcards. It is different from the wildcard? method
# because it includes the ancestors when determining if
# the current page has wildcards or not.
#
def has_wildcards?
self.wildcard? || !self.fullpath.try(:index, '*').nil?
end
# It returns a pretty output of the fullpath. The "*" characters
# are replaced by the following pattern ":<slug>" like the ones you can find
# in the Ruby on Rails routes.
#
def pretty_fullpath
return self.fullpath unless self.has_wildcards?
index = 0
self.fullpath.split('/').map do |segment|
if segment == '*'
":#{self.wildcards[index]}".tap { index += 1 }
else
segment
end
end.join('/')
end
# It returns the fullpath with wildcard segments replaced by the values
# specified in the first argument.
#
# @param [ Hash ] values The map assigning to a wildcard name its value
# @return [ String ] The compiled fullpath
#
def compiled_fullpath(values)
return self.fullpath unless self.has_wildcards?
index = 0
self.fullpath.split('/').map do |segment|
if segment == '*'
"#{values[self.wildcards[index]]}".tap { index += 1 }
else
segment
end
end.join('/')
end
# It builds the map associating the name of a wildcard
# with its value within the path.
# The map is also stored in the wildcards_hash attribute
# of the page.
#
# @param [ String ] path the path from the HTTP request
# @return [ Hash ] The map
#
def match_wildcards(path)
self.wildcards_hash, wildcard_index, segments = {}, 0, self.fullpath.split('/')
path.split('/').each_with_index do |segment, index|
if segments[index] == '*'
self.wildcards_hash[self.wildcards[wildcard_index].underscore] = segment
wildcard_index += 1
end
end
self.wildcards_hash
end
protected
# def set_children_autosave
# @autosave_for_children = !must_propagate_fullpath_changes?
# true
# end
def get_wildcards_from_parent
return true if self.parent.nil?
if self.parent.has_wildcards?
# puts "[get_wildcards_from_parent] #{self.slug} - #{self.parent.wildcards.inspect}"
self.wildcards = self.parent.wildcards.clone
else
# puts "[get_wildcards_from_parent] #{self.slug} - reset wildcards"
self.wildcards = []
end
end
def add_slug_to_wildcards
# puts "[add_slug_to_wildcards] #{self.slug} / #{self.wildcard?}"
(self.wildcards ||= []) << self.slug if self.wildcard?
end
def build_fullpath
if self.index? || self.not_found?
self.fullpath = self.slug
else
segments = (self.parent.fullpath.try(:split, '/') || [nil]) + [self.wildcard? ? '*' : self.slug]
segments.shift if segments.first == 'index'
self.fullpath = File.join segments.compact
end
end
def propagate_fullpath_changes
if self.fullpath_changed? || self.wildcards_changed?
self.rearrange_children!
end
end
# def must_propagate_fullpath_changes?
# self.wildcard_changed? || self.slug_changed?
# end
#
# def propagate_fullpath_changes
# return true unless must_propagate_fullpath_changes?
#
# parent_identities = { self._id => self }
#
# Rails.logger.debug "[propagate_fullpath_changes] BEGIN page #{self.slug} #{self.fullpath} / #{self.wildcards.inspect} / #{self._parent.try(:has_wildcards?).inspect}"
# puts "[propagate_fullpath_changes] BEGIN page #{self.slug} #{self.fullpath} / #{self.wildcards.inspect} / #{self._parent.try(:has_wildcards?).inspect}"
#
# self.descendants.order_by([[:depth, :asc]]).each do |page|
# _parent = parent_identities[page.parent_id]
# _fullpath = {}
# _wildcards = nil
#
# puts "[propagate_fullpath_changes] #{page.fullpath} / #{page.wildcards.inspect} / #{page._parent.try(:has_wildcards?).inspect}"
#
# if _parent.has_wildcards?
# _wildcards = _parent.wildcards + (page.wildcard? ? [page.slug] : [])
# end
#
# self.site.locales.each do |locale|
# base_fullpath = _parent.fullpath_translations[locale]
# slug = page.wildcard? ? '*' : page.slug_translations[locale]
#
# next if base_fullpath.blank?
#
# _fullpath[locale] = File.join(base_fullpath, slug)
# end
#
# selector = { 'id' => page._id }
# operations = {
# '$set' => {
# 'wildcards' => _wildcards,
# 'fullpath' => _fullpath
# }
# }
# self.collection.update selector, operations
#
# parent_identities[page._id] = page
# end
# end
end
end
end
end

View File

@ -22,7 +22,8 @@ module Locomotive
validate :template_must_be_valid validate :template_must_be_valid
## scopes ## ## scopes ##
scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } } scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
scope :dependent_from, lambda { |id| { :where => { :template_dependencies.in => [id] } } }
end end
def template def template

View File

@ -9,7 +9,7 @@ module Locomotive
## fields ## ## fields ##
field :redirect, :type => Boolean, :default => false field :redirect, :type => Boolean, :default => false
field :redirect_url, :type => String, :localize => true field :redirect_url, :type => String
## validations ## ## validations ##
validates_presence_of :redirect_url, :if => :redirect validates_presence_of :redirect_url, :if => :redirect

View File

@ -11,11 +11,10 @@ module Locomotive
module ClassMethods module ClassMethods
# Given both a site and a path, this method tries # Given both a site and a path, this method retrieves
# to get the matching page. # the matching page if it exists.
# If the page is templatized, the related content entry is # If the found page owns wildcards in its fullpath, then
# associated to the page (page.content_entry stores the entry). # assigns the value for each wildcard and store the result within the page.
# If no page is found, then it returns the 404 one instead.
# #
# @param [ Site ] site The site where to find the page # @param [ Site ] site The site where to find the page
# @param [ String ] path The fullpath got from the request # @param [ String ] path The fullpath got from the request
@ -33,17 +32,7 @@ module Locomotive
if !_page.published? && !logged_in if !_page.published? && !logged_in
next next
else else
if _page.templatized? _page.match_wildcards(path)
%r(^#{_page.fullpath.gsub('content_type_template', '([^\/]+)')}$) =~ path
permalink = $1
_page.content_entry = _page.fetch_target_entry(permalink)
if _page.content_entry.nil? || (!_page.content_entry.visible? && !logged_in) # content instance not found or not visible
next
end
end
end end
page = _page page = _page
@ -56,9 +45,7 @@ module Locomotive
# Calculate all the combinations possible based on the # Calculate all the combinations possible based on the
# fact that one of the segment of the path could be # fact that one of the segment of the path could be
# a content type from a templatized page. # a wildcard.
# We postulate that there is only one templatized page in a path
# (ie: no nested templatized pages)
# #
# @param [ String ] path The path to the page # @param [ String ] path The path to the page
# #
@ -69,13 +56,13 @@ module Locomotive
end end
#:nodoc: #:nodoc:
def _path_combinations(segments, can_include_template = true) def _path_combinations(segments)
return nil if segments.empty? return nil if segments.empty?
segment = segments.shift segment = segments.shift
(can_include_template ? [segment, 'content_type_template'] : [segment]).map do |_segment| [segment, '*'].map do |_segment|
if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != 'content_type_template')) if (_combinations = _path_combinations(segments.clone))
[*_combinations].map do |_combination| [*_combinations].map do |_combination|
File.join(_segment, _combination) File.join(_segment, _combination)
end end

View File

@ -1,136 +1,136 @@
module Locomotive # module Locomotive
module Extensions # module Extensions
module Page # module Page
module Templatized # module Templatized
#
extend ActiveSupport::Concern # extend ActiveSupport::Concern
#
included do # included do
#
## fields ## # ## fields ##
field :templatized, :type => Boolean, :default => false # field :templatized, :type => Boolean, :default => false
field :templatized_from_parent, :type => Boolean, :default => false # field :templatized_from_parent, :type => Boolean, :default => false
field :target_klass_name # field :target_klass_name
#
## validations ## # ## validations ##
validates_presence_of :target_klass_name, :if => :templatized? # validates_presence_of :target_klass_name, :if => :templatized?
validate :ensure_target_klass_name_security # validate :ensure_target_klass_name_security
#
## callbacks ## # ## callbacks ##
before_validation :get_templatized_from_parent # before_validation :get_templatized_from_parent
before_validation :set_slug_if_templatized # before_validation :set_slug_if_templatized
before_validation :ensure_target_klass_name_security # before_validation :ensure_target_klass_name_security
after_save :propagate_templatized # after_save :propagate_templatized
#
## scopes ## # ## scopes ##
scope :templatized, :where => { :templatized => true } # scope :templatized, :where => { :templatized => true }
#
## virtual attributes ## # ## virtual attributes ##
attr_accessor :content_entry # attr_accessor :content_entry
end # end
#
# Returns the class specified by the target_klass_name property # # Returns the class specified by the target_klass_name property
# # #
# @example # # @example
# # #
# page.target_klass_name = 'Locomotive::Entry12345' # # page.target_klass_name = 'Locomotive::Entry12345'
# page.target_klass = Locomotive::Entry12345 # # page.target_klass = Locomotive::Entry12345
# # #
# @return [ Class ] The target class # # @return [ Class ] The target class
# # #
def target_klass # def target_klass
target_klass_name.constantize # target_klass_name.constantize
end # end
#
# Gives the name which can be used in a liquid template in order # # Gives the name which can be used in a liquid template in order
# to reference an entry. It uses the slug property if the target klass # # to reference an entry. It uses the slug property if the target klass
# is a Locomotive content type or the class name itself for the other classes. # # is a Locomotive content type or the class name itself for the other classes.
# # #
# @example # # @example
# # #
# page.target_klass_name = 'Locomotive::Entry12345' # related to the content type Articles # # page.target_klass_name = 'Locomotive::Entry12345' # related to the content type Articles
# page.target_entry_name = 'article' # # page.target_entry_name = 'article'
# # #
# page.target_klass_name = 'OurProduct' # # page.target_klass_name = 'OurProduct'
# page.target_entry_name = 'our_product' # # page.target_entry_name = 'our_product'
# # #
# @return [ String ] The name in lowercase and underscored # # @return [ String ] The name in lowercase and underscored
# # #
def target_entry_name # def target_entry_name
if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/ # if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
@content_type ||= self.site.content_types.find($1) # @content_type ||= self.site.content_types.find($1)
@content_type.slug.singularize # @content_type.slug.singularize
else # else
self.target_klass_name.underscore # self.target_klass_name.underscore
end # end
end # end
#
# Finds the entry both specified by the target klass and identified by the permalink # # Finds the entry both specified by the target klass and identified by the permalink
# # #
# @param [ String ] permalink The permalink of the entry # # @param [ String ] permalink The permalink of the entry
# # #
# @return [ Object ] The document # # @return [ Object ] The document
# # #
def fetch_target_entry(permalink) # def fetch_target_entry(permalink)
target_klass.find_by_permalink(permalink) # target_klass.find_by_permalink(permalink)
end # end
#
protected # protected
#
def get_templatized_from_parent # def get_templatized_from_parent
return if self.parent.nil? # return if self.parent.nil?
#
if self.parent.templatized? # if self.parent.templatized?
self.templatized = self.templatized_from_parent = true # self.templatized = self.templatized_from_parent = true
self.target_klass_name = self.parent.target_klass_name # self.target_klass_name = self.parent.target_klass_name
elsif !self.templatized? # elsif !self.templatized?
self.templatized = self.templatized_from_parent = false # self.templatized = self.templatized_from_parent = false
self.target_klass_name = nil # self.target_klass_name = nil
end # end
end # end
#
def set_slug_if_templatized # def set_slug_if_templatized
self.slug = 'content_type_template' if self.templatized? && !self.templatized_from_parent? # self.slug = 'content_type_template' if self.templatized? && !self.templatized_from_parent?
end # end
#
# Makes sure the target_klass is owned by the site OR # # Makes sure the target_klass is owned by the site OR
# if it belongs to the models allowed by the application # # if it belongs to the models allowed by the application
# thanks to the models_for_templatization option. # # thanks to the models_for_templatization option.
# # #
def ensure_target_klass_name_security # def ensure_target_klass_name_security
return if !self.templatized? || self.target_klass_name.blank? # return if !self.templatized? || self.target_klass_name.blank?
#
if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/ # if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
content_type = Locomotive::ContentType.find($1) # content_type = Locomotive::ContentType.find($1)
#
if content_type.site_id != self.site_id # if content_type.site_id != self.site_id
self.errors.add :target_klass_name, :security # self.errors.add :target_klass_name, :security
end # end
elsif !Locomotive.config.models_for_templatization.include?(self.target_klass_name) # elsif !Locomotive.config.models_for_templatization.include?(self.target_klass_name)
self.errors.add :target_klass_name, :security # self.errors.add :target_klass_name, :security
end # end
end # end
#
# Sets the templatized, templatized_from_parent properties of # # Sets the templatized, templatized_from_parent properties of
# the children of the current page ONLY IF the templatized # # the children of the current page ONLY IF the templatized
# attribute got changed. # # attribute got changed.
# # #
def propagate_templatized # def propagate_templatized
return unless self.templatized_changed? # return unless self.templatized_changed?
#
selector = { 'parent_ids' => { '$in' => [self._id] } } # selector = { 'parent_ids' => { '$in' => [self._id] } }
operations = { # operations = {
'$set' => { # '$set' => {
'templatized' => self.templatized, # 'templatized' => self.templatized,
'templatized_from_parent' => self.templatized, # 'templatized_from_parent' => self.templatized,
'target_klass_name' => self.target_klass_name # 'target_klass_name' => self.target_klass_name
} # }
} # }
#
self.collection.update selector, operations, :multi => true # self.collection.update selector, operations, :multi => true
end # end
#
end # end
end # end
end # end
end # end

View File

@ -26,7 +26,7 @@ module Locomotive
module ClassMethods module ClassMethods
# Returns the tree of pages from the site with the most minimal amount of queries. # Returns the pages tree from the site with the most minimal amount of queries.
# This method should only be used for read-only purpose since # This method should only be used for read-only purpose since
# the mongodb returns the minimal set of required attributes to build # the mongodb returns the minimal set of required attributes to build
# the tree. # the tree.
@ -77,6 +77,10 @@ module Locomotive
end end
# def autosave_for_children?
# @autosave_for_children != false
# end
# Returns the children of this node but with the minimal set of required attributes # Returns the children of this node but with the minimal set of required attributes
# #
# @return [ Array ] The children pages ordered by their position # @return [ Array ] The children pages ordered by their position

View File

@ -56,6 +56,10 @@ module Locomotive
self.locales_was.first || Locomotive.config.site_locales.first self.locales_was.first || Locomotive.config.site_locales.first
end end
def default_locale_changed?
self.default_locale != self.default_locale_was
end
def locale_fallbacks(locale) def locale_fallbacks(locale)
[locale.to_s] + (locales - [locale.to_s]) [locale.to_s] + (locales - [locale.to_s])
end end
@ -93,4 +97,22 @@ module Locomotive
end end
end end
end end
#
# %w(index 404).each do |slug|
# page = self.pages.where("slug.#{self.default_locale}" => slug).first
#
# self.locales.each do |locale|
# if .blank?
# page.collection.update({ :_id => page._id }, { '$set' => { "slug.#{locale}" => slug } })
# end
#
# if page.attributes['title'][locale.to_s].blank?
# page.collection.update({ :_id => page._id }, {
# '$set' => { "title.#{locale}" => }
# })
# end
# end
# end
# end

View File

@ -8,7 +8,7 @@ module Locomotive
include Extensions::Page::EditableElements include Extensions::Page::EditableElements
include Extensions::Page::Parse include Extensions::Page::Parse
include Extensions::Page::Render include Extensions::Page::Render
include Extensions::Page::Templatized include Extensions::Page::Fullpath
include Extensions::Page::Redirect include Extensions::Page::Redirect
include Extensions::Page::Listed include Extensions::Page::Listed
include Extensions::Shared::Seo include Extensions::Shared::Seo
@ -16,7 +16,6 @@ module Locomotive
## fields ## ## fields ##
field :title, :localize => true field :title, :localize => true
field :slug, :localize => true field :slug, :localize => true
field :fullpath, :localize => true
field :handle field :handle
field :raw_template, :localize => true field :raw_template, :localize => true
field :locales, :type => Array field :locales, :type => Array
@ -35,14 +34,13 @@ module Locomotive
## callbacks ## ## callbacks ##
after_initialize :set_default_raw_template after_initialize :set_default_raw_template
before_validation :normalize_slug before_validation :normalize_slug
before_save :build_fullpath
before_save :record_current_locale before_save :record_current_locale
before_destroy :do_not_remove_index_and_404_pages before_destroy :do_not_remove_index_and_404_pages
## validations ## ## validations ##
validates_presence_of :site, :title, :slug validates_presence_of :site, :title, :slug
validates_uniqueness_of :slug, :scope => [:site_id, :parent_id] validates_uniqueness_of :slug, :scope => [:site_id, :parent_id]
validates_uniqueness_of :handle, :allow_blank => true validates_uniqueness_of :handle, :allow_blank => true, :scope => [:site_id]
validates_exclusion_of :slug, :in => Locomotive.config.reserved_slugs, :if => Proc.new { |p| p.depth <= 1 } validates_exclusion_of :slug, :in => Locomotive.config.reserved_slugs, :if => Proc.new { |p| p.depth <= 1 }
## named scopes ## ## named scopes ##
@ -50,10 +48,8 @@ module Locomotive
scope :root, :where => { :slug => 'index', :depth => 0 } scope :root, :where => { :slug => 'index', :depth => 0 }
scope :not_found, :where => { :slug => '404', :depth => 0 } scope :not_found, :where => { :slug => '404', :depth => 0 }
scope :published, :where => { :published => true } scope :published, :where => { :published => true }
scope :fullpath, lambda { |fullpath| { :where => { :fullpath => fullpath } } }
scope :handle, lambda { |handle| { :where => { :handle => handle } } } scope :handle, lambda { |handle| { :where => { :handle => handle } } }
scope :minimal_attributes, lambda { |attrs = []| { :only => (attrs || []) + %w(title slug fullpath position depth published templatized redirect listed response_type parent_id parent_ids site_id created_at updated_at) } } scope :minimal_attributes, lambda { |attrs = []| { :only => (attrs || []) + %w(title slug fullpath position depth published with_wildcards redirect listed wildcard response_type parent_id parent_ids site_id created_at updated_at) } }
scope :dependent_from, lambda { |id| { :where => { :template_dependencies.in => [id] } } }
## methods ## ## methods ##
@ -114,16 +110,6 @@ module Locomotive
self.raw_template ||= ::I18n.t('attributes.defaults.pages.other.body') self.raw_template ||= ::I18n.t('attributes.defaults.pages.other.body')
end end
def build_fullpath
if self.index? || self.not_found?
self.fullpath = self.slug
else
slugs = self.ancestors_and_self.map(&:slug)
slugs.shift unless slugs.size == 1
self.fullpath = File.join slugs.compact
end
end
def record_current_locale def record_current_locale
self.locales ||= [] self.locales ||= []
self.locales << ::Mongoid::Fields::I18n.locale self.locales << ::Mongoid::Fields::I18n.locale

View File

@ -64,20 +64,21 @@ module Locomotive
protected protected
# FIXME: Currently there is no t/translate method on the I18n module # FIXME: Currently there is no t/translate method on the
# Extensions::Site::I18n which is breaking the testing. The # Extensions::Site::I18n module which is breaking the testing. The
# namespaced ::I18n should be changed to just I18n when the t() # namespaced ::I18n should be replaced by simply I18n when the t()
# method is available # method will be available.
def create_default_pages! def create_default_pages!
::Mongoid::Fields::I18n.with_locale(self.default_locale) do %w(index 404).each do |slug|
%w{index 404}.each do |slug| page = self.pages.build(:title => '', :slug => '', :raw_template => '', :published => true)
self.pages.create({
:slug => slug, self.locales.each do |locale|
:title => ::I18n.t("attributes.defaults.pages.#{slug}.title"), page.attributes['slug'][locale] = slug
:raw_template => ::I18n.t("attributes.defaults.pages.#{slug}.body"), page.attributes['title'][locale] = ::I18n.t("attributes.defaults.pages.#{slug}.title", :locale => locale)
:published => true page.attributes['raw_template'][locale] = ::I18n.t("attributes.defaults.pages.#{slug}.body", :locale => locale)
})
end end
page.save
end end
end end

View File

@ -145,7 +145,7 @@ module Locomotive
def escape_shortcut_urls(text) def escape_shortcut_urls(text)
return if text.blank? return if text.blank?
text.gsub(/[("'](\/(stylesheets|javascripts|images|media)\/(([^;.]+)\/)*([a-zA-Z_\-0-9]+)\.[a-z]{2,3})[)"']/) do |path| text.gsub(/[("'](\/(stylesheets|javascripts|images|media)\/(([^;.]+)\/)*([a-z_\-0-9]+)\.[a-z]{2,3})[)"']/) do |path|
sanitized_path = path.gsub(/[("')]/, '').gsub(/^\//, '') sanitized_path = path.gsub(/[("')]/, '').gsub(/^\//, '')

View File

@ -1,7 +1,7 @@
module Locomotive module Locomotive
class PagePresenter < BasePresenter class PagePresenter < BasePresenter
delegate :title, :slug, :fullpath, :handle, :raw_template, :published, :listed, :templatized, :templatized_from_parent, :redirect, :redirect_url, :template_changed, :cache_strategy, :response_type, :to => :source delegate :title, :slug, :fullpath, :handle, :raw_template, :published, :listed, :wildcard, :wildcards, :redirect, :redirect_url, :template_changed, :cache_strategy, :response_type, :to => :source
def escaped_raw_template def escaped_raw_template
h(self.source.raw_template) h(self.source.raw_template)
@ -12,7 +12,7 @@ module Locomotive
end end
def included_methods def included_methods
super + %w(title slug fullpath handle raw_template published listed templatized templatized_from_parent redirect redirect_url cache_strategy response_type template_changed editable_elements localized_fullpaths) super + %w(title slug fullpath handle raw_template published listed wildcard wildcards redirect redirect_url cache_strategy response_type template_changed editable_elements localized_fullpaths)
end end
def localized_fullpaths def localized_fullpaths

View File

@ -11,9 +11,9 @@
= link_to t('locomotive.buttons.close'), '#', :id => 'close-link' = link_to t('locomotive.buttons.close'), '#', :id => 'close-link'
.button-wrapper.upload .button-wrapper.upload
= form_tag content_assets_url(:json), :class => 'quick-upload' do = form_tag theme_assets_url(:json), :class => 'quick-upload' do
= file_field_tag 'content_asset[source]', :multiple => 'multiple' = file_field_tag 'theme_asset[source]', :multiple => 'multiple'
= link_to t('locomotive.content_assets.image_picker.upload'), content_assets_url(:json), :class => 'new', :id => 'upload-link' = link_to t('locomotive.theme_assets.image_picker.upload'), theme_assets_url(:json), :class => 'new', :id => 'upload-link'
%script{ :type => 'text/html', :id => 'content_asset' } %script{ :type => 'text/html', :id => 'content_asset' }

View File

@ -3,7 +3,7 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
content_entry: #{j @content_entry.to_json.html_safe} content_entry: #{@content_entry.to_json}
= f.inputs :name => :attributes do = f.inputs :name => :attributes do
- @content_type.ordered_entries_custom_fields.each_with_index do |field, index| - @content_type.ordered_entries_custom_fields.each_with_index do |field, index|

View File

@ -3,8 +3,8 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
content_type: #{j @content_type.persisted? ? @content_type.to_json.html_safe : 'null'}, content_type: #{@content_type.persisted? ? @content_type.to_json : 'null'},
inverse_of_list: #{j options_for_content_type_inverse_of.to_json.html_safe} inverse_of_list: #{options_for_content_type_inverse_of.to_json}
= f.inputs :name => :information do = f.inputs :name => :information do

View File

@ -4,7 +4,7 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
site: #{j @site.to_json(:current_account => current_locomotive_account, :current_site => current_site).html_safe}, site: #{@site.to_json(:current_account => current_locomotive_account, :current_site => current_site)},
errors: #{@site.errors.to_json} errors: #{@site.errors.to_json}
= f.inputs :name => :information do = f.inputs :name => :information do

View File

@ -38,4 +38,4 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
, all_#{name}_entries: #{j target_content_type.list_or_group_entries.to_json(:depth => 1).html_safe} , all_#{name}_entries: #{target_content_type.list_or_group_entries.to_json(:depth => 1)}

View File

@ -2,7 +2,7 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
account: #{j @account.to_json.html_safe} account: #{@account.to_json}
- content_for :submenu do - content_for :submenu do
= render_cell 'locomotive/settings_menu', :show = render_cell 'locomotive/settings_menu', :show

View File

@ -5,7 +5,7 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
page: #{j @page.to_presenter.as_json_for_html_view.to_json.html_safe} page: #{@page.to_presenter.as_json_for_html_view.to_json}
- if can?(:manage, @page) - if can?(:manage, @page)
@ -16,7 +16,7 @@
- if not @page.index? and not @page.not_found? - if not @page.index? and not @page.not_found?
= f.input :parent_id, :as => :select, :collection => parent_pages_options, :include_blank => false = f.input :parent_id, :as => :select, :collection => parent_pages_options, :include_blank => false
= f.input :slug, :required => false, :hint => @page.slug.blank? ? t('.empty_slug') : public_page_url(@page), :input_html => { :'data-url' => get_path_pages_url, :disabled => @page.index? || @page.not_found? }, :wrapper_html => { :style => "#{'display: none' if @page.templatized? && !@page.templatized_from_parent?};", :class => 'em-inline-hints' } = f.input :slug, :required => false, :hint => @page.slug.blank? ? t('.empty_slug') : public_page_url(@page), :input_html => { :'data-url' => get_path_pages_url, :disabled => @page.index? || @page.not_found? }, :class => 'em-inline-hints'
= f.inputs :name => :seo, :class => "inputs foldable #{'folded' if inputs_folded?(@page)}" do = f.inputs :name => :seo, :class => "inputs foldable #{'folded' if inputs_folded?(@page)}" do
@ -34,15 +34,13 @@
= f.input :response_type, :as => :select, :collection => options_for_page_response_type, :include_blank => false = f.input :response_type, :as => :select, :collection => options_for_page_response_type, :include_blank => false
= f.input :templatized, :as => :'Locomotive::Toggle', :style => "#{'display: none' if @page.redirect? || @page.templatized_from_parent?}" = f.input :wildcard, :as => :'Locomotive::Toggle', :style => "#{'display: none' if @page.redirect?}"
= f.input :target_klass_name, :as => :select, :collection => options_for_target_klass_name, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if !@page.templatized? || @page.templatized_from_parent?}" }
= f.input :published, :as => :'Locomotive::Toggle' = f.input :published, :as => :'Locomotive::Toggle'
= f.input :listed, :as => :'Locomotive::Toggle' = f.input :listed, :as => :'Locomotive::Toggle', :wrapper_html => { :style => "#{'display: none' if @page.has_wildcards?}" }
= f.input :redirect, :as => :'Locomotive::Toggle', :wrapper_html => { :style => "#{'display: none' if @page.templatized? || !@page.default_response_type?}" } = f.input :redirect, :as => :'Locomotive::Toggle', :wrapper_html => { :style => "#{'display: none' if !@page.default_response_type? || @page.has_wildcards?}" }
= f.input :cache_strategy, :as => :select, :collection => options_for_page_cache_strategy, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if @page.redirect?}" } = f.input :cache_strategy, :as => :select, :collection => options_for_page_cache_strategy, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if @page.redirect?}" }
@ -50,4 +48,4 @@
= f.inputs :name => :raw_template, :class => "inputs foldable #{'folded' if inputs_folded?(@page)}" do = f.inputs :name => :raw_template, :class => "inputs foldable #{'folded' if inputs_folded?(@page)}" do
= f.input :raw_template, :as => :'Locomotive::Code' = f.input :raw_template, :as => :'Locomotive::Code'

View File

@ -3,7 +3,7 @@
%li{ :id => "item-#{page.id}", :class => "page #{css_for_page(page)}" } %li{ :id => "item-#{page.id}", :class => "page #{css_for_page(page)}" }
- children = can?(:manage, page) ? page.children : page.children.find_all { |p| !p.templatized? } - children = page.children
- with_children = !children.empty? - with_children = !children.empty?

View File

@ -20,8 +20,8 @@
window.content_locale = '#{::Mongoid::Fields::I18n.locale}'; window.content_locale = '#{::Mongoid::Fields::I18n.locale}';
Locomotive.mounted_on = '#{Locomotive.mounted_on}'; Locomotive.mounted_on = '#{Locomotive.mounted_on}';
Locomotive.current_site = new Locomotive.Models.Site(#{j current_site.to_json.html_safe}); Locomotive.current_site = new Locomotive.Models.Site(#{current_site.to_json});
Locomotive.current_account = new Locomotive.Models.Account(#{j current_locomotive_account.to_json.html_safe}); Locomotive.current_account = new Locomotive.Models.Account(#{current_locomotive_account.to_json});
$(document).ready(function() { $(document).ready(function() {

View File

@ -8,17 +8,11 @@ xml.urlset "xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9" do
@pages.each do |page| @pages.each do |page|
if not page.index_or_not_found? if not page.index_or_not_found?
if page.templatized? if page.wildcard?
page.content_type.entries.visible.each do |c| # FIXME (Didier L.) unable for now to generate all the pages
xml.url do
xml.loc page_url(page, { :content => c })
xml.lastmod c.updated_at.to_date.to_s('%Y-%m-%d')
xml.priority 0.9
end
end
else else
xml.url do xml.url do
xml.loc page_url(page) xml.loc page_url(page, { :host => true })
xml.lastmod page.updated_at.to_date.to_s('%Y-%m-%d') xml.lastmod page.updated_at.to_date.to_s('%Y-%m-%d')
xml.priority 0.9 xml.priority 0.9
end end

View File

@ -9,6 +9,6 @@
.span-12.last .span-12.last
%p %p
= submit_tag button_label.is_a?(Symbol) ? t(".#{button_label}") : button_label, :'data-disable-with' => t('.disable_with'), :'data-sending-form-message' => t('locomotive.messages.sending_form') = submit_tag button_label.is_a?(Symbol) ? t(".#{button_label}") : button_label, :disable_with => t('.disable_with'), :'data-sending-form-message' => t('locomotive.messages.sending_form')
.clear .clear

View File

@ -19,8 +19,8 @@
window.locale = '#{I18n.locale}'; window.locale = '#{I18n.locale}';
window.content_locale = '#{::Mongoid::Fields::I18n.locale}'; window.content_locale = '#{::Mongoid::Fields::I18n.locale}';
Locomotive.current_site = new Locomotive.Models.Site(#{j current_site.to_presenter.as_json_for_html_view.to_json.html_safe}); Locomotive.current_site = new Locomotive.Models.Site(#{current_site.to_presenter.as_json_for_html_view.to_json});
Locomotive.current_account = new Locomotive.Models.Account(#{j current_locomotive_account.to_json.html_safe}); Locomotive.current_account = new Locomotive.Models.Account(#{current_locomotive_account.to_json});
$(document).ready(function() { $(document).ready(function() {

View File

@ -3,7 +3,7 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
snippet: #{j @snippet.persisted? ? @snippet.to_presenter.as_json_for_html_view.to_json.html_safe : 'null'} snippet: #{@snippet.persisted? ? @snippet.to_presenter.as_json_for_html_view.to_json : 'null'}
= f.inputs :name => :information do = f.inputs :name => :information do
= f.input :name, :wrapper_html => { :class => 'highlighted' } = f.input :name, :wrapper_html => { :class => 'highlighted' }

View File

@ -3,7 +3,7 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
theme_asset: #{j @theme_asset.persisted? ? @theme_asset.to_json.html_safe : 'null'} theme_asset: #{@theme_asset.persisted? ? @theme_asset.to_json : 'null'}
= f.hidden_field :performing_plain_text = f.hidden_field :performing_plain_text

View File

@ -16,11 +16,11 @@
- content_for :backbone_view_data do - content_for :backbone_view_data do
:plain :plain
snippets: #{j can?(:manage, Locomotive::Snippet) ? @snippets.map { |snippet| snippet.to_presenter.as_json_for_html_view }.to_json.html_safe : 'null'}, snippets: #{can?(:manage, Locomotive::Snippet) ? @snippets.map { |snippet| snippet.to_presenter.as_json_for_html_view }.to_json : 'null'},
images: #{j theme_assets_to_json(@assets[:images]).html_safe}, images: #{theme_assets_to_json(@assets[:images])},
media: #{j theme_assets_to_json(@assets[:media]).html_safe}, media: #{theme_assets_to_json(@assets[:media])},
js_and_css_assets: #{j can?(:manage, Locomotive::ThemeAsset) ? theme_assets_to_json(@js_and_css_assets).html_safe : 'null'}, js_and_css_assets: #{can?(:manage, Locomotive::ThemeAsset) ? theme_assets_to_json(@js_and_css_assets) : 'null'},
fonts: #{j can?(:manage, Locomotive::ThemeAsset) ? theme_assets_to_json(@assets[:fonts]).html_safe : 'null'} fonts: #{can?(:manage, Locomotive::ThemeAsset) ? theme_assets_to_json(@assets[:fonts]) : 'null'}
- content_for :submenu do - content_for :submenu do
= render_cell 'locomotive/settings_menu', :show = render_cell 'locomotive/settings_menu', :show

View File

@ -1,2 +1,2 @@
Haml::Template.options[:format] = :html5 Haml::Template.options[:format] = :html5
Haml::Template.options[:ugly] = true # improve performance in dev Haml::Template.options[:ugly] = true # improve performance in dev

View File

@ -1,26 +1,5 @@
de: de:
locomotive: locomotive:
errors:
"500":
title: Anwendungs-Fehler
notice: "Entschuldigung, irgendetwas ist hier schief gelaufen."
link: "&rarr; Zurück zur Anwendung"
"404":
title: Seite nicht gefunden
notice: "Die angefragte Seite existiert nicht."
link: "&rarr; Zurück zur Anwendung"
locales:
en: Englisch
de: Deutsch
fr: Französisch
pt-BR: "Bras. Portugiesisch"
it: Italienisch
nl: Niederländisch
nb: Norwegisch
es: Spanisch
ru: Russisch
buttons: buttons:
login: Einloggen login: Einloggen
send_password: Senden send_password: Senden
@ -30,9 +9,19 @@ de:
delete: "Löschen" delete: "Löschen"
close: "Schließen" close: "Schließen"
locales:
en: Englisch
de: Deutsch
fr: Französisch
pt-BR: "Bras. Portugiesisch"
it: Italienisch
nl: Niederländisch
"no": Norwegisch
es: Spanisch
ru: Russisch
messages: messages:
confirm: Sind Sie sicher ? confirm: Sind Sie sicher ?
sending_form: "Formular wird gesendet"
shared: shared:
header: header:
@ -50,10 +39,8 @@ de:
account: Mein Zugang account: Mein Zugang
site: Webseite site: Webseite
theme_assets: Dateien theme_assets: Dateien
list:
untranslated: "Nicht übersetzt"
form: form:
change_file: ändern change_file: Ändern
delete_file: Löschen delete_file: Löschen
cancel: Abbrechen cancel: Abbrechen
form_actions: form_actions:
@ -61,14 +48,24 @@ de:
create: Neu create: Neu
update: Speichern update: Speichern
send: Senden send: Senden
disable_with: "Transfer..." disable_with: "locomotive.disable_with.form_actions"
footer: footer:
who_is_behind: "LocomitveCMS - entwickelt von %{development} und entworfen von <a href=\"http://www.sachagreif.com\">Sacha Greif</a> &mdash; <small>version</small> %{version}" who_is_behind: "Dienst entwickelt von %{development} und entworfen von <a href=\"http://www.sachagreif.com\">Sacha Greif</a> &mdash; <small>version</small> %{version}"
errors:
"500":
title: Anwendungs-Fehler
notice: "Entschuldigung, irgendetwas ist hier schief gelaufen."
link: "&rarr; Zurück zur Anwendung"
"404":
title: Seite nicht gefunden
notice: "Die angefragte Seite existiert nicht."
link: "&rarr; Zurück zur Anwendung"
notifications: notifications:
new_content_entry: new_content_entry:
subject: "[%{type}] neu" subject: "[%{type}] neu"
title: "Hi %{name}, nur damit Sie Bescheid wissen, am %{date} wurde eine neue Instanz erstellt." title: "Hi %{name}, nur damit Sie Bescheid wissen! Am %{date} wurde folgende neue Instanz erstellt."
type: "Model: %{type}" type: "Model: %{type}"
sites_picker: sites_picker:
@ -160,16 +157,16 @@ de:
sites: sites:
new: new:
title: Neue Webseite title: Neuer Webseite
help: "Füllen Sie das folgende Formular aus, um eine neue Webseite zu erstellen." help: "Fülle das folgende Formular aus, um einen neuen Webseiteen zu erstellen."
domains: domains:
empty: "Bisher sind keine Domains/Hostnamen an diese Seite gebunden. Wenn Sie unten Domains/Hostnamen angeben, achten Sie bitte darauf <b>Ihren DNS Server zu prüfen/aktualisieren.</b>" empty: "Bisher sind keine Domains/Hostnamen an diese Seite gebunden. Wenn Sie unten Domains/Hostnamen angeben, achten Sie bitte darauf <b>Ihren DNS Server zu prüfen/aktualisieren.</b>"
current_site: current_site:
edit: edit:
new_membership: Account hinzufügen new_membership: Account hinzufügen
help: "Der Name der Webseiten kann durch einen Klick auf den Namen bearbeitet werden." help: "Der Name des Webseiteen kann durch einen Klick auf den Namen bearbeitet werden."
ask_for_name: "Bitte geben Sie den neuen Namen der Webseite ein" ask_for_name: "Bitte geben Sie den neuen Namen der Webseite an"
memberships: memberships:
roles: roles:
@ -198,11 +195,10 @@ de:
new: neue Datei new: neue Datei
snippets: Snippets snippets: Snippets
css_and_js: Style und Javascript css_and_js: Style und Javascript
fonts: Fonts
images: Bilder images: Bilder
media: Medien media: Medien
fonts: Fonts
no_items: "Momentan gibt es keine Dateien. Klicken Sie einfach <a href='%{url}'>hier</a>, um die erste Datei zu erstellen." no_items: "Momentan gibt es keine Dateien. Klicken Sie einfach <a href='%{url}'>hier</a>, um die erste Datei zu erstellen."
quick_upload: Schneller Upload
asset: asset:
updated_at: Aktualisiert am updated_at: Aktualisiert am
new: new:
@ -295,15 +291,13 @@ de:
explanations: "Es ist fast geschafft. Bitte geben Sie Ihrer ersten Webseite einen Namen und wählen Sie eine Sprache aus." explanations: "Es ist fast geschafft. Bitte geben Sie Ihrer ersten Webseite einen Namen und wählen Sie eine Sprache aus."
default_site_locale: Sprachauswahl default_site_locale: Sprachauswahl
default_site_locales_hints: Sie können später weitere Sprachen im Einstellungsdialog vornehmen. default_site_locales_hints: Sie können später weitere Sprachen im Einstellungsdialog vornehmen.
next: Webseite erstellen next: Webseite erstellen
back_to_default_template: "Klicken Sie <a href='#'>hier</a> um die Standardeinstellungen wieder herzustellen"
public: public:
pages: pages:
show_toolbar: show_toolbar:
statuses: statuses:
loading: "Laden..." loading: "Lade...."
disabled: "Inline Editor deaktiviert" disabled: "Inline Editor deaktiviert"
labels: labels:
save_changes: "Änderungen speichern: " save_changes: "Änderungen speichern: "

View File

@ -16,7 +16,7 @@ en:
pt-BR: "Brazilian Portuguese" pt-BR: "Brazilian Portuguese"
it: Italian it: Italian
nl: Dutch nl: Dutch
nb: Norwegian "no": Norwegian
es: Spanish es: Spanish
ru: Russian ru: Russian

View File

@ -20,7 +20,6 @@ es:
messages: messages:
confirm: Por favor confirme confirm: Por favor confirme
sending_form: "locomotive.messages.sending_form"
shared: shared:
header: header:
@ -166,7 +165,7 @@ es:
pt-BR: "Portugués (Brasil)" pt-BR: "Portugués (Brasil)"
it: Italiano it: Italiano
nl: holandés nl: holandés
nb: Noruego "no": Noruego
es: Español es: Español
ru: Ruso ru: Ruso
ask_for_name: "Por favor escriba su nuevo nombre" ask_for_name: "Por favor escriba su nuevo nombre"

View File

@ -17,7 +17,7 @@ fr:
pt-BR: "Portugais" pt-BR: "Portugais"
it: "Italien" it: "Italien"
nl: "Hollandais" nl: "Hollandais"
nb: "Norvégien" "no": "Norvégien"
es: Espagnol es: Espagnol
ru: Russe ru: Russe

View File

@ -10,7 +10,6 @@ it:
messages: messages:
confirm: Sicuro? confirm: Sicuro?
sending_form: "locomotive.messages.sending_form"
shared: shared:
header: header:
@ -166,7 +165,7 @@ it:
pt-BR: "Portoghese Brasiliano" pt-BR: "Portoghese Brasiliano"
it: Italiano it: Italiano
nl: Olandese nl: Olandese
nb: Norvegese "no": Norvegese
es: Spagnolo es: Spagnolo
ru: Russo ru: Russo
ask_for_name: "Prego, digita il tuo nome" ask_for_name: "Prego, digita il tuo nome"

View File

@ -9,7 +9,6 @@ nl:
messages: messages:
confirm: Weet u het zeker ? confirm: Weet u het zeker ?
sending_form: "locomotive.messages.sending_form"
shared: shared:
header: header:
@ -154,7 +153,7 @@ nl:
pt-BR: "Braziliaans Portugees" pt-BR: "Braziliaans Portugees"
it: Italiaans it: Italiaans
nl: Nederlands nl: Nederlands
nb: Noors "no": Noors
ru: Russisch ru: Russisch
ask_for_name: "Voer uw nieuwe naam in" ask_for_name: "Voer uw nieuwe naam in"

View File

@ -1,4 +1,4 @@
nb: "no":
locomotive: locomotive:
buttons: buttons:
login: Logg inn login: Logg inn
@ -6,23 +6,10 @@ nb:
change_password: Endre change_password: Endre
new_item: "+ ny" new_item: "+ ny"
switch_to_site: Vis switch_to_site: Vis
delete: Slett delete: "Slett"
close: Lukk
locales:
en: Engelsk
de: Tysk
fr: Fransk
pt-BR: "Brazilian Portuguese"
it: Italiensk
nl: Nederlandsk
nb: Norsk
es: Spansk
ru: Russisk
messages: messages:
confirm: Er du sikker? confirm: Er du sikker?
sending_form: Skjemaet blir sendt
shared: shared:
header: header:
@ -40,20 +27,14 @@ nb:
account: Min konto account: Min konto
site: Siden site: Siden
theme_assets: Temafiler theme_assets: Temafiler
form: footer:
change_file: Endre who_is_behind: "Tjenesten utviklet av %{development} og designet av <a href=\"http://www.sachagreif.com\">Sacha Greif</a>"
delete_file: Slett
cancel: Avbryt
form_actions: form_actions:
back: Tilbake uten å lagre back: Tilbake uten å lagre
create: Opprett create: Opprett
update: Lagre update: Lagre
send: Send send: Send
disable_with: "Vent litt.." disable_with: "locomotive.disable_with.form_actions"
list:
untranslated: ikke oversatt
footer:
who_is_behind: "LocomotiveCMS er utviklet av %{development} og designet av <a href=\"http://www.sachagreif.com\">Sacha Greif</a> &mdash; <small>versjon</small> %{version}"
errors: errors:
"500": "500":
@ -85,16 +66,9 @@ nb:
delete_file: Slett fil delete_file: Slett fil
has_many: has_many:
empty: Tom empty: Tom
new_entry: + Legg til ny index:
many_to_many: is_required: er nødvendig
empty: Listen er tom. Legg til ny fra listen nedenfor.
form:
required: Nødvendig
optional: Valgfri
default_label: Feltnavn default_label: Feltnavn
select_options:
ask_name: "Skriv inn etiketten for dette valget"
sessions: sessions:
new: new:
@ -131,9 +105,7 @@ nb:
help: "Tittelen til siden kan oppdateres ved å klikke på den. For å lagre endringene, klikk på \"Lagre\" -knappen." help: "Tittelen til siden kan oppdateres ved å klikke på den. For å lagre endringene, klikk på \"Lagre\" -knappen."
ask_for_title: "Endre tittelen" ask_for_title: "Endre tittelen"
form: form:
change_file: endre delete_file: Slett fil
delete_file: slett fil
cancel: avbryt
default_block: Standard default_block: Standard
cache_strategy: cache_strategy:
none: Ingen none: Ingen
@ -162,14 +134,14 @@ nb:
new: new:
title: Ny nettside title: Ny nettside
help: "Fyll ut skjemaet nedenfor for å opprette en ny nettside." help: "Fyll ut skjemaet nedenfor for å opprette en ny nettside."
domains:
empty: "Det er ingen domener tilknyttet denne siden ennå. Legg til domenene dine nedenfor. <b>Ikke glem å oppdatere DNS-pekerene.</b>"
current_site: current_site:
edit: edit:
new_membership: legg til konto export: eksporter
import: importer
new_membership: nytt medlemskap
help: "Navnet på siden kan oppdateres ved å trykke på det. For å lagre endringen, trykk på \"Lagre\" -knappen." help: "Navnet på siden kan oppdateres ved å trykke på det. For å lagre endringen, trykk på \"Lagre\" -knappen."
ask_for_name: "Skriv inn det nye navnet" ask_for_name: "Rediger navnet"
memberships: memberships:
roles: roles:
@ -189,13 +161,21 @@ nb:
edit: edit:
help: "Navnet ditt kan endres ved å trykke på det. For å lagre endringen, trykk på \"Lagre\" -knappen." help: "Navnet ditt kan endres ved å trykke på det. For å lagre endringen, trykk på \"Lagre\" -knappen."
new_site: ny nettside new_site: ny nettside
en: Engelsk
de: Tysk
fr: Fransk
pt-BR: "Brasiliansk Portugisisk"
it: Italiensk
nl: Nederlandsk
"no": Norsk
es: Spansk
ru: Russisk
ask_for_name: "Rediger navnet ditt" ask_for_name: "Rediger navnet ditt"
theme_assets: theme_assets:
index: index:
title: Temafiler title: Temafiler
help: "I denne seksjonen kan du håndtere alle layout-relaterte filer. Hvis du trenger et bildegalleri så opprett en ny innholdstype i stedet.<br/><b>Advarsel:</b> hvis det er enkelte filer du ikke ser så kan dette skyldes manglende rettigheter." help: "I denne seksjonen kan du håndtere alle layout-relaterte filer. Hvis du trenger et bildegalleri så opprett en ny innholdstype i stedet.<br/><b>Advarsel:</b> hvis det er enkelte filer du ikke ser så kan dette skyldes manglende rettigheter."
quick_upload: Hurtigopplasting
new: ny fil new: ny fil
snippets: HTML-snutter snippets: HTML-snutter
css_and_js: Stilark og javascript css_and_js: Stilark og javascript
@ -218,29 +198,29 @@ nb:
picker_link: Sett inn en fil i koden picker_link: Sett inn en fil i koden
choose_file: Velg fil choose_file: Velg fil
choose_plain_text: Velg klartekst choose_plain_text: Velg klartekst
image_picker: images:
title: "Sett inn bilde" title: Bilder
no_items: "Det finnes ingen bilder foreløpig." no_items: "Det er ingen filer her ennå."
upload: "Last opp bilder"
content_assets: assets:
picker: new:
title: "Sett inn media" title: New asset
no_items: "Det finnes ingen media foreløpig." help: "Fill in the form below to create your asset."
upload: "Last opp media" edit:
title: Edit asset
help: "Fill in the form below to update your asset."
content_types: content_types:
index: index:
new: Ny modell new: Ny modell
edit: Rediger modell
new: new:
title: Ny modell title: Ny modell
help: "Lag din egen datamodell (Prosjekter, Ansatte, ...etc). Modellen må ha minst ett felt. Det første feltet vil være obligatorisk for elementer som opprettes av denne innholdstypen." help: "Lag din egen datamodell (Prosjekter, Ansatte, ...etc). Modellen må ha minst ett felt. Det første feltet vil være obligatorisk for elementer som opprettes av denne innholdstypen."
edit: edit:
title: Redigerer modell title: Rediger modellen
help: "Modellen må ha minst ett felt. Det første feltet vil være obligatorisk for elementer som opprettes av denne innholdstypen." help: "Modellen må ha minst ett felt. Det første feltet vil være obligatorisk for elementer som opprettes av denne innholdstypen."
show_entries: vis elementer show_items: vis elementer
new_entry: nytt element new_item: nytt element
form: form:
order_by: order_by:
created_at: 'Etter dato opprettet' created_at: 'Etter dato opprettet'
@ -261,7 +241,7 @@ nb:
latest_entries: "Siste elementer" latest_entries: "Siste elementer"
updated_at: "Sist oppdatert" updated_at: "Sist oppdatert"
list: list:
no_entries: "Det finnes ingen elementer her ennå. Klikk <a href=\"%{url}\">her</a> for å opprette det første." no_entries: "Det har ikke blitt opprettet noen elementer her ennå. Klikk <a href=\"%{url}\">her</a> for å opprette det første."
new: new:
title: '%{type} &mdash; nytt element' title: '%{type} &mdash; nytt element'
edit: edit:
@ -278,6 +258,25 @@ nb:
title: Cross-domain authentication title: Cross-domain authentication
notice: Du blir sendt videre til nettsiden i løpet av noen få sekunder. notice: Du blir sendt videre til nettsiden i løpet av noen få sekunder.
import:
new:
title: Importer en mal for siden
help: "Be careful when you upload a new template for your existing website, your current data could be modified or even removed."
help: "Vær forsiktig hvis du laster opp en ny mal til en ekisterende side. Dataene dine kan bli slettet eller endret."
show:
title: Import pågår
help: "Your site is being updated from the theme zip file you have just uploaded. It lasts a couple of seconds."
help: "Siden blir oppdatert fra temafilen som ble lastet opp. Dette vil ta noen sekunder."
steps:
site: Sideinformasjon
content_types: Tilpassede innholdstyper
assets: Temafiler
snippets: HTML-snutter
pages: Sider
messages:
success: "Importen var velykket og siden har blitt oppdatert."
failure: "Importen kunne ikke gjennomføres."
installation: installation:
common: common:
title: Locomotive førstegangsoppsett title: Locomotive førstegangsoppsett
@ -293,21 +292,5 @@ nb:
step_2: step_2:
title: "Steg 2/2 &mdash; Lag din første nettside" title: "Steg 2/2 &mdash; Lag din første nettside"
explanations: "Hvis du allerede har lastet opp standardmalen (se instruksjoner), så kan du bruke denne med en gang. Du kan også laste opp en sidemal som en zip-fil (gratis maler finnes <a href=\"http://www.locomotivecms.com/support/themes\">her</a>)." explanations: "Hvis du allerede har lastet opp standardmalen (se instruksjoner), så kan du bruke denne med en gang. Du kan også laste opp en sidemal som en zip-fil (gratis maler finnes <a href=\"http://www.locomotivecms.com/support/themes\">her</a>)."
default_site_locale: Språk back_to_default_template: "Trykk <a href='#'>her</a> for å velge standardmalen i stedet"
default_site_locales_hints: Du kan legge til flere språk under Innstilinger senere
next: Opprett side next: Opprett side
public:
pages:
show_toolbar:
statuses:
loading: "Vent litt...."
disabled: "Inline Editor disabled"
labels:
save_changes: "Lagre endringer: "
editing_mode: "Redigeringsmodus: "
lang: "Språk: "
buttons:
back: Tilbake til admin-siden
confirm: Bekreft
cancel: Avbryt

View File

@ -9,7 +9,6 @@ pt-BR:
messages: messages:
confirm: Você tem certeza ? confirm: Você tem certeza ?
sending_form: "locomotive.messages.sending_form"
shared: shared:
header: header:
@ -152,7 +151,7 @@ pt-BR:
pt-BR: "Português do Brasil" pt-BR: "Português do Brasil"
it: Italiano it: Italiano
nl: Holandês nl: Holandês
nb: Norueguês "no": Norueguês
es: Espanhol es: Espanhol
ru: Russo ru: Russo
ask_for_name: "Por favor preencha o novo nome" ask_for_name: "Por favor preencha o novo nome"

View File

@ -16,7 +16,7 @@ ru:
pt-BR: "Браз. - Португальский" pt-BR: "Браз. - Португальский"
it: Итальянский it: Итальянский
nl: Голландский nl: Голландский
nb: Норвежский "no": Норвежский
es: Испанский es: Испанский
ru: Русский ru: Русский

View File

@ -1,4 +1,4 @@
nb: "no":
carrierwave: carrierwave:
errors: errors:
integrity: 'er ikke en tillatt filtype.' integrity: 'er ikke en tillatt filtype.'

View File

@ -34,13 +34,10 @@ de:
array_too_short: "ist zu kurz (minimale Element-Zahl ist %{count})" array_too_short: "ist zu kurz (minimale Element-Zahl ist %{count})"
liquid_syntax: "Liquid Syntax-Fehler, bitte überprüfe die Syntax ('%{error}')" liquid_syntax: "Liquid Syntax-Fehler, bitte überprüfe die Syntax ('%{error}')"
invalid_theme_file: "darf nicht leer sein oder ist keine zip-Datei" invalid_theme_file: "darf nicht leer sein oder ist keine zip-Datei"
security: "stellt ein Sicherheitproblem dar"
site:
default_locale_removed: Die vorige Standard-Spracheinstellung kann noch nicht gelöscht werden
page: page:
liquid_syntax: "Liquid Syntax-Fehler, bitte überprüfe die Syntax ('%{error}'/'%{fullpath}')" liquid_syntax: "Liquid Syntax-Fehler, bitte überprüfe die Syntax ('%{error}'/'%{fullpath}')"
liquid_extend: "Die Seite '%{fullpath}' verwendet eine Vorlage, die gar nicht existiert" liquid_extend: "Die Seite '%{fullpath}' verwendet eine Vorlage, die gar nicht existiert"
liquid_translation: "Die Seite '%{fullpath}' erweitert eine Vorlage die noch nicht übersetzt wurde"
attributes: attributes:
defaults: defaults:
@ -55,24 +52,17 @@ de:
body: "{% extends 'parent' %}" body: "{% extends 'parent' %}"
mongoid: mongoid:
errors:
messages:
blank_on_locale: "darf nicht leer sein"
attributes: attributes:
page: page:
title: Titel title: Titel
parent: Elternprozess parent: Parent
pared_id: Elternprozess
slug: Slug slug: Slug
listed: Im Menü wildcard: Wildcard
templatized: Templatized
published: Veröffentlicht published: Veröffentlicht
listed: Im Menü
redirect: Umleitung redirect: Umleitung
redirect_url: Umleitungs-URL redirect_url: Umleitungs-URL
cache_strategy: Cache cache_strategy: Cache
response_type: Antworttyp
seo_title: SEO-Titel
content_type: content_type:
name: Name name: Name
description: Beschreibung description: Beschreibung

View File

@ -3,11 +3,6 @@ en:
formats: formats:
default: "%m/%d/%Y" default: "%m/%d/%Y"
mongoid:
errors:
messages:
blank_on_locale: "can't be blank"
errors: errors:
messages: messages:
domain_taken: "%{value} is already taken" domain_taken: "%{value} is already taken"

View File

@ -58,7 +58,7 @@ es:
parent_id: Padre parent_id: Padre
slug: Enlace slug: Enlace
listed: Menu listed: Menu
templatized: Templatizada wildcard: Wildcard
published: Publicada published: Publicada
redirect: Redirección redirect: Redirección
redirect_url: Url de redirección redirect_url: Url de redirección

View File

@ -53,10 +53,6 @@ fr:
body: "{% extends 'parent' %}" body: "{% extends 'parent' %}"
mongoid: mongoid:
errors:
messages:
blank_on_locale: "doit être rempli(e)"
attributes: attributes:
locomotive/page: locomotive/page:
title: Titre title: Titre
@ -64,7 +60,7 @@ fr:
parent_id: Dossier parent parent_id: Dossier parent
slug: Raccourci slug: Raccourci
listed: Menu listed: Menu
templatized: Templatisée wildcard: Wildcard
published: Publiée published: Publiée
redirect: Redirection redirect: Redirection
redirect_url: Url de redirection redirect_url: Url de redirection

View File

@ -64,7 +64,7 @@ it:
parent_id: Pagina superiore parent_id: Pagina superiore
slug: Slug slug: Slug
listed: In menù listed: In menù
templatized: Templatized wildcard: Wildcard
published: Pubblicata published: Pubblicata
redirect: Redirezione redirect: Redirezione
redirect_url: Url di redirezione redirect_url: Url di redirezione

View File

@ -1,46 +1,4 @@
nb: "no":
date:
formats:
default: "%d.%m.%Y"
mongoid:
errors:
messages:
blank_on_locale: "må fylles ut"
errors:
messages:
domain_taken: "%{value} er alerede tatt"
invalid_domain: "%{value} er ugyldig"
needs_admin_account: "Det må være minst en admin-konto"
protected_page: "Du kan ikke fjerne index eller 404 sidene"
extname_changed: "Den nye filen har ikke det opprinnelige filetternavnet"
array_too_short: "er for liten (minimum elementnummer er %{count})"
invalid_theme_file: "må være en zip-fil"
site:
default_locale_removed: Forrige standardspråk kan ikke fjernes før nytt er valgt.
page:
liquid_syntax: "Liquid Syntax error ('%{error}' on '%{fullpath}')"
liquid_extend: "The page '%{fullpath}' extends a template which does not exist"
liquid_translation: "The page '%{fullpath}' extends a template which is not translated"
too_few_custom_fields: "At least, one custom field is required"
security: "presents a security problem"
attributes:
defaults:
pages:
index:
title: "Startside"
body: "Startsidens innholds"
"404":
title: "Siden finnes ikke"
body: "Sidens innhold"
other:
body: "{% extends 'parent' %}"
pagination:
previous: "&laquo; Previous"
next: "Next &raquo;"
support: support:
array: array:
words_connector: ", " words_connector: ", "
@ -263,7 +221,7 @@ nb:
parent: Tilhører parent: Tilhører
parent_id: Tilhører parent_id: Tilhører
slug: Slug slug: Slug
templatized: Templatized wildcard: Wildcard
published: Publisert published: Publisert
listed: I meny listed: I meny
redirect: Videresending redirect: Videresending

View File

@ -60,7 +60,7 @@ pt-BR:
title: Título title: Título
parent: Pai parent: Pai
slug: Slug slug: Slug
templatized: Template wildcard: Wildcard
published: Publicado published: Publicado
cache_strategy: Cache cache_strategy: Cache
content_type: content_type:

View File

@ -35,7 +35,7 @@ ru:
title: Имя title: Имя
parent: Родитель parent: Родитель
slug: Ссылка slug: Ссылка
templatized: Шаблонизирована wildcard: Wildcard
published: Опубликована published: Опубликована
listed: Меню listed: Меню
redirect: Перенаправлена redirect: Перенаправлена
@ -89,7 +89,7 @@ ru:
default: "%d.%m.%Y" default: "%d.%m.%Y"
short: "%d %b" short: "%d %b"
long: "%d %B %Y" long: "%d %B %Y"
# Названия дней недели -- контекстные и отдельностоящие # Названия дней недели -- контекстные и отдельностоящие
day_names: [воскресенье, понедельник, вторник, среда, четверг, пятница, суббота] day_names: [воскресенье, понедельник, вторник, среда, четверг, пятница, суббота]
standalone_day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота] standalone_day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
@ -97,19 +97,19 @@ ru:
# Названия месяцев -- сокращенные и полные, плюс отдельностоящие. # Названия месяцев -- сокращенные и полные, плюс отдельностоящие.
# Не забудьте nil в начале массиве (~) # Не забудьте nil в начале массиве (~)
# #
# #
# Don't forget the nil at the beginning; there's no such thing as a 0th month # Don't forget the nil at the beginning; there's no such thing as a 0th month
month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря] month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря]
standalone_month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь] standalone_month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
abbr_month_names: [~, янв., февр., марта, апр., мая, июня, июля, авг., сент., окт., нояб., дек.] abbr_month_names: [~, янв., февр., марта, апр., мая, июня, июля, авг., сент., окт., нояб., дек.]
standalone_abbr_month_names: [~, янв., февр., март, апр., май, июнь, июль, авг., сент., окт., нояб., дек.] standalone_abbr_month_names: [~, янв., февр., март, апр., май, июнь, июль, авг., сент., окт., нояб., дек.]
# Порядок компонентов даты для хелперов # Порядок компонентов даты для хелперов
# #
# #
# Used in date_select and datime_select. # Used in date_select and datime_select.
order: order:
- :day - :day
- :month - :month
- :year - :year
@ -120,7 +120,7 @@ ru:
default: "%a, %d %b %Y, %H:%M:%S %z" default: "%a, %d %b %Y, %H:%M:%S %z"
short: "%d %b, %H:%M" short: "%d %b, %H:%M"
long: "%d %B %Y, %H:%M" long: "%d %B %Y, %H:%M"
# am/pm решено перевести как "утра/вечера" :) # am/pm решено перевести как "утра/вечера" :)
am: "утра" am: "утра"
pm: "вечера" pm: "вечера"
@ -138,7 +138,7 @@ ru:
delimiter: " " delimiter: " "
# Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00) # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
precision: 3 precision: 3
# Used in number_to_currency() # Used in number_to_currency()
currency: currency:
format: format:
@ -152,14 +152,14 @@ ru:
separator: "." separator: "."
delimiter: " " delimiter: " "
precision: 2 precision: 2
# Used in number_to_percentage() # Used in number_to_percentage()
percentage: percentage:
format: format:
# These three are to override number.format and are optional # These three are to override number.format and are optional
# separator: # separator:
delimiter: "" delimiter: ""
# Used in number_to_precision() # Used in number_to_precision()
precision: precision:
format: format:
@ -167,18 +167,18 @@ ru:
# separator: # separator:
delimiter: "" delimiter: ""
# precision: # precision:
# Used in number_to_human_size() # Used in number_to_human_size()
human: human:
format: format:
# These three are to override number.format and are optional # These three are to override number.format and are optional
# separator: # separator:
delimiter: "" delimiter: ""
precision: 1 precision: 1
# Rails 2.2 # Rails 2.2
# storage_units: [байт, КБ, МБ, ГБ, ТБ] # storage_units: [байт, КБ, МБ, ГБ, ТБ]
# Rails 2.3 # Rails 2.3
storage_units: storage_units:
# Storage units output formatting. # Storage units output formatting.
@ -272,7 +272,7 @@ ru:
# Rails 2.2 # Rails 2.2
sentence_connector: "и" sentence_connector: "и"
skip_last_comma: true skip_last_comma: true
# Rails 2.3 # Rails 2.3
words_connector: ", " words_connector: ", "
two_words_connector: " и " two_words_connector: " и "

View File

@ -1,4 +1,4 @@
nb: "no":
errors: errors:
messages: messages:
not_found: "finnes ikke" not_found: "finnes ikke"
@ -7,7 +7,7 @@ nb:
devise: devise:
failure: failure:
locomotive_account: locomotive:
unauthenticated: 'Du må logge inn eller registrere deg før du kan fortsette.' unauthenticated: 'Du må logge inn eller registrere deg før du kan fortsette.'
unconfirmed: 'Kontoen må aktiveres før du kan fortsette.' unconfirmed: 'Kontoen må aktiveres før du kan fortsette.'
locked: 'Brukerkontoen er sperret.' locked: 'Brukerkontoen er sperret.'
@ -17,34 +17,34 @@ nb:
timeout: 'Innloggingen har utløpt. Logg inn på nytt for å fortsette.' timeout: 'Innloggingen har utløpt. Logg inn på nytt for å fortsette.'
inactive: 'Kontoen din er ikke aktivert ennå.' inactive: 'Kontoen din er ikke aktivert ennå.'
sessions: sessions:
locomotive_account: locomotive:
signed_in: 'Du er nå logget inn.' signed_in: 'Du er nå logget inn.'
signed_out: 'Du har blitt logget ut.' signed_out: 'Du har blitt logget ut.'
passwords: passwords:
locomotive_account: locomotive:
send_instructions: 'Du vil motta en epost med instruksjoner for hvordan du kan tilbakestille passordet i løpet av kort tid.' send_instructions: 'Du vil motta en epost med instruksjoner for hvordan du kan tilbakestille passordet i løpet av kort tid.'
updated: 'Passordendringen var vellykket. Du er nå logget inn.' updated: 'Passordendringen var vellykket. Du er nå logget inn.'
confirmations: confirmations:
locomotive_account: locomotive:
send_instructions: 'Du vil motta en epost med instrusksjoner for hvordan brukerkontoen aktiveres i løpet av kort tid.' send_instructions: 'Du vil motta en epost med instrusksjoner for hvordan brukerkontoen aktiveres i løpet av kort tid.'
confirmed: 'Aktiveringen av brukerkontoen var vellykket. Du er nå logget inn.' confirmed: 'Aktiveringen av brukerkontoen var vellykket. Du er nå logget inn.'
registrations: registrations:
locomotive_account: locomotive:
signed_up: 'Registreringen var vellykket.' signed_up: 'Registreringen var vellykket.'
updated: 'Oppdateringen av kontoen var vellykket' updated: 'Oppdateringen av kontoen var vellykket'
destroyed: 'Kontoen din har blitt kansellert. Vi håper å se deg igjen en annen gang.' destroyed: 'Kontoen din har blitt kansellert. Vi håper å se deg igjen en annen gang.'
unlocks: unlocks:
locomotive_account: locomotive:
send_instructions: 'Du vil motta en epost med instruksjoner for hvordan du kan åpne kontoen i løpet av kort tid.' send_instructions: 'Du vil motta en epost med instruksjoner for hvordan du kan åpne kontoen i løpet av kort tid.'
unlocked: 'Kontoen har blitt åpnet og du er nå logget inn.' unlocked: 'Kontoen har blitt åpnet og du er nå logget inn.'
mailer: mailer:
locomotive_account: locomotive:
confirmation_instructions: 'Bekreftelsesinstrukser' confirmation_instructions: 'Bekreftelsesinstrukser'
reset_password_instructions: 'Instrukser for tilbakestilling av passord' reset_password_instructions: 'Instrukser for tilbakestilling av passord'
unlock_instructions: 'Instrukser for åpning' unlock_instructions: 'Instrukser for åpning'
locomotive_account: locomotive:
mailer: mailer:
common: common:
hello: Hallo hello: Hallo

View File

@ -1,4 +1,4 @@
nb: "no":
flash: flash:
locomotive: locomotive:
pages: pages:

View File

@ -55,9 +55,7 @@ de:
page: page:
published: "Nur authentifizierte Accounts können nicht publizierte Seiten ansehen." published: "Nur authentifizierte Accounts können nicht publizierte Seiten ansehen."
cache_strategy: "Cache die Seiten, um eine bessere Geschwindigkeit zu erzielen. Die 'Einfach' Option ist ein guter Kompromiss." cache_strategy: "Cache die Seiten, um eine bessere Geschwindigkeit zu erzielen. Die 'Einfach' Option ist ein guter Kompromiss."
templatized: "Nutze diese Seite als Vorlage für einen Baustein, den du erstellt hast."
listed: "Regele, ob die Seite in den generierten Menüs angezeigt werden soll." listed: "Regele, ob die Seite in den generierten Menüs angezeigt werden soll."
content_type_id: "Der Baustein für den diese Seite als Vorlage dienen soll."
seo_title: "Wähle einen Titel für den 'title' Tag im Seiten Header. Lass es leer, wenn der Seitentitel verwendet werden soll." seo_title: "Wähle einen Titel für den 'title' Tag im Seiten Header. Lass es leer, wenn der Seitentitel verwendet werden soll."
meta_keywords: "Meta-Schlagworte, die im HEAD-Bereich der Webseite genutzt werden. Die einzelnen Wörter werden durch eine Leertaste getrennt. Diese werden für die Suchmaschinen benötigt." meta_keywords: "Meta-Schlagworte, die im HEAD-Bereich der Webseite genutzt werden. Die einzelnen Wörter werden durch eine Leertaste getrennt. Diese werden für die Suchmaschinen benötigt."
meta_description: "Meta-Beschreibung, die im HEAD-Bereich der Webseite genutzt wird. Diese wird für die Suchmaschinen benötigt." meta_description: "Meta-Beschreibung, die im HEAD-Bereich der Webseite genutzt wird. Diese wird für die Suchmaschinen benötigt."

View File

@ -57,9 +57,8 @@ en:
handle: "Unique identifier to retrieve this page within an external controller instance" handle: "Unique identifier to retrieve this page within an external controller instance"
published: "Only authenticated accounts can view unpublished pages." published: "Only authenticated accounts can view unpublished pages."
cache_strategy: "Cache the page for better performance. The 'Simple' choice is a good compromise." cache_strategy: "Cache the page for better performance. The 'Simple' choice is a good compromise."
templatized: "Use the page as a template for a model you defined." wildcard: "Make the page have a wildcard segment in its path. Then the slug will be used as the name of the wildcard in the template"
listed: "Control whether to show the page from generated menus." listed: "Control whether to show the page from generated menus."
target_klass_name: "The type of content this page will be a template for."
seo_title: "Define a page title which should be used as the value for the title tag in the head section. Leave it empty if you want to use the default value from the site settings." seo_title: "Define a page title which should be used as the value for the title tag in the head section. Leave it empty if you want to use the default value from the site settings."
meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma." meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma."
meta_description: "Overrides the site's meta description used within the head tag of the page." meta_description: "Overrides the site's meta description used within the head tag of the page."
@ -84,7 +83,7 @@ en:
source: "The current file is available here %{url}" source: "The current file is available here %{url}"
content_entry: content_entry:
_slug: "Property used to generate the url of a page working as a template for this content type (ex: \"template_page/{{ your_object._permalink }})\"." _slug: "Property used to generate the url of a page working as a template for this content type (ex: \"template_page/{{ your_object._permalink }})\"."
seo_title: "The value you fill in will replace the SEO title of the templatized page related to your model." seo_title: "The value you fill in can be used to replace the SEO title in any pages."
meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma." meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma."
meta_description: "Overrides the site's meta description used within the head tag of the page." meta_description: "Overrides the site's meta description used within the head tag of the page."
import: import:

View File

@ -49,9 +49,7 @@ es:
page: page:
published: "Las páginas no publicadas son únicamente visibles tras iniciar sesión." published: "Las páginas no publicadas son únicamente visibles tras iniciar sesión."
cache_strategy: "Utilizar una caché de página para un mejor rendimiento. La opción 'Simple' es un buen compromiso." cache_strategy: "Utilizar una caché de página para un mejor rendimiento. La opción 'Simple' es un buen compromiso."
templatized: "Usar la página como plantilla de un modelo."
listed: "Controla si la página se enseña o no en los menús." listed: "Controla si la página se enseña o no en los menús."
content_type_id: "El modelo del cual será una plantilla esta página."
meta_keywords: "Reescribir las palabras clave SEO utilizadas en la cabecera de la página. Deben estar separadas por comas." meta_keywords: "Reescribir las palabras clave SEO utilizadas en la cabecera de la página. Deben estar separadas por comas."
meta_description: "Reescribir la metadescripción que se utiliza en la cabecera de la página." meta_description: "Reescribir la metadescripción que se utiliza en la cabecera de la página."
snippet: snippet:

View File

@ -53,9 +53,8 @@ fr:
page: page:
published: "Seuls les administrateurs authentifiés peuvent voir une page non publiée." published: "Seuls les administrateurs authentifiés peuvent voir une page non publiée."
cache_strategy: "Cache la page pour de meilleure performance. L'option 'Simple' est le meilleur compromis." cache_strategy: "Cache la page pour de meilleure performance. L'option 'Simple' est le meilleur compromis."
templatized: "Utilise la page comme un template pour un modèle défini." wildcard: "Détermine si la page aura la dernière partie de son URL dynamique. Si oui, le slug sera utilisé comme nom du segment dans le template."
listed: "Controle si la page doit être visible depuis les menus automatiquement générés." listed: "Controle si la page doit être visible depuis les menus automatiquement générés."
target_klass_name: "Le type du contenu pour lequel cette page est un template."
seo_title: "Définit un titre de page à mettre dans la balise TITLE de la page. Laissez le blanc pour utiliser la valeur par défaut (voir configuration du site)." seo_title: "Définit un titre de page à mettre dans la balise TITLE de la page. Laissez le blanc pour utiliser la valeur par défaut (voir configuration du site)."
meta_keywords: "Redéfinit les mots-clés du site. Utilisés à l'intérieur de la balise HEAD. Ils sont séparés par une virgule." meta_keywords: "Redéfinit les mots-clés du site. Utilisés à l'intérieur de la balise HEAD. Ils sont séparés par une virgule."
meta_description: "Redéfinit la description du site. Utilisée à l'intérieur de la balise HEAD." meta_description: "Redéfinit la description du site. Utilisée à l'intérieur de la balise HEAD."

View File

@ -55,9 +55,7 @@ it:
page: page:
published: "Solo gli account autenticati possono visualizzare le pagine non pubblicate." published: "Solo gli account autenticati possono visualizzare le pagine non pubblicate."
cache_strategy: "Attiva il cache della pagina per miglirare le prestazioni. L'opzione 'Semplice' è un buon compromesso." cache_strategy: "Attiva il cache della pagina per miglirare le prestazioni. L'opzione 'Semplice' è un buon compromesso."
templatized: "Utilizzare la pagina come template per un modello che hai definito."
listed: "Determina se la pagina deve essere mostrata nei menù generati." listed: "Determina se la pagina deve essere mostrata nei menù generati."
content_type_id: "Il tipo di contenuto di cui questa pagina sarà il template."
seo_title: "Definisce il titolo della pagina inserito nel tag title della sezione head. Lascia vuoto se vuoi che venga utilizzato il titolo definito per il sito." seo_title: "Definisce il titolo della pagina inserito nel tag title della sezione head. Lascia vuoto se vuoi che venga utilizzato il titolo definito per il sito."
meta_keywords: "Sovrascrive per questa pagina le meta keywords definite per il sito all'interno del tag head della pagina. Sono separate da virgola." meta_keywords: "Sovrascrive per questa pagina le meta keywords definite per il sito all'interno del tag head della pagina. Sono separate da virgola."
meta_description: "Sovrascrive per questa pagina la meta description definita per il sito." meta_description: "Sovrascrive per questa pagina la meta description definita per il sito."

View File

@ -49,9 +49,7 @@ nl:
page: page:
published: "Alleen geauthenticeerde accounts kunnen niet gepubliceerde pagina's zien." published: "Alleen geauthenticeerde accounts kunnen niet gepubliceerde pagina's zien."
cache_strategy: "Cache de pagina voor betere prestaties. De 'Simpele' keus is een goed compromis." cache_strategy: "Cache de pagina voor betere prestaties. De 'Simpele' keus is een goed compromis."
templatized: "Gebruik de pagina als template voor een door u gedefinieerd model."
listed: "Controleer of de pagina getoond wordt van de gegenereerde menu's." listed: "Controleer of de pagina getoond wordt van de gegenereerde menu's."
content_type_id: "Het type inhoud waar deze pagina als template voor dient"
meta_keywords: "Overschrijft de meta keywords van de website in de head tag van deze pagina. Gescheiden door een komma" meta_keywords: "Overschrijft de meta keywords van de website in de head tag van deze pagina. Gescheiden door een komma"
meta_description: "Overschrijft de meta description van de website in de head tag van deze pagina." meta_description: "Overschrijft de meta description van de website in de head tag van deze pagina."
snippet: snippet:

View File

@ -1,4 +1,4 @@
nb: "no":
formtastic: formtastic:
titles: titles:
information: Generell informasjon information: Generell informasjon
@ -33,40 +33,35 @@ nb:
custom_fields: custom_fields:
field: field:
name: Alias name: Alias
import:
new:
source: Fil
samples: Kopier testdata
reset: Reset side
default_site_template: "Bruk standardmalen. Klikk <a href='#'>her</a> for å laste opp en mal fra en zip-fil i stedet."
content_type: content_type:
raw_item_template: Elementmal item_template: Elementmal
public_submission_enabled: Kan opprettes utenfra api_accounts: Varslede kontoer
public_submission_accounts: Kontoer som varsles
"custom_fields/field":
select_options: "Valg"
content_entry: content_entry:
_slug: Permalink _slug: Permalink
account: account:
edit: edit:
locale: Språk
password: Nytt passord password: Nytt passord
password_confirmation: Bekreft nytt passord password_confirmation: Bekreft nytt passord
page: page:
seo_title: Tittel seo_title: Tittel
target_klass_name: Modell
site:
locales: Språk
hints: hints:
page: page:
handle: "En unik ID for å hente siden fra en ekstern controller"
published: "Kun autoriserte kontoer kan se ikke-publiserte sider" published: "Kun autoriserte kontoer kan se ikke-publiserte sider"
cache_strategy: "Buffre siden for å bedre ytelsen. \"Enkel\" er et bra kompromiss." cache_strategy: "Buffre siden for å bedre ytelsen. \"Enkel\" er et bra kompromiss."
templatized: "Bruk denne siden som mal for en modell."
listed: "Styr om siden skal vises i de genererte menyene." listed: "Styr om siden skal vises i de genererte menyene."
target_klass_name: "Innholdstypen denne siden skal være mal for."
seo_title: "Definer en egen tittel for siden. Denne blir benyttet av nettleseren. Hvis denne står tom blir standardverdien fra sideinnstillingene benyttet." seo_title: "Definer en egen tittel for siden. Denne blir benyttet av nettleseren. Hvis denne står tom blir standardverdien fra sideinnstillingene benyttet."
meta_keywords: "Overstyr søkemotor-metadata for denne siden. Separer med komma." meta_keywords: "Overstyr søkemotor-metadata for denne siden. Separer med komma."
meta_description: "Overstyr søkemotorbeskrivelsen for denne siden." meta_description: "Overstyr søkemotorbeskrivelsen for denne siden."
snippet: snippet:
slug: "Denne brukes for å inkludere HTML-snutten i en side." slug: "Denne brukes for å inkludere HTML-snutten i en side."
site: site:
locales: "Dra et flagg til første posisjon for å sette som standard."
seo_title: "Definer en global verdi her som brukes som verdi for titteltaggen i sidens head-seksjon." seo_title: "Definer en global verdi her som brukes som verdi for titteltaggen i sidens head-seksjon."
meta_keywords: "Meta-nøkkelord blir brukt i head-seksjonen og leses av søkemotorer. Separeres med komma." meta_keywords: "Meta-nøkkelord blir brukt i head-seksjonen og leses av søkemotorer. Separeres med komma."
meta_description: "Meta-beskrivelse brukes i head-seksjonen og leses av søkemotorer." meta_description: "Meta-beskrivelse brukes i head-seksjonen og leses av søkemotorer."
@ -82,6 +77,10 @@ nb:
source: "Filen er tilgjengelig her: %{url}" source: "Filen er tilgjengelig her: %{url}"
update: update:
source: "Filen er tilgjengelig her: %{url}" source: "Filen er tilgjengelig her: %{url}"
custom_fields:
field:
name: "Verdi tilgjengelig i liquid-maler"
hint: "Tekst som vises i skjemaet rett under feltet"
content_entry: content_entry:
_slug: "Verdien brukes til å generere en url for en side som fungerer som en mal for denne innholdstypen (f.eks: \"template_page/{{ your_object._permalink }})\"." _slug: "Verdien brukes til å generere en url for en side som fungerer som en mal for denne innholdstypen (f.eks: \"template_page/{{ your_object._permalink }})\"."
seo_title: "Verdien benyttes til å erstatte sidetittelen for malen knyttet til modellen. Leses av søkemotorer." seo_title: "Verdien benyttes til å erstatte sidetittelen for malen knyttet til modellen. Leses av søkemotorer."
@ -92,12 +91,7 @@ nb:
samples: "Vil gjøre at importen kopierer innhold og assets" samples: "Vil gjøre at importen kopierer innhold og assets"
reset: "Vil gjøre at alle data slettes for den nye siden importeres." reset: "Vil gjøre at alle data slettes for den nye siden importeres."
content_type: content_type:
name: "Vi foreslår at du bruker flertals form (E.G: Personer)" item_template: "Du kan justere teksten som vises for hvert element i listen. Bruk liquid, f.eks: {{ entry.name }}"
slug: "It will be used as the name of the collection in the liquid templates. Ex: <span class='code'>{{ contents.my_projects }}</span>" api_enabled: "Brukes for å la sidebrukere opprette ny elementer (f.eks: meldinger i et kontaktskjema)"
raw_item_template: "You can customize the text displayed for each item in the list. Simply use Liquid. Ex: <span class='code'>{{ entry.name }})</span>" api_accounts: "En varslingsepost vil bli sendt til alle kontoene ovenfor når et nytt element blir opprettet."
public_submission_enabled: "It is used to let people from outside to create new entries (example: messages in a contact form)"
public_submission_accounts: "If the public submission option is enabled and for each entry created, sends a notification email to the accounts listed above."
"custom_fields/field":
name: "Name of the property for liquid templates. Ex: <span class='code'>&#123;&#123; your_object.&lt;name_of_your_field&gt; &#125;&#125;</span>"
hint: "Text displayed in the model form just below the field"

View File

@ -46,7 +46,6 @@ pt-BR:
page: page:
published: "Apenas contas autenticadas podem ver páginas não publicadas." published: "Apenas contas autenticadas podem ver páginas não publicadas."
cache_strategy: 'Faça o Cache da página para obter melhor desempenho. A escolha do "Simples" é um bom compromisso' cache_strategy: 'Faça o Cache da página para obter melhor desempenho. A escolha do "Simples" é um bom compromisso'
templatized: "Utilize a página como template para o modelo definido."
snippet: snippet:
slug: "Você precisa saber a ordem para inserir fragmentos dentro da página." slug: "Você precisa saber a ordem para inserir fragmentos dentro da página."
site: site:

Some files were not shown because too many files have changed in this diff Show More