Merge pull request #416 from miskander/wildcards
Merged master into wildcards
This commit is contained in:
commit
177f1e6c82
@ -11,4 +11,4 @@ notifications:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
- 2.0.0.rc
|
- 1.0-stable
|
||||||
|
2
1
Normal file
2
1
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Haml::Template.options[:format] = :html5
|
||||||
|
Haml::Template.options[:ugly] = true # improve performance in dev
|
6
Gemfile
6
Gemfile
@ -10,7 +10,9 @@ gemspec # Include gemspec dependencies
|
|||||||
group :development do
|
group :development do
|
||||||
# gem 'locomotive-mongoid-tree', :path => '../gems/custom_fields' # for Developers
|
# 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
|
||||||
|
|
||||||
|
# gem 'locomotive-aloha-rails', :path => '../gems/aloha-rails' # for Developers
|
||||||
|
|
||||||
gem 'rspec-rails', '~> 2.8.0' # In order to have rspec tasks and generators
|
gem 'rspec-rails', '~> 2.8.0' # In order to have rspec tasks and generators
|
||||||
gem 'rspec-cells'
|
gem 'rspec-cells'
|
||||||
@ -46,5 +48,7 @@ group :test do
|
|||||||
|
|
||||||
gem 'xpath', '~> 0.1.4'
|
gem 'xpath', '~> 0.1.4'
|
||||||
|
|
||||||
|
gem 'json_spec'
|
||||||
|
|
||||||
gem 'database_cleaner'
|
gem 'database_cleaner'
|
||||||
end
|
end
|
80
Gemfile.lock
80
Gemfile.lock
@ -15,20 +15,10 @@ GIT
|
|||||||
fssm (>= 0.2.7)
|
fssm (>= 0.2.7)
|
||||||
sass (~> 3.1)
|
sass (~> 3.1)
|
||||||
|
|
||||||
GIT
|
|
||||||
remote: git://github.com/locomotivecms/custom_fields.git
|
|
||||||
revision: 5b0e68859eaca41ac9d7a0231c6cd68ad66018b8
|
|
||||||
branch: 2.0.0.rc
|
|
||||||
specs:
|
|
||||||
custom_fields (2.0.0.rc9)
|
|
||||||
activesupport (~> 3.2.1)
|
|
||||||
carrierwave-mongoid (~> 0.1.3)
|
|
||||||
mongoid (~> 2.4.7)
|
|
||||||
|
|
||||||
PATH
|
PATH
|
||||||
remote: .
|
remote: .
|
||||||
specs:
|
specs:
|
||||||
locomotive_cms (2.0.0.rc4)
|
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)
|
||||||
@ -37,7 +27,7 @@ PATH
|
|||||||
carrierwave-mongoid (~> 0.1.3)
|
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.rc9)
|
custom_fields (~> 2.0.0.rc10)
|
||||||
devise (~> 1.5.3)
|
devise (~> 1.5.3)
|
||||||
dragonfly (~> 0.9.8)
|
dragonfly (~> 0.9.8)
|
||||||
flash_cookie_session (~> 1.1.1)
|
flash_cookie_session (~> 1.1.1)
|
||||||
@ -48,13 +38,14 @@ PATH
|
|||||||
httparty (~> 0.8.1)
|
httparty (~> 0.8.1)
|
||||||
jquery-rails (~> 1.0.16)
|
jquery-rails (~> 1.0.16)
|
||||||
kaminari (~> 0.13.0)
|
kaminari (~> 0.13.0)
|
||||||
locomotive-aloha-rails (~> 0.20.1.1)
|
locomotive-aloha-rails (~> 0.20.1.4)
|
||||||
locomotive-mongoid-tree (~> 0.6.2)
|
locomotive-mongoid-tree (~> 0.6.2)
|
||||||
locomotive-tinymce-rails (~> 3.4.7.1)
|
locomotive-tinymce-rails (~> 3.4.7.2)
|
||||||
locomotive_liquid (= 2.2.2)
|
locomotive_liquid (= 2.2.2)
|
||||||
mimetype-fu (~> 0.1.2)
|
mimetype-fu (~> 0.1.2)
|
||||||
mongo (~> 1.5.2)
|
mongo (~> 1.5.2)
|
||||||
mongoid (~> 2.4.6)
|
mongoid (~> 2.4.9)
|
||||||
|
multi_json (~> 1.3.4)
|
||||||
rack-cache (~> 1.1)
|
rack-cache (~> 1.1)
|
||||||
rails (~> 3.2.3)
|
rails (~> 3.2.3)
|
||||||
rails-backbone (~> 0.6.1)
|
rails-backbone (~> 0.6.1)
|
||||||
@ -62,6 +53,7 @@ PATH
|
|||||||
responders (~> 0.6.4)
|
responders (~> 0.6.4)
|
||||||
rmagick (~> 2.12.2)
|
rmagick (~> 2.12.2)
|
||||||
sanitize (~> 2.0.3)
|
sanitize (~> 2.0.3)
|
||||||
|
unidecoder (~> 1.1.1)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
@ -96,7 +88,7 @@ GEM
|
|||||||
activesupport (3.2.3)
|
activesupport (3.2.3)
|
||||||
i18n (~> 0.6)
|
i18n (~> 0.6)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
addressable (2.2.7)
|
addressable (2.2.8)
|
||||||
arel (3.0.2)
|
arel (3.0.2)
|
||||||
bcrypt-ruby (3.0.1)
|
bcrypt-ruby (3.0.1)
|
||||||
bson (1.5.2)
|
bson (1.5.2)
|
||||||
@ -111,7 +103,7 @@ GEM
|
|||||||
rack-test (>= 0.5.4)
|
rack-test (>= 0.5.4)
|
||||||
selenium-webdriver (~> 2.0)
|
selenium-webdriver (~> 2.0)
|
||||||
xpath (~> 0.1.4)
|
xpath (~> 0.1.4)
|
||||||
carrierwave (0.6.1)
|
carrierwave (0.6.2)
|
||||||
activemodel (>= 3.2.0)
|
activemodel (>= 3.2.0)
|
||||||
activesupport (>= 3.2.0)
|
activesupport (>= 3.2.0)
|
||||||
carrierwave-mongoid (0.1.3)
|
carrierwave-mongoid (0.1.3)
|
||||||
@ -120,10 +112,10 @@ GEM
|
|||||||
cells (3.8.3)
|
cells (3.8.3)
|
||||||
actionpack (~> 3.0)
|
actionpack (~> 3.0)
|
||||||
railties (~> 3.0)
|
railties (~> 3.0)
|
||||||
childprocess (0.3.1)
|
childprocess (0.3.2)
|
||||||
ffi (~> 1.0.6)
|
ffi (~> 1.0.6)
|
||||||
chunky_png (1.2.5)
|
chunky_png (1.2.5)
|
||||||
codemirror-rails (2.22)
|
codemirror-rails (2.24)
|
||||||
railties (~> 3.0)
|
railties (~> 3.0)
|
||||||
coffee-rails (3.2.2)
|
coffee-rails (3.2.2)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
@ -131,7 +123,7 @@ GEM
|
|||||||
coffee-script (2.2.0)
|
coffee-script (2.2.0)
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
execjs
|
execjs
|
||||||
coffee-script-source (1.2.0)
|
coffee-script-source (1.3.1)
|
||||||
cucumber (1.1.9)
|
cucumber (1.1.9)
|
||||||
builder (>= 2.1.2)
|
builder (>= 2.1.2)
|
||||||
diff-lcs (>= 1.1.2)
|
diff-lcs (>= 1.1.2)
|
||||||
@ -142,6 +134,10 @@ GEM
|
|||||||
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.rc10)
|
||||||
|
activesupport (~> 3.2.1)
|
||||||
|
carrierwave-mongoid (~> 0.1.3)
|
||||||
|
mongoid (~> 2.4.7)
|
||||||
database_cleaner (0.7.2)
|
database_cleaner (0.7.2)
|
||||||
devise (1.5.3)
|
devise (1.5.3)
|
||||||
bcrypt-ruby (~> 3.0)
|
bcrypt-ruby (~> 3.0)
|
||||||
@ -152,8 +148,8 @@ GEM
|
|||||||
rack
|
rack
|
||||||
ejs (1.0.0)
|
ejs (1.0.0)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
excon (0.13.3)
|
excon (0.13.4)
|
||||||
execjs (1.3.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)
|
||||||
@ -182,15 +178,18 @@ GEM
|
|||||||
haml (3.1.4)
|
haml (3.1.4)
|
||||||
highline (1.6.11)
|
highline (1.6.11)
|
||||||
hike (1.2.1)
|
hike (1.2.1)
|
||||||
httparty (0.8.1)
|
httparty (0.8.3)
|
||||||
multi_json
|
multi_json (~> 1.0)
|
||||||
multi_xml
|
multi_xml
|
||||||
i18n (0.6.0)
|
i18n (0.6.0)
|
||||||
journey (1.0.3)
|
journey (1.0.3)
|
||||||
jquery-rails (1.0.19)
|
jquery-rails (1.0.19)
|
||||||
railties (~> 3.0)
|
railties (~> 3.0)
|
||||||
thor (~> 0.14)
|
thor (~> 0.14)
|
||||||
json (1.6.6)
|
json (1.7.0)
|
||||||
|
json_spec (1.0.3)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
rspec (~> 2.0)
|
||||||
kaminari (0.13.0)
|
kaminari (0.13.0)
|
||||||
actionpack (>= 3.0.0)
|
actionpack (>= 3.0.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
@ -198,12 +197,14 @@ GEM
|
|||||||
kgio (2.7.4)
|
kgio (2.7.4)
|
||||||
launchy (2.1.0)
|
launchy (2.1.0)
|
||||||
addressable (~> 2.2.6)
|
addressable (~> 2.2.6)
|
||||||
locomotive-aloha-rails (0.20.1.1)
|
libwebsocket (0.1.3)
|
||||||
|
addressable
|
||||||
|
locomotive-aloha-rails (0.20.1.4)
|
||||||
actionpack (~> 3.2.1)
|
actionpack (~> 3.2.1)
|
||||||
locomotive-mongoid-tree (0.6.2)
|
locomotive-mongoid-tree (0.6.2)
|
||||||
mongoid (~> 2.0)
|
mongoid (~> 2.0)
|
||||||
locomotive-tinymce-rails (3.4.7.1)
|
locomotive-tinymce-rails (3.4.7.2)
|
||||||
actionpack (~> 3.2.1)
|
actionpack (~> 3.0)
|
||||||
locomotive_liquid (2.2.2)
|
locomotive_liquid (2.2.2)
|
||||||
mail (2.4.4)
|
mail (2.4.4)
|
||||||
i18n (>= 0.4.0)
|
i18n (>= 0.4.0)
|
||||||
@ -214,12 +215,12 @@ 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.8)
|
mongoid (2.4.9)
|
||||||
activemodel (~> 3.1)
|
activemodel (~> 3.1)
|
||||||
mongo (~> 1.3)
|
mongo (~> 1.3)
|
||||||
tzinfo (~> 0.3.22)
|
tzinfo (~> 0.3.22)
|
||||||
multi_json (1.0.4)
|
multi_json (1.3.4)
|
||||||
multi_xml (0.4.2)
|
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.3.0)
|
net-ssh (2.3.0)
|
||||||
@ -279,21 +280,23 @@ GEM
|
|||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
rspec (~> 2.8.0)
|
rspec (~> 2.8.0)
|
||||||
ruby-hmac (0.4.0)
|
ruby-hmac (0.4.0)
|
||||||
rubyzip (0.9.7)
|
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.15)
|
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.20.0)
|
selenium-webdriver (2.21.2)
|
||||||
childprocess (>= 0.2.5)
|
childprocess (>= 0.2.5)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
|
libwebsocket (~> 0.1.3)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
rubyzip
|
rubyzip
|
||||||
shoulda-matchers (1.0.0)
|
shoulda-matchers (1.1.0)
|
||||||
sprockets (2.1.2)
|
activesupport (>= 3.0.0)
|
||||||
|
sprockets (2.1.3)
|
||||||
hike (~> 1.2)
|
hike (~> 1.2)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (~> 1.1, != 1.3.0)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
@ -307,10 +310,11 @@ GEM
|
|||||||
uglifier (1.2.4)
|
uglifier (1.2.4)
|
||||||
execjs (>= 0.3.0)
|
execjs (>= 0.3.0)
|
||||||
multi_json (>= 1.0.2)
|
multi_json (>= 1.0.2)
|
||||||
unicorn (4.2.1)
|
unicorn (4.3.1)
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
rack
|
rack
|
||||||
raindrops (~> 0.7)
|
raindrops (~> 0.7)
|
||||||
|
unidecoder (1.1.1)
|
||||||
warden (1.1.1)
|
warden (1.1.1)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
xpath (0.1.4)
|
xpath (0.1.4)
|
||||||
@ -325,9 +329,9 @@ DEPENDENCIES
|
|||||||
compass!
|
compass!
|
||||||
compass-rails!
|
compass-rails!
|
||||||
cucumber-rails
|
cucumber-rails
|
||||||
custom_fields!
|
|
||||||
database_cleaner
|
database_cleaner
|
||||||
factory_girl_rails (~> 1.6.0)
|
factory_girl_rails (~> 1.6.0)
|
||||||
|
json_spec
|
||||||
launchy
|
launchy
|
||||||
locomotive_cms!
|
locomotive_cms!
|
||||||
mocha (= 0.9.12)
|
mocha (= 0.9.12)
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,3 @@
|
|||||||
|
button.aloha-locomotive-media-insert {
|
||||||
|
background: url(../img/image.gif) !important;
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 621 B |
@ -0,0 +1,96 @@
|
|||||||
|
define(
|
||||||
|
['aloha/jquery', 'aloha/plugin', 'aloha/floatingmenu', 'i18n!aloha/nls/i18n', 'i18n!locomotive_media/nls/i18n', 'css!locomotive_media/css/image.css'],
|
||||||
|
function(aQuery, Plugin, FloatingMenu, i18nCore, i18n) {
|
||||||
|
var jQuery = aQuery;
|
||||||
|
var $ = aQuery;
|
||||||
|
var GENTICS = window.GENTICS, Aloha = window.Aloha;
|
||||||
|
|
||||||
|
return Plugin.create('locomotive_media', {
|
||||||
|
init: function() {
|
||||||
|
FloatingMenu.createScope(this.name, 'Aloha.continuoustext');
|
||||||
|
|
||||||
|
this._addUIInsertButton(i18nCore.t('floatingmenu.tab.insert'));
|
||||||
|
},
|
||||||
|
|
||||||
|
openDialog: function() {
|
||||||
|
var that = this;
|
||||||
|
var picker = window.parent.application_view.content_assets_picker_view;
|
||||||
|
|
||||||
|
picker.options.on_select = function(asset) {
|
||||||
|
if (asset.get('image') == true)
|
||||||
|
that.insertImg(asset);
|
||||||
|
else
|
||||||
|
that.insertLink(asset);
|
||||||
|
|
||||||
|
picker.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
picker.render()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will insert a new image dom element into the dom tree
|
||||||
|
*/
|
||||||
|
insertImg: function(asset) {
|
||||||
|
var range = Aloha.Selection.getRangeObject(),
|
||||||
|
imageUrl = asset.get('url'),
|
||||||
|
imagestyle, imagetag, newImg;
|
||||||
|
|
||||||
|
if (range.isCollapsed()) {
|
||||||
|
imagestyle = "max-width: " + asset.get('width') + "; max-height: " + asset.get('height');
|
||||||
|
imagetag = '<img style="'+ imagestyle + '" src="' + imageUrl + '" title="" />';
|
||||||
|
newImg = jQuery(imagetag);
|
||||||
|
GENTICS.Utils.Dom.insertIntoDOM(newImg, range, jQuery(Aloha.activeEditable.obj));
|
||||||
|
} else {
|
||||||
|
Aloha.Log.error('media cannot markup a selection');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will insert a new link dom element into the dom tree
|
||||||
|
*/
|
||||||
|
insertLink: function(asset) {
|
||||||
|
var range = Aloha.Selection.getRangeObject(),
|
||||||
|
linkText = asset.get('filename'),
|
||||||
|
linkUrl = asset.get('url'),
|
||||||
|
linktag, newLink;
|
||||||
|
|
||||||
|
if (range.isCollapsed()) {
|
||||||
|
linktag = '<a href="' + linkUrl + '">' + linkText + '</a>';
|
||||||
|
newLink = jQuery(linktag);
|
||||||
|
GENTICS.Utils.Dom.insertIntoDOM(newLink, range, jQuery(Aloha.activeEditable.obj));
|
||||||
|
range.startContainer = range.endContainer = newLink.contents().get(0);
|
||||||
|
range.startOffset = 0;
|
||||||
|
range.endOffset = linkText.length;
|
||||||
|
} else {
|
||||||
|
linktag = '<a href="' + linkUrl + '"></a>';
|
||||||
|
newLink = jQuery(linktag);
|
||||||
|
GENTICS.Utils.Dom.addMarkup(range, newLink, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the insert button to the floating menu
|
||||||
|
*/
|
||||||
|
_addUIInsertButton: function(tabId) {
|
||||||
|
var that = this;
|
||||||
|
this.insertMediaButton = new Aloha.ui.Button({
|
||||||
|
'name' : 'insertlocomotivemedia',
|
||||||
|
'iconClass': 'aloha-button aloha-locomotive-media-insert',
|
||||||
|
'size' : 'small',
|
||||||
|
'onclick' : function () { that.openDialog(); },
|
||||||
|
'tooltip' : i18n.t('button.addimg.tooltip'),
|
||||||
|
'toggle' : false
|
||||||
|
});
|
||||||
|
|
||||||
|
FloatingMenu.addButton(
|
||||||
|
'Aloha.continuoustext',
|
||||||
|
this.insertMediaButton,
|
||||||
|
tabId,
|
||||||
|
1
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
@ -0,0 +1 @@
|
|||||||
|
define({ 'button.addimg.tooltip': 'insérer média' });
|
@ -0,0 +1,4 @@
|
|||||||
|
define({
|
||||||
|
root: { "button.addimg.tooltip": "insert media" },
|
||||||
|
fr: true
|
||||||
|
});
|
@ -0,0 +1 @@
|
|||||||
|
{}
|
@ -4,7 +4,7 @@
|
|||||||
#= require_tree ./views
|
#= require_tree ./views
|
||||||
|
|
||||||
window.Locomotive =
|
window.Locomotive =
|
||||||
mounted_on: '/locomotive' # default path
|
mounted_on: window.Locomotive.mounted_on
|
||||||
Models: {}
|
Models: {}
|
||||||
Collections: {}
|
Collections: {}
|
||||||
Views: {}
|
Views: {}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#= require_self
|
#= require_self
|
||||||
#= require_tree ./utils
|
#= require_tree ./utils
|
||||||
#= require_tree ./models
|
#= require_tree ./models
|
||||||
|
#= require_tree ./views/content_assets
|
||||||
#= require_tree ./views/inline_editor
|
#= require_tree ./views/inline_editor
|
||||||
|
|
||||||
window.Locomotive =
|
window.Locomotive =
|
||||||
|
@ -23,6 +23,11 @@ window.Aloha.settings =
|
|||||||
editables:
|
editables:
|
||||||
'.editable-short-text': [ ]
|
'.editable-short-text': [ ]
|
||||||
|
|
||||||
|
image:
|
||||||
|
ui:
|
||||||
|
insert: false
|
||||||
|
crop: false
|
||||||
|
|
||||||
i18n:
|
i18n:
|
||||||
available: ['en', 'fr', 'pt-BR', 'es', 'de', 'no', 'ru', 'nl']
|
available: ['en', 'fr', 'pt-BR', 'es', 'de', 'no', 'ru', 'nl']
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
String.prototype.slugify = function(sep) {
|
String.prototype.slugify = function(sep) {
|
||||||
if (typeof sep == 'undefined') sep = '_';
|
if (typeof sep == 'undefined') sep = '_';
|
||||||
var alphaNumRegexp = new RegExp('[^a-zA-Z0-9\\' + sep + ']', 'g');
|
var alphaNumRegexp = new RegExp('[^\\w\\' + sep + ']', 'g');
|
||||||
var avoidDuplicateRegexp = new RegExp('[\\' + sep + ']{2,}', 'g');
|
var avoidDuplicateRegexp = new RegExp('[\\' + sep + ']{2,}', 'g');
|
||||||
return this.replace(/\s/g, sep).replace(alphaNumRegexp, '').replace(avoidDuplicateRegexp, sep).toLowerCase()
|
return this.replace(/\s/g, sep).replace(alphaNumRegexp, '').replace(avoidDuplicateRegexp, sep).toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addParameterToURL = function(key, value, context) { // code from http://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript
|
window.addParameterToURL = function(key, value, context) { // code from http://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript
|
||||||
|
@ -50,6 +50,8 @@ class Locomotive.Views.ContentEntries.PopupFormView extends Locomotive.Views.Con
|
|||||||
parent_el.find('.new-section').hide()
|
parent_el.find('.new-section').hide()
|
||||||
parent_el.find('.edit-section').show()
|
parent_el.find('.edit-section').show()
|
||||||
|
|
||||||
|
@clear_errors()
|
||||||
|
|
||||||
$(@el).dialog('open')
|
$(@el).dialog('open')
|
||||||
|
|
||||||
close: (event) ->
|
close: (event) ->
|
||||||
|
@ -78,8 +78,10 @@ class Locomotive.Views.ContentTypes.CustomFieldEntryView extends Backbone.View
|
|||||||
form = @$('ol')
|
form = @$('ol')
|
||||||
|
|
||||||
if form.is(':hidden')
|
if form.is(':hidden')
|
||||||
|
@$('a.toggle').addClass('open')
|
||||||
form.slideDown()
|
form.slideDown()
|
||||||
else
|
else
|
||||||
|
@$('a.toggle').removeClass('open')
|
||||||
form.slideUp()
|
form.slideUp()
|
||||||
|
|
||||||
show_error: (message) ->
|
show_error: (message) ->
|
||||||
|
@ -11,5 +11,4 @@ class Locomotive.Views.ContentTypes.EditView extends Locomotive.Views.ContentTyp
|
|||||||
|
|
||||||
if custom_field.isNew() # assign an id for each new custom field
|
if custom_field.isNew() # assign an id for each new custom field
|
||||||
custom_field.set id: data._id, _id: data._id
|
custom_field.set id: data._id, _id: data._id
|
||||||
console.log(custom_field)
|
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ class Locomotive.Views.EditableElements.FileView extends Backbone.View
|
|||||||
on_change: =>
|
on_change: =>
|
||||||
@$('a:first').hide() & @$('input[type=file]').show() & @$('a.delete').hide()
|
@$('a:first').hide() & @$('input[type=file]').show() & @$('a.delete').hide()
|
||||||
on_cancel: =>
|
on_cancel: =>
|
||||||
@$('a:first').show() & @$('input[type=file]').hide() & @$('a.delete').show()
|
@model.set(source: null)
|
||||||
|
@$('a:first').show() & @$('input[type=file]').val('').hide() & @$('a.delete').show()
|
||||||
|
|
||||||
toggle_delete: (event) ->
|
toggle_delete: (event) ->
|
||||||
@_toggle event, 'delete',
|
@_toggle event, 'delete',
|
||||||
|
@ -2,7 +2,35 @@
|
|||||||
|
|
||||||
Locomotive.Views.EditableElements ||= {}
|
Locomotive.Views.EditableElements ||= {}
|
||||||
|
|
||||||
class Locomotive.Views.EditableElements.LongTextView extends Locomotive.Views.EditableElements.ShortTextView
|
class Locomotive.Views.EditableElements.LongTextView extends Backbone.View
|
||||||
|
|
||||||
|
tagName: 'li'
|
||||||
|
|
||||||
|
className: 'text input html'
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
$(@el).html(ich.editable_text_input(@model.toJSON()))
|
||||||
|
|
||||||
|
return @
|
||||||
|
|
||||||
|
after_render: ->
|
||||||
|
settings = _.extend {}, @tinymce_settings(),
|
||||||
|
oninit: ((editor) =>
|
||||||
|
$.cmd 'S', (() =>
|
||||||
|
@model.set(content: editor.getBody().innerHTML)
|
||||||
|
$(@el).parents('form').trigger('submit')
|
||||||
|
), [], ignoreCase: true, document: editor.dom.doc),
|
||||||
|
onchange_callback: (editor) =>
|
||||||
|
@model.set(content: editor.getBody().innerHTML)
|
||||||
|
|
||||||
|
@$('textarea').tinymce(settings)
|
||||||
|
|
||||||
tinymce_settings: ->
|
tinymce_settings: ->
|
||||||
window.Locomotive.tinyMCE.defaultSettings
|
window.Locomotive.tinyMCE.defaultSettings
|
||||||
|
|
||||||
|
refresh: ->
|
||||||
|
# do nothing
|
||||||
|
|
||||||
|
remove: ->
|
||||||
|
@$('textarea').tinymce().destroy()
|
||||||
|
super
|
||||||
|
@ -4,31 +4,19 @@ class Locomotive.Views.EditableElements.ShortTextView extends Backbone.View
|
|||||||
|
|
||||||
tagName: 'li'
|
tagName: 'li'
|
||||||
|
|
||||||
className: 'text input html'
|
className: 'text input short'
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
$(@el).html(ich.editable_text_input(@model.toJSON()))
|
$(@el).html(ich.editable_text_input(@model.toJSON()))
|
||||||
|
|
||||||
|
@$('textarea').bind 'keyup', (event) =>
|
||||||
|
input = $(event.target)
|
||||||
|
@model.set(content: input.val())
|
||||||
|
|
||||||
return @
|
return @
|
||||||
|
|
||||||
after_render: ->
|
after_render: ->
|
||||||
settings = _.extend {}, @tinymce_settings(),
|
# do nothing
|
||||||
oninit: ((editor) =>
|
|
||||||
$.cmd 'S', (() =>
|
|
||||||
@model.set(content: editor.getBody().innerHTML)
|
|
||||||
$(@el).parents('form').trigger('submit')
|
|
||||||
), [], ignoreCase: true, document: editor.dom.doc),
|
|
||||||
onchange_callback: (editor) =>
|
|
||||||
@model.set(content: editor.getBody().innerHTML)
|
|
||||||
|
|
||||||
@$('textarea').tinymce(settings)
|
|
||||||
|
|
||||||
tinymce_settings: ->
|
|
||||||
window.Locomotive.tinyMCE.minimalSettings
|
|
||||||
|
|
||||||
refresh: ->
|
refresh: ->
|
||||||
# do nothing
|
# do nothing
|
||||||
|
|
||||||
remove: ->
|
|
||||||
@$('textarea').tinymce().destroy()
|
|
||||||
super
|
|
@ -1,8 +1,8 @@
|
|||||||
Locomotive.Views.InlinEditor ||= {}
|
Locomotive.Views.InlineEditor ||= {}
|
||||||
|
|
||||||
#= require ./toolbar_view
|
#= require ./toolbar_view
|
||||||
|
|
||||||
class Locomotive.Views.InlinEditor.ApplicationView extends Backbone.View
|
class Locomotive.Views.InlineEditor.ApplicationView extends Backbone.View
|
||||||
|
|
||||||
el: 'body'
|
el: 'body'
|
||||||
|
|
||||||
@ -13,7 +13,9 @@ class Locomotive.Views.InlinEditor.ApplicationView extends Backbone.View
|
|||||||
|
|
||||||
_.bindAll(@, '_$')
|
_.bindAll(@, '_$')
|
||||||
|
|
||||||
@toolbar_view = new Locomotive.Views.InlinEditor.ToolbarView(target: @iframe)
|
@toolbar_view = new Locomotive.Views.InlineEditor.ToolbarView(target: @iframe)
|
||||||
|
|
||||||
|
@content_assets_picker_view = new Locomotive.Views.ContentAssets.PickerView(collection: new Locomotive.Models.ContentAssetsCollection())
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
super
|
super
|
||||||
@ -26,15 +28,13 @@ class Locomotive.Views.InlinEditor.ApplicationView extends Backbone.View
|
|||||||
iframe = @iframe
|
iframe = @iframe
|
||||||
|
|
||||||
iframe.load =>
|
iframe.load =>
|
||||||
console.log('iframe loading')
|
|
||||||
|
|
||||||
if @_$('meta[name=inline-editor]').size() > 0
|
if @_$('meta[name=inline-editor]').size() > 0
|
||||||
# bind the resize event. When the iFrame's size changes, update its height
|
# bind the resize event. When the iFrame's size changes, update its height
|
||||||
iframe_content = iframe.contents().find('body')
|
iframe_content = iframe.contents()
|
||||||
iframe_content.resize ->
|
iframe_content.resize ->
|
||||||
elem = $(this)
|
elem = $(this)
|
||||||
|
|
||||||
if elem.outerHeight(true) > $('body').outerHeight(true) # Resize the iFrame.
|
if elem.outerHeight(true) > iframe.outerHeight(true) # Resize the iFrame.
|
||||||
iframe.css height: elem.outerHeight(true)
|
iframe.css height: elem.outerHeight(true)
|
||||||
|
|
||||||
# Resize the iFrame immediately.
|
# Resize the iFrame immediately.
|
||||||
@ -46,8 +46,6 @@ class Locomotive.Views.InlinEditor.ApplicationView extends Backbone.View
|
|||||||
@enhance_iframe_links()
|
@enhance_iframe_links()
|
||||||
|
|
||||||
set_page: (attributes) ->
|
set_page: (attributes) ->
|
||||||
console.log('set_page')
|
|
||||||
|
|
||||||
@page = new Locomotive.Models.Page(attributes)
|
@page = new Locomotive.Models.Page(attributes)
|
||||||
|
|
||||||
@toolbar_view.model = @page
|
@toolbar_view.model = @page
|
||||||
@ -78,7 +76,7 @@ class Locomotive.Views.InlinEditor.ApplicationView extends Backbone.View
|
|||||||
_jQuery('a').each ->
|
_jQuery('a').each ->
|
||||||
link = _jQuery(this)
|
link = _jQuery(this)
|
||||||
url = link.attr('href')
|
url = link.attr('href')
|
||||||
if url? && url.indexOf('#') != 0 && /^(www|http)/.exec(url) == null && /(\/_edit)$/.exec(url) == null
|
if url? && url.indexOf('#') != 0 && /^(www|http)/.exec(url) == null && /(\/_edit)$/.exec(url) == null && /^\/sites\//.exec(url) == null
|
||||||
url = '/index' if url == '/'
|
url = '/index' if url == '/'
|
||||||
|
|
||||||
unless url.indexOf('_edit') > 0
|
unless url.indexOf('_edit') > 0
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Locomotive.Views.InlinEditor ||= {}
|
Locomotive.Views.InlineEditor ||= {}
|
||||||
|
|
||||||
class Locomotive.Views.InlinEditor.ToolbarView extends Backbone.View
|
class Locomotive.Views.InlineEditor.ToolbarView extends Backbone.View
|
||||||
|
|
||||||
el: '#toolbar .inner'
|
el: '#toolbar .inner'
|
||||||
|
|
||||||
@ -13,8 +13,6 @@ class Locomotive.Views.InlinEditor.ToolbarView extends Backbone.View
|
|||||||
render: ->
|
render: ->
|
||||||
super
|
super
|
||||||
|
|
||||||
console.log('render toolbar')
|
|
||||||
|
|
||||||
@enable_editing_mode_checkbox()
|
@enable_editing_mode_checkbox()
|
||||||
|
|
||||||
@enable_content_locale_picker()
|
@enable_content_locale_picker()
|
||||||
@ -22,8 +20,6 @@ class Locomotive.Views.InlinEditor.ToolbarView extends Backbone.View
|
|||||||
@
|
@
|
||||||
|
|
||||||
notify: (aloha_editable) ->
|
notify: (aloha_editable) ->
|
||||||
console.log('editable_element has been modified...')
|
|
||||||
|
|
||||||
window.bar = aloha_editable
|
window.bar = aloha_editable
|
||||||
|
|
||||||
element_id = aloha_editable.obj.attr('data-element-id')
|
element_id = aloha_editable.obj.attr('data-element-id')
|
||||||
@ -125,8 +121,6 @@ class Locomotive.Views.InlinEditor.ToolbarView extends Backbone.View
|
|||||||
context.find('span.text').html(values[1])
|
context.find('span.text').html(values[1])
|
||||||
|
|
||||||
refresh: ->
|
refresh: ->
|
||||||
console.log('refreshing toolbar...')
|
|
||||||
|
|
||||||
@$('h1').html(@model.get('title')).removeClass()
|
@$('h1').html(@model.get('title')).removeClass()
|
||||||
|
|
||||||
if @$('.editing-mode input[type=checkbox]').is(':checked')
|
if @$('.editing-mode input[type=checkbox]').is(':checked')
|
||||||
|
@ -5,10 +5,14 @@ class Locomotive.Views.Pages.EditView extends Locomotive.Views.Pages.FormView
|
|||||||
save: (event) ->
|
save: (event) ->
|
||||||
event.stopPropagation() & event.preventDefault()
|
event.stopPropagation() & event.preventDefault()
|
||||||
|
|
||||||
|
form = $(event.target).trigger('ajax:beforeSend')
|
||||||
|
|
||||||
@clear_errors()
|
@clear_errors()
|
||||||
|
|
||||||
@model.save {},
|
@model.save {},
|
||||||
success: (model, response, xhr) =>
|
success: (model, response, xhr) =>
|
||||||
|
form.trigger('ajax:complete')
|
||||||
|
|
||||||
model._normalize()
|
model._normalize()
|
||||||
|
|
||||||
if model.get('template_changed') == true
|
if model.get('template_changed') == true
|
||||||
@ -17,9 +21,8 @@ class Locomotive.Views.Pages.EditView extends Locomotive.Views.Pages.FormView
|
|||||||
@refresh_editable_elements()
|
@refresh_editable_elements()
|
||||||
|
|
||||||
error: (model, xhr) =>
|
error: (model, xhr) =>
|
||||||
|
form.trigger('ajax:complete')
|
||||||
|
|
||||||
errors = JSON.parse(xhr.responseText)
|
errors = JSON.parse(xhr.responseText)
|
||||||
|
|
||||||
@show_errors errors
|
@show_errors errors
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,10 +24,6 @@ class Locomotive.Views.Shared.Fields.ManyToManyView extends Backbone.View
|
|||||||
@collection = @model.get(@options.name)
|
@collection = @model.get(@options.name)
|
||||||
@all_entries = @options.all_entries
|
@all_entries = @options.all_entries
|
||||||
|
|
||||||
window.collection = @collection
|
|
||||||
window.bar = @all_entries
|
|
||||||
window.model = @model
|
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
$(@el).html(@template()())
|
$(@el).html(@template()())
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
|
|||||||
# allow users to save with CTRL+S or CMD+s
|
# allow users to save with CTRL+S or CMD+s
|
||||||
@enable_save_with_keys_combination()
|
@enable_save_with_keys_combination()
|
||||||
|
|
||||||
|
# enable form notifications
|
||||||
|
@enable_form_notifications()
|
||||||
|
|
||||||
return @
|
return @
|
||||||
|
|
||||||
save: (event) ->
|
save: (event) ->
|
||||||
@ -24,6 +27,8 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
|
|||||||
save_in_ajax: (event, options) ->
|
save_in_ajax: (event, options) ->
|
||||||
event.stopPropagation() & event.preventDefault()
|
event.stopPropagation() & event.preventDefault()
|
||||||
|
|
||||||
|
form = $(event.target).trigger('ajax:beforeSend')
|
||||||
|
|
||||||
@clear_errors()
|
@clear_errors()
|
||||||
|
|
||||||
options ||= { headers: {}, on_success: null, on_error: null }
|
options ||= { headers: {}, on_success: null, on_error: null }
|
||||||
@ -33,11 +38,15 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
|
|||||||
@model.save {},
|
@model.save {},
|
||||||
headers: options.headers
|
headers: options.headers
|
||||||
success: (model, response, xhr) =>
|
success: (model, response, xhr) =>
|
||||||
|
form.trigger('ajax:complete')
|
||||||
|
|
||||||
model.attributes = previous_attributes
|
model.attributes = previous_attributes
|
||||||
|
|
||||||
options.on_success(response, xhr) if options.on_success
|
options.on_success(response, xhr) if options.on_success
|
||||||
|
|
||||||
error: (model, xhr) =>
|
error: (model, xhr) =>
|
||||||
|
form.trigger('ajax:complete')
|
||||||
|
|
||||||
errors = JSON.parse(xhr.responseText)
|
errors = JSON.parse(xhr.responseText)
|
||||||
|
|
||||||
@show_errors errors
|
@show_errors errors
|
||||||
@ -72,7 +81,10 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
|
|||||||
content.slideUp 100, -> parent.addClass('folded')
|
content.slideUp 100, -> parent.addClass('folded')
|
||||||
|
|
||||||
enable_save_with_keys_combination: ->
|
enable_save_with_keys_combination: ->
|
||||||
$.cmd 'S', (() => @$('form').trigger('submit')), [], ignoreCase: true
|
$.cmd 'S', (() => @$('form input[type=submit]').trigger('click')), [], ignoreCase: true
|
||||||
|
|
||||||
|
enable_form_notifications: ->
|
||||||
|
@$('form').formSubmitNotification()
|
||||||
|
|
||||||
after_inputs_fold: ->
|
after_inputs_fold: ->
|
||||||
# overide this method if necessary
|
# overide this method if necessary
|
||||||
|
@ -7,7 +7,7 @@ class Locomotive.Views.ThemeAssets.IndexView extends Backbone.View
|
|||||||
_lists_views: []
|
_lists_views: []
|
||||||
|
|
||||||
initialize: ->
|
initialize: ->
|
||||||
_.bindAll(@, 'add_asset')
|
_.bindAll(@, 'insert_asset')
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
@build_uploader()
|
@build_uploader()
|
||||||
@ -29,16 +29,24 @@ class Locomotive.Views.ThemeAssets.IndexView extends Backbone.View
|
|||||||
input = form.find('input[type=file]')
|
input = form.find('input[type=file]')
|
||||||
link = form.find('a.new')
|
link = form.find('a.new')
|
||||||
|
|
||||||
|
form.formSubmitNotification()
|
||||||
|
|
||||||
link.bind 'click', (event) ->
|
link.bind 'click', (event) ->
|
||||||
event.stopPropagation() & event.preventDefault()
|
event.stopPropagation() & event.preventDefault()
|
||||||
input.click()
|
input.click()
|
||||||
|
|
||||||
input.bind 'change', (event) =>
|
input.bind 'change', (event) =>
|
||||||
|
form.trigger('ajax:beforeSend')
|
||||||
_.each event.target.files, (file) =>
|
_.each event.target.files, (file) =>
|
||||||
asset = new Locomotive.Models.ThemeAsset(source: file)
|
asset = new Locomotive.Models.ThemeAsset(source: file)
|
||||||
asset.save {}, success: @add_asset, headers: { 'X-Flash': true }
|
asset.save {},
|
||||||
|
success: (model, response, xhr) =>
|
||||||
|
form.trigger('ajax:complete')
|
||||||
|
@insert_asset(model)
|
||||||
|
error: (() => form.trigger('ajax:complete'))
|
||||||
|
headers: { 'X-Flash': true }
|
||||||
|
|
||||||
add_asset: (model) ->
|
insert_asset: (model) ->
|
||||||
list_view = @pick_list_view(model.get('content_type'))
|
list_view = @pick_list_view(model.get('content_type'))
|
||||||
list_view.collection.add(model)
|
list_view.collection.add(model)
|
||||||
|
|
||||||
|
@ -33,24 +33,6 @@
|
|||||||
|
|
||||||
/* ___ list ___ */
|
/* ___ list ___ */
|
||||||
|
|
||||||
p.no-items {
|
|
||||||
background: #fffbe6;
|
|
||||||
border: 5px solid #eee3a8;
|
|
||||||
@include border-radius(25px);
|
|
||||||
|
|
||||||
padding: 15px 0px;
|
|
||||||
|
|
||||||
text-align: center;
|
|
||||||
color: #9d8963;
|
|
||||||
font-size: 16px !important;
|
|
||||||
@include single-text-shadow(rgba(255, 255, 255, 1), 1px, 1px, 1px);
|
|
||||||
|
|
||||||
a {
|
|
||||||
@include hover-link;
|
|
||||||
color: #ff2900;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.list {
|
ul.list {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
@ -314,6 +296,29 @@ ul.list {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ___ form notification ___ */
|
||||||
|
|
||||||
|
#form-submit-notification {
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
z-index: 9999;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
padding: 5px 10px;
|
||||||
|
|
||||||
|
background-color: #fffbe5;
|
||||||
|
border-left: 4px solid #efe4a5;
|
||||||
|
border-bottom: 4px solid #efe4a5;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
@include single-text-shadow(rgba(255, 255, 255, 1), 0px, 1px, 0px);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #aa9a79;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ___ paragraph (for help for example) ___ */
|
/* ___ paragraph (for help for example) ___ */
|
||||||
|
|
||||||
p span.code {
|
p span.code {
|
||||||
@ -323,19 +328,3 @@ p span.code {
|
|||||||
color: #8B8D9A;
|
color: #8B8D9A;
|
||||||
@include single-text-shadow(#fff, 0px, 0px, 1px);
|
@include single-text-shadow(#fff, 0px, 0px, 1px);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ___ quick upload ___ */
|
|
||||||
|
|
||||||
form.quick-upload {
|
|
||||||
display: inline;
|
|
||||||
|
|
||||||
input[type=file] {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
|
|
||||||
ul.content-assets {
|
ul.content-assets {
|
||||||
|
|
||||||
|
list-style: none;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
|
||||||
li.asset {
|
li.asset {
|
||||||
position: relative;
|
position: relative;
|
||||||
float: left;
|
float: left;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
width: auto;
|
width: auto;
|
||||||
|
|
||||||
z-index: 999 !important;
|
z-index: 1001 !important;
|
||||||
|
|
||||||
background: #f1f1f1;
|
background: #f1f1f1;
|
||||||
|
|
||||||
|
@ -84,6 +84,12 @@
|
|||||||
width: 530px;
|
width: 530px;
|
||||||
}
|
}
|
||||||
} // li.string
|
} // li.string
|
||||||
|
|
||||||
|
li.date {
|
||||||
|
input[type=text] {
|
||||||
|
width: 90px;
|
||||||
|
}
|
||||||
|
} // li.string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // .form.formtastic
|
} // .form.formtastic
|
||||||
|
@ -157,6 +157,10 @@ form.formtastic {
|
|||||||
&:hover {
|
&:hover {
|
||||||
background-image: image-url("locomotive/list/icons/toggle.png");
|
background-image: image-url("locomotive/list/icons/toggle.png");
|
||||||
}
|
}
|
||||||
|
&.open {
|
||||||
|
@include rotate(180deg);
|
||||||
|
}
|
||||||
|
@include single-transition(transform, 0.5s);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.drag {
|
&.drag {
|
||||||
@ -291,6 +295,17 @@ form.formtastic {
|
|||||||
}
|
}
|
||||||
} // li.string, li.password
|
} // li.string, li.password
|
||||||
|
|
||||||
|
&.text {
|
||||||
|
|
||||||
|
&.short textarea {
|
||||||
|
padding: 5px;
|
||||||
|
height: 28px;
|
||||||
|
width: 696px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // li.text
|
||||||
|
|
||||||
&.locale, &.locales {
|
&.locale, &.locales {
|
||||||
.list {
|
.list {
|
||||||
margin-left: 150px;
|
margin-left: 150px;
|
||||||
|
@ -176,7 +176,7 @@ body {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=submit] {
|
input[type=submit], button[type=submit] {
|
||||||
@include light-button;
|
@include light-button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
||||||
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
||||||
*= require locomotive/blueprint/screen.css
|
*= require locomotive/blueprint/screen.css
|
||||||
|
*= require locomotive/jquery
|
||||||
*= require locomotive/toggle.css
|
*= require locomotive/toggle.css
|
||||||
|
*= require locomotive/backoffice/dialog_changes.css
|
||||||
|
*= require locomotive/backoffice/content_assets.css
|
||||||
*= require_tree ./shared
|
*= require_tree ./shared
|
||||||
*= require_tree ./inline_editor
|
*= require_tree ./inline_editor
|
||||||
*/
|
*/
|
34
app/assets/stylesheets/locomotive/shared/common.css.scss
Normal file
34
app/assets/stylesheets/locomotive/shared/common.css.scss
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
@import "compass/css3/border-radius";
|
||||||
|
@import "compass/css3/text-shadow";
|
||||||
|
@import "locomotive/shared/helpers";
|
||||||
|
|
||||||
|
/* ___ quick upload ___ */
|
||||||
|
|
||||||
|
form.quick-upload {
|
||||||
|
display: inline;
|
||||||
|
|
||||||
|
input[type=file] {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ___ list ___ */
|
||||||
|
|
||||||
|
p.no-items {
|
||||||
|
background: #fffbe6;
|
||||||
|
border: 5px solid #eee3a8;
|
||||||
|
@include border-radius(25px);
|
||||||
|
|
||||||
|
padding: 15px 0px;
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
color: #9d8963;
|
||||||
|
font-size: 16px !important;
|
||||||
|
@include single-text-shadow(rgba(255, 255, 255, 1), 1px, 1px, 1px);
|
||||||
|
|
||||||
|
a {
|
||||||
|
@include hover-link;
|
||||||
|
color: #ff2900;
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,8 @@ module Locomotive
|
|||||||
|
|
||||||
skip_before_filter :verify_authenticity_token
|
skip_before_filter :verify_authenticity_token
|
||||||
|
|
||||||
|
skip_load_and_authorize_resource
|
||||||
|
|
||||||
self.responder = Locomotive::ActionController::PublicResponder # custom responder
|
self.responder = Locomotive::ActionController::PublicResponder # custom responder
|
||||||
|
|
||||||
respond_to :html, :json
|
respond_to :html, :json
|
||||||
@ -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
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
visible << content_type
|
visible << content_type
|
||||||
|
|
||||||
|
end.each do |content_type|
|
||||||
|
# make sure to have a fresh copy of the content types because for now we don't have the full content types (ie: content_types.only(...))
|
||||||
|
::Mongoid::IdentityMap.remove(content_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
if visible.size > 0
|
if visible.size > 0
|
||||||
|
@ -44,7 +44,7 @@ module Locomotive
|
|||||||
|
|
||||||
def options_for_content_type
|
def options_for_content_type
|
||||||
current_site.content_types.map do |c|
|
current_site.content_types.map do |c|
|
||||||
c != @content_type ? [c.name, c.klass_with_custom_fields(:entries).to_s] : nil
|
[c.name, c.klass_with_custom_fields(:entries).to_s]
|
||||||
end.compact
|
end.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ module Locomotive
|
|||||||
default :from => Locomotive.config.mailer_sender
|
default :from => Locomotive.config.mailer_sender
|
||||||
|
|
||||||
def new_content_entry(account, entry)
|
def new_content_entry(account, entry)
|
||||||
@account, @entry, @type = account, entry.to_presenter, entry.content_type
|
@account, @entry, @type = account, entry, entry.content_type
|
||||||
|
|
||||||
subject = t('locomotive.notifications.new_content_entry.subject', :type => @type.name, :locale => account.locale)
|
subject = t('locomotive.notifications.new_content_entry.subject', :type => @type.name, :locale => account.locale)
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
def as_json(options = {})
|
def as_json(options = {})
|
||||||
self.to_presenter.as_json
|
self.to_presenter(options).as_json
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
@ -146,7 +146,7 @@ module Locomotive
|
|||||||
return if !self.content_type.public_submission_enabled? || self.content_type.public_submission_accounts.blank?
|
return if !self.content_type.public_submission_enabled? || self.content_type.public_submission_accounts.blank?
|
||||||
|
|
||||||
self.site.accounts.each do |account|
|
self.site.accounts.each do |account|
|
||||||
next unless self.content_type.public_submission_accounts.include?(account._id)
|
next unless self.content_type.public_submission_accounts.map(&:to_s).include?(account._id.to_s)
|
||||||
|
|
||||||
Locomotive::Notifications.new_content_entry(account, self).deliver
|
Locomotive::Notifications.new_content_entry(account, self).deliver
|
||||||
end
|
end
|
||||||
|
@ -27,7 +27,7 @@ module Locomotive
|
|||||||
|
|
||||||
def set_label_field
|
def set_label_field
|
||||||
if @new_label_field_name.present?
|
if @new_label_field_name.present?
|
||||||
self.label_field_id = self.entries_custom_fields.detect { |f| f.name == @new_label_field_name.underscore }._id
|
self.label_field_id = self.entries_custom_fields.detect { |f| f.name == @new_label_field_name.underscore }.try(:_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
# unknown label_field_name, get the first one instead
|
# unknown label_field_name, get the first one instead
|
||||||
|
@ -71,6 +71,11 @@ module Locomotive
|
|||||||
new_el.copy_attributes_from(el)
|
new_el.copy_attributes_from(el)
|
||||||
else
|
else
|
||||||
existing_el.disabled = false
|
existing_el.disabled = false
|
||||||
|
|
||||||
|
# only the type and hint properties can be modified from the parent element
|
||||||
|
%w(_type hint).each do |attr|
|
||||||
|
existing_el.send(:"#{attr}=", el.send(attr.to_sym))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -19,6 +19,9 @@ module Locomotive
|
|||||||
## indexes ##
|
## indexes ##
|
||||||
index :position
|
index :position
|
||||||
index [[:depth, Mongo::ASCENDING], [:position, Mongo::ASCENDING]]
|
index [[:depth, Mongo::ASCENDING], [:position, Mongo::ASCENDING]]
|
||||||
|
|
||||||
|
alias_method_chain :rearrange, :identity_map
|
||||||
|
alias_method_chain :rearrange_children, :identity_map
|
||||||
end
|
end
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
@ -105,6 +108,16 @@ module Locomotive
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def rearrange_with_identity_map
|
||||||
|
::Mongoid::IdentityMap.clear
|
||||||
|
rearrange_without_identity_map
|
||||||
|
end
|
||||||
|
|
||||||
|
def rearrange_children_with_identity_map
|
||||||
|
self.children.reset
|
||||||
|
rearrange_children_without_identity_map
|
||||||
|
end
|
||||||
|
|
||||||
def persist_depth
|
def persist_depth
|
||||||
self.attributes['depth'] = self.depth
|
self.attributes['depth'] = self.depth
|
||||||
self.depth_will_change!
|
self.depth_will_change!
|
||||||
|
@ -37,9 +37,13 @@ module Locomotive
|
|||||||
|
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
|
|
||||||
|
def subdomain=(subdomain)
|
||||||
|
super(subdomain.try(:downcase))
|
||||||
|
end
|
||||||
|
|
||||||
def domains=(array)
|
def domains=(array)
|
||||||
array.reject!(&:blank?)
|
array.reject!(&:blank?)
|
||||||
array = [] if array.blank?; super(array)
|
array = [] if array.blank?; super(array.map(&:downcase))
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_subdomain_to_domains
|
def add_subdomain_to_domains
|
||||||
|
@ -54,8 +54,12 @@ module Locomotive
|
|||||||
Locomotive::Liquid::Drops::Site.new(self)
|
Locomotive::Liquid::Drops::Site.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_presenter(options = {})
|
||||||
|
Locomotive::SitePresenter.new(self, options)
|
||||||
|
end
|
||||||
|
|
||||||
def as_json(options = {})
|
def as_json(options = {})
|
||||||
Locomotive::SitePresenter.new(self, options).as_json
|
self.to_presenter(options).as_json
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
module Locomotive
|
module Locomotive
|
||||||
class ContentAssetPresenter < BasePresenter
|
class ContentAssetPresenter < BasePresenter
|
||||||
|
|
||||||
delegate :content_type, :vignette_url, :to => :source
|
delegate :content_type, :width, :height, :vignette_url, :to => :source
|
||||||
|
|
||||||
def full_filename
|
def full_filename
|
||||||
self.source.source_filename
|
self.source.source_filename
|
||||||
@ -29,7 +29,7 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
def included_methods
|
def included_methods
|
||||||
super + %w(full_filename filename short_name extname content_type content_type_text url vignette_url)
|
super + %w(full_filename filename short_name extname content_type content_type_text url vignette_url width height)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
module Locomotive
|
module Locomotive
|
||||||
class MembershipPresenter < BasePresenter
|
class MembershipPresenter < BasePresenter
|
||||||
|
|
||||||
delegate :role, :to => :source
|
delegate :role, :account_id, :to => :source
|
||||||
|
|
||||||
def name
|
def name
|
||||||
self.source.account.name
|
self.source.account.name
|
||||||
@ -26,8 +26,13 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
def included_methods
|
def included_methods
|
||||||
super + %w(name email role role_name can_update grant_admin)
|
super + %w(account_id name email role role_name can_update grant_admin)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# def light_as_json
|
||||||
|
# methods = included_methods.clone - %w(name email)
|
||||||
|
# self.as_json(methods)
|
||||||
|
# end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -15,5 +15,10 @@ module Locomotive
|
|||||||
super + %w(name locales domain_name subdomain domains robots_txt seo_title meta_keywords meta_description domains_without_subdomain memberships)
|
super + %w(name locales domain_name subdomain domains robots_txt seo_title meta_keywords meta_description domains_without_subdomain memberships)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def as_json_for_html_view
|
||||||
|
methods = included_methods.clone - %w(memberships)
|
||||||
|
self.as_json(methods)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -38,4 +38,4 @@
|
|||||||
|
|
||||||
- content_for :backbone_view_data do
|
- content_for :backbone_view_data do
|
||||||
:plain
|
:plain
|
||||||
, all_#{name}_entries: #{target_content_type.list_or_group_entries.to_json}
|
, all_#{name}_entries: #{target_content_type.list_or_group_entries.to_json(:depth => 1)}
|
@ -10,13 +10,20 @@
|
|||||||
%hr
|
%hr
|
||||||
|
|
||||||
%ul
|
%ul
|
||||||
- @type.entries_custom_fields.each do |field|
|
- @type.ordered_entries_custom_fields.each do |field|
|
||||||
- value = @entry.value_for(field)
|
- value = @entry.send(field.name)
|
||||||
%li
|
%li
|
||||||
%strong= field.label
|
%strong= field.label
|
||||||
-
|
-
|
||||||
%i
|
%i
|
||||||
- if field.type == 'file'
|
- case field.type.to_s
|
||||||
= link_to File.basename(value), value
|
- when 'string', 'text', 'boolean', 'date'
|
||||||
- else
|
|
||||||
= value
|
= value
|
||||||
|
- when 'file'
|
||||||
|
= link_to File.basename(value.to_s), value.to_s
|
||||||
|
- when 'select'
|
||||||
|
= value
|
||||||
|
- when 'belongs_to'
|
||||||
|
= value.try(:_label)
|
||||||
|
- when 'has_many', 'many_to_many'
|
||||||
|
= value.map(&:_label).join(', ')
|
@ -25,11 +25,13 @@
|
|||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
window.application_view = new Locomotive.Views.InlinEditor.ApplicationView();
|
window.application_view = new Locomotive.Views.InlineEditor.ApplicationView();
|
||||||
window.application_view.render();
|
window.application_view.render();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
= render '/locomotive/content_assets/picker'
|
||||||
|
|
||||||
%body
|
%body
|
||||||
#page
|
#page
|
||||||
%iframe{ :src => request.fullpath.gsub('_admin', '_edit'), :scrolling => 'no', :frameborder => '0' }
|
%iframe{ :src => request.fullpath.gsub('_admin', '_edit'), :scrolling => 'no', :frameborder => '0' }
|
||||||
|
@ -9,6 +9,6 @@
|
|||||||
|
|
||||||
.span-12.last
|
.span-12.last
|
||||||
%p
|
%p
|
||||||
= submit_tag button_label.is_a?(Symbol) ? t(".#{button_label}") : button_label
|
= 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
|
@ -7,6 +7,10 @@
|
|||||||
%meta{ :name => 'key-param', :content => Rails.application.config.session_options[:key] }
|
%meta{ :name => 'key-param', :content => Rails.application.config.session_options[:key] }
|
||||||
%meta{ :name => 'key-token', :content => cookies[key] }
|
%meta{ :name => 'key-token', :content => cookies[key] }
|
||||||
|
|
||||||
|
%script{ :type => 'text/javascript' }
|
||||||
|
:plain
|
||||||
|
window.Locomotive = { mounted_on: '#{Locomotive.mounted_on}' };
|
||||||
|
|
||||||
= stylesheet_link_tag 'locomotive', :media => 'screen'
|
= stylesheet_link_tag 'locomotive', :media => 'screen'
|
||||||
= javascript_include_tag 'locomotive'
|
= javascript_include_tag 'locomotive'
|
||||||
|
|
||||||
@ -15,8 +19,7 @@
|
|||||||
window.locale = '#{I18n.locale}';
|
window.locale = '#{I18n.locale}';
|
||||||
window.content_locale = '#{::Mongoid::Fields::I18n.locale}';
|
window.content_locale = '#{::Mongoid::Fields::I18n.locale}';
|
||||||
|
|
||||||
Locomotive.mounted_on = '#{Locomotive.mounted_on}';
|
Locomotive.current_site = new Locomotive.Models.Site(#{current_site.to_presenter.as_json_for_html_view.to_json});
|
||||||
Locomotive.current_site = new Locomotive.Models.Site(#{current_site.to_json});
|
|
||||||
Locomotive.current_account = new Locomotive.Models.Account(#{current_locomotive_account.to_json});
|
Locomotive.current_account = new Locomotive.Models.Account(#{current_locomotive_account.to_json});
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
- content_for :buttons do
|
- content_for :buttons do
|
||||||
- if can?(:manage, Locomotive::ThemeAsset)
|
- if can?(:manage, Locomotive::ThemeAsset)
|
||||||
= form_tag theme_assets_url(:json), :id => 'theme-assets-quick-upload', :class => 'quick-upload' do
|
= form_tag theme_assets_url(:json), :id => 'theme-assets-quick-upload', :class => 'quick-upload', :'data-sending-form-message' => t('locomotive.messages.sending_form') do
|
||||||
= file_field_tag 'theme_asset[source]', :multiple => 'multiple'
|
= file_field_tag 'theme_asset[source]', :multiple => 'multiple'
|
||||||
= local_action_button :quick_upload, '#', :class => 'new'
|
= local_action_button :quick_upload, '#', :class => 'new'
|
||||||
|
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
Haml::Template.options[:ugly] = true
|
|
||||||
Haml::Template.options[:format] = :html5
|
Haml::Template.options[:format] = :html5
|
||||||
|
Haml::Template.options[:ugly] = true # improve performance in dev
|
||||||
|
@ -48,6 +48,7 @@ de:
|
|||||||
create: Neu
|
create: Neu
|
||||||
update: Speichern
|
update: Speichern
|
||||||
send: Senden
|
send: Senden
|
||||||
|
disable_with: "locomotive.disable_with.form_actions"
|
||||||
footer:
|
footer:
|
||||||
who_is_behind: "Dienst entwickelt von %{development} und entworfen von <a href=\"http://www.sachagreif.com\">Sacha Greif</a> — <small>version</small> %{version}"
|
who_is_behind: "Dienst entwickelt von %{development} und entworfen von <a href=\"http://www.sachagreif.com\">Sacha Greif</a> — <small>version</small> %{version}"
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ en:
|
|||||||
|
|
||||||
messages:
|
messages:
|
||||||
confirm: Are you sure ?
|
confirm: Are you sure ?
|
||||||
|
sending_form: Your form is being submitted
|
||||||
|
|
||||||
shared:
|
shared:
|
||||||
header:
|
header:
|
||||||
@ -48,6 +49,7 @@ en:
|
|||||||
create: Create
|
create: Create
|
||||||
update: Save
|
update: Save
|
||||||
send: Send
|
send: Send
|
||||||
|
disable_with: Pending...
|
||||||
list:
|
list:
|
||||||
untranslated: untranslated
|
untranslated: untranslated
|
||||||
footer:
|
footer:
|
||||||
@ -193,6 +195,7 @@ en:
|
|||||||
index:
|
index:
|
||||||
title: Listing theme files
|
title: Listing theme files
|
||||||
help: "The theme files section is the place where you manage the files needed by your layout, snippets...etc. If you need to manage an image gallery, create a new content type instead.<br/><b>Warning:</b> you may not see all the assets depending on your rights."
|
help: "The theme files section is the place where you manage the files needed by your layout, snippets...etc. If you need to manage an image gallery, create a new content type instead.<br/><b>Warning:</b> you may not see all the assets depending on your rights."
|
||||||
|
quick_upload: Quick upload
|
||||||
new: new file
|
new: new file
|
||||||
snippets: Snippets
|
snippets: Snippets
|
||||||
css_and_js: Style and javascript
|
css_and_js: Style and javascript
|
||||||
|
@ -37,6 +37,7 @@ es:
|
|||||||
account: Mi Cuenta
|
account: Mi Cuenta
|
||||||
site: Sitio
|
site: Sitio
|
||||||
theme_assets: Ficheros del Tema
|
theme_assets: Ficheros del Tema
|
||||||
|
disable_with: "locomotive.disable_with.form_actions"
|
||||||
footer:
|
footer:
|
||||||
who_is_behind: "Servicio desarrollado por %{development} y diseñado por <a href=\"http://www.sachagreif.com\">Sacha Greif</a>"
|
who_is_behind: "Servicio desarrollado por %{development} y diseñado por <a href=\"http://www.sachagreif.com\">Sacha Greif</a>"
|
||||||
form_actions:
|
form_actions:
|
||||||
|
@ -31,6 +31,7 @@ fr:
|
|||||||
|
|
||||||
messages:
|
messages:
|
||||||
confirm: "Êtes-vous sûr(e) ?"
|
confirm: "Êtes-vous sûr(e) ?"
|
||||||
|
sending_form: "Votre formulaire est en cours d'envoi"
|
||||||
|
|
||||||
shared:
|
shared:
|
||||||
header:
|
header:
|
||||||
@ -57,6 +58,7 @@ fr:
|
|||||||
create: Créer
|
create: Créer
|
||||||
update: Mettre à jour
|
update: Mettre à jour
|
||||||
send: Envoyer
|
send: Envoyer
|
||||||
|
disable_with: En cours...
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
new_content_entry:
|
new_content_entry:
|
||||||
|
@ -34,6 +34,7 @@ it:
|
|||||||
create: Crea
|
create: Crea
|
||||||
update: Salva
|
update: Salva
|
||||||
send: Invia
|
send: Invia
|
||||||
|
disable_with: "locomotive.disable_with.form_actions"
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
"500":
|
"500":
|
||||||
|
@ -31,6 +31,7 @@ nl:
|
|||||||
create: Maak
|
create: Maak
|
||||||
update: Update
|
update: Update
|
||||||
send: Verstuur
|
send: Verstuur
|
||||||
|
disable_with: "locomotive.disable_with.form_actions"
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
"500":
|
"500":
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
create: Opprett
|
create: Opprett
|
||||||
update: Lagre
|
update: Lagre
|
||||||
send: Send
|
send: Send
|
||||||
|
disable_with: "locomotive.disable_with.form_actions"
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
"500":
|
"500":
|
||||||
|
@ -31,6 +31,7 @@ pt-BR:
|
|||||||
create: Criar
|
create: Criar
|
||||||
update: Atualizar
|
update: Atualizar
|
||||||
send: Enviar
|
send: Enviar
|
||||||
|
disable_with: "locomotive.disable_with.form_actions"
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
"500":
|
"500":
|
||||||
|
@ -7,9 +7,22 @@ ru:
|
|||||||
new_item: "+ добавить"
|
new_item: "+ добавить"
|
||||||
switch_to_site: Сайт
|
switch_to_site: Сайт
|
||||||
delete: "Удалить"
|
delete: "Удалить"
|
||||||
|
close: "Закрыть"
|
||||||
|
|
||||||
|
locales:
|
||||||
|
en: Английский
|
||||||
|
de: Немецкий
|
||||||
|
fr: Французский
|
||||||
|
pt-BR: "Браз. - Португальский"
|
||||||
|
it: Итальянский
|
||||||
|
nl: Голландский
|
||||||
|
"no": Норвежский
|
||||||
|
es: Испанский
|
||||||
|
ru: Русский
|
||||||
|
|
||||||
messages:
|
messages:
|
||||||
confirm: Вы уверены ?
|
confirm: Вы уверены ?
|
||||||
|
sending_form: Ваша форма отправляется
|
||||||
|
|
||||||
shared:
|
shared:
|
||||||
header:
|
header:
|
||||||
@ -27,6 +40,10 @@ ru:
|
|||||||
account: Аккаунт
|
account: Аккаунт
|
||||||
site: Сайт
|
site: Сайт
|
||||||
theme_assets: Файлы темы
|
theme_assets: Файлы темы
|
||||||
|
form:
|
||||||
|
change_file: изменить
|
||||||
|
delete_file: удалить
|
||||||
|
cancel: отменить
|
||||||
footer:
|
footer:
|
||||||
who_is_behind: "Service developed by %{development} and designed by <a href=\"http://www.sachagreif.com\">Sacha Greif</a>"
|
who_is_behind: "Service developed by %{development} and designed by <a href=\"http://www.sachagreif.com\">Sacha Greif</a>"
|
||||||
form_actions:
|
form_actions:
|
||||||
@ -34,6 +51,9 @@ ru:
|
|||||||
create: Создать
|
create: Создать
|
||||||
update: Сохранить
|
update: Сохранить
|
||||||
send: Отправить
|
send: Отправить
|
||||||
|
disable_with: В ожидании...
|
||||||
|
list:
|
||||||
|
untranslated: непереведено
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
"500":
|
"500":
|
||||||
@ -65,9 +85,15 @@ ru:
|
|||||||
delete_file: Удалить файл
|
delete_file: Удалить файл
|
||||||
has_many:
|
has_many:
|
||||||
empty: Пусто
|
empty: Пусто
|
||||||
index:
|
new_entry: + Добавить новый элемент
|
||||||
is_required: является обязательным
|
many_to_many:
|
||||||
|
empty: Список пуст. Добавьте элемент из селекта ниже.
|
||||||
|
form:
|
||||||
|
required: Обязательное
|
||||||
|
optional: Опциональное
|
||||||
default_label: Название поля
|
default_label: Название поля
|
||||||
|
select_options:
|
||||||
|
ask_name: "Введите название элемента"
|
||||||
|
|
||||||
sessions:
|
sessions:
|
||||||
new:
|
new:
|
||||||
@ -104,7 +130,9 @@ ru:
|
|||||||
help: "Заголовок страницы может быть изменен, если кликнуть на нем. Чтобы применить изменения, нажмите кнопку \"Сохранить\"."
|
help: "Заголовок страницы может быть изменен, если кликнуть на нем. Чтобы применить изменения, нажмите кнопку \"Сохранить\"."
|
||||||
ask_for_title: "Пожалуйста введите новое имя страницы"
|
ask_for_title: "Пожалуйста введите новое имя страницы"
|
||||||
form:
|
form:
|
||||||
|
change_file: Изменить
|
||||||
delete_file: Удалить файл
|
delete_file: Удалить файл
|
||||||
|
cancel: Отмена
|
||||||
default_block: По умолчанию
|
default_block: По умолчанию
|
||||||
cache_strategy:
|
cache_strategy:
|
||||||
none: Нет
|
none: Нет
|
||||||
@ -133,11 +161,11 @@ ru:
|
|||||||
new:
|
new:
|
||||||
title: Новый сайт
|
title: Новый сайт
|
||||||
help: "Заполните форму, приведенную ниже, чтобы создать новый сайт."
|
help: "Заполните форму, приведенную ниже, чтобы создать новый сайт."
|
||||||
|
domains:
|
||||||
|
empty: "Пока нет ни одного домена, привязанного к этому сайту. Просто добавьте домены ниже. <b>Не забудьте обновить ваши DNS.</b>"
|
||||||
|
|
||||||
current_site:
|
current_site:
|
||||||
edit:
|
edit:
|
||||||
export: экспорт
|
|
||||||
import: импорт
|
|
||||||
new_membership: добавить аккаунт
|
new_membership: добавить аккаунт
|
||||||
help: "Название сайта может быть изменено, если кликнуть на нем. Чтобы применить изменения, нажмите кнопку \"Save\"."
|
help: "Название сайта может быть изменено, если кликнуть на нем. Чтобы применить изменения, нажмите кнопку \"Save\"."
|
||||||
ask_for_name: "Пожалуйста введите новое имя сайта"
|
ask_for_name: "Пожалуйста введите новое имя сайта"
|
||||||
@ -160,20 +188,13 @@ ru:
|
|||||||
edit:
|
edit:
|
||||||
help: "Вы можете изменить логин просто кликнув на нем. Чтобы применить изменения, нажмите кнопку \"Сохранить\"."
|
help: "Вы можете изменить логин просто кликнув на нем. Чтобы применить изменения, нажмите кнопку \"Сохранить\"."
|
||||||
new_site: новый сайт
|
new_site: новый сайт
|
||||||
en: Английский
|
|
||||||
de: Немецкий
|
|
||||||
fr: Французский
|
|
||||||
pt-BR: "Бразильский - Португальский"
|
|
||||||
it: Итальянский
|
|
||||||
nl: Голландский
|
|
||||||
"no": норвежский
|
|
||||||
es: Испанский
|
|
||||||
ask_for_name: "Пожалуйста введите ваш новый логин"
|
ask_for_name: "Пожалуйста введите ваш новый логин"
|
||||||
|
|
||||||
theme_assets:
|
theme_assets:
|
||||||
index:
|
index:
|
||||||
title: Список файлов темы
|
title: Список файлов темы
|
||||||
help: "Секция файлов темы это место, где вы можете управлять файлами, необходимыми для вашего шаблона, сниппетов и т.д. Если вам необходимо управление галереей изображений, создайте новый тип контента.<br/><b>Внимание:</b> вы можете не увидеть всех файлов - в зависимости от ваших прав."
|
help: "Секция файлов темы это место, где вы можете управлять файлами, необходимыми для вашего шаблона, сниппетов и т.д. Если вам необходимо управление галереей изображений, создайте новый тип контента.<br/><b>Внимание:</b> вы можете не увидеть всех файлов - в зависимости от ваших прав."
|
||||||
|
quick_upload: Быстрая загрузка
|
||||||
new: новый файл
|
new: новый файл
|
||||||
snippets: Сниппеты
|
snippets: Сниппеты
|
||||||
css_and_js: Стили и javascript
|
css_and_js: Стили и javascript
|
||||||
@ -196,29 +217,29 @@ ru:
|
|||||||
picker_link: Вставить файл в код
|
picker_link: Вставить файл в код
|
||||||
choose_file: Выбрать файл
|
choose_file: Выбрать файл
|
||||||
choose_plain_text: Выбрать простой текст
|
choose_plain_text: Выбрать простой текст
|
||||||
images:
|
image_picker:
|
||||||
title: Список изображений
|
title: "Вставить изображение"
|
||||||
no_items: "Пока нет ни одного файла."
|
no_items: "Нет ни одного изображения."
|
||||||
|
upload: "Upload theme images"
|
||||||
|
|
||||||
assets:
|
content_assets:
|
||||||
new:
|
picker:
|
||||||
title: Новый файл
|
title: "Вставьте медиа-файл"
|
||||||
help: "Заполните форму, приведенную ниже, для создания файла (asset)."
|
no_items: "Нет ни одного медиа-файла."
|
||||||
edit:
|
upload: "Загрузить медиа"
|
||||||
title: Редактировать файл
|
|
||||||
help: "Заполните форму, приведенную ниже, для изменения файла."
|
|
||||||
|
|
||||||
content_types:
|
content_types:
|
||||||
index:
|
index:
|
||||||
new: новая модель
|
new: новая модель
|
||||||
|
edit: редактировать модель
|
||||||
new:
|
new:
|
||||||
title: Новая модель
|
title: Новая модель
|
||||||
help: "Создайте ваши собственные модели данных (Проекты, Персоны, ...и т.д.). Модель должна иметь по крайней мере одно поле. Элементы, созданные из этого типа содержимого, будут иметь первое поле как обязательное."
|
help: "Создайте ваши собственные модели данных (Проекты, Персоны, ...и т.д.). Модель должна иметь по крайней мере одно поле. Элементы, созданные из этого типа содержимого, будут иметь первое поле как обязательное."
|
||||||
edit:
|
edit:
|
||||||
title: Редактирование модели
|
title: Редактирование модели
|
||||||
help: "Ваша модель должна иметь по крайней мере одно поле. Элементы, созданные из этого типа содержимого, будут иметь это поле как обязательное."
|
help: "Ваша модель должна иметь по крайней мере одно поле. Элементы, созданные из этого типа содержимого, будут иметь это поле как обязательное."
|
||||||
show_items: смотреть элементы
|
show_entries: смотреть элементы
|
||||||
new_item: новый элемент
|
new_entry: новый элемент
|
||||||
form:
|
form:
|
||||||
order_by:
|
order_by:
|
||||||
created_at: 'По дате создания'
|
created_at: 'По дате создания'
|
||||||
@ -256,23 +277,6 @@ ru:
|
|||||||
title: Кроссдоменная аутентификация
|
title: Кроссдоменная аутентификация
|
||||||
notice: Вы будете перенаправлены на вебсайт в течение нескольких секунд.
|
notice: Вы будете перенаправлены на вебсайт в течение нескольких секунд.
|
||||||
|
|
||||||
import:
|
|
||||||
new:
|
|
||||||
title: Импортировать шаблон сайта
|
|
||||||
help: "Будьте осторожны при загрузке нового шаблона для существующего сайта, ваши текущие данные могут быть изменены или даже удалены."
|
|
||||||
show:
|
|
||||||
title: Выполняется импорт
|
|
||||||
help: "Ваш сайт обновляется из zip файла темы, который вы только что загрузили. Это займет несколько секунд."
|
|
||||||
steps:
|
|
||||||
site: Информация сайта
|
|
||||||
content_types: Пользовательские типы содержимого
|
|
||||||
assets: Файлы темы
|
|
||||||
snippets: Сниппеты
|
|
||||||
pages: Страницы
|
|
||||||
messages:
|
|
||||||
success: "Ваш сайт был успешно обновлен."
|
|
||||||
failure: "Импорт не работает."
|
|
||||||
|
|
||||||
installation:
|
installation:
|
||||||
common:
|
common:
|
||||||
title: Первая установка Locomotive
|
title: Первая установка Locomotive
|
||||||
@ -288,5 +292,21 @@ ru:
|
|||||||
step_2:
|
step_2:
|
||||||
title: "Шаг 2/2 — Создайте первый сайт"
|
title: "Шаг 2/2 — Создайте первый сайт"
|
||||||
explanations: "Если вы уже загрузили шаблон сайта по умолчанию (см. инструкцию), вы можете использовать его прямо сейчас. Или вы можете загрузить шаблон сайта как zip файл (доступные бесплатные шаблоны <a href=\"http://www.locomotivecms.com/support/themes\">здесь</a>)."
|
explanations: "Если вы уже загрузили шаблон сайта по умолчанию (см. инструкцию), вы можете использовать его прямо сейчас. Или вы можете загрузить шаблон сайта как zip файл (доступные бесплатные шаблоны <a href=\"http://www.locomotivecms.com/support/themes\">здесь</a>)."
|
||||||
back_to_default_template: "Нажмите <a href='#'>здесь</a> для выбора шаблона сайта по умолчанию"
|
default_site_locale: Локаль сайта по умолчанию
|
||||||
|
default_site_locales_hints: Вы всегда можете добавить больше локалей в разделе Настройки.
|
||||||
next: Создать сайт
|
next: Создать сайт
|
||||||
|
|
||||||
|
public:
|
||||||
|
pages:
|
||||||
|
show_toolbar:
|
||||||
|
statuses:
|
||||||
|
loading: "Загрузка...."
|
||||||
|
disabled: "Встроенный редактор отключен"
|
||||||
|
labels:
|
||||||
|
save_changes: "Сохранить изменения: "
|
||||||
|
editing_mode: "Режим редактирования: "
|
||||||
|
lang: "Язык: "
|
||||||
|
buttons:
|
||||||
|
back: Назад в админку
|
||||||
|
confirm: Подтвердить
|
||||||
|
cancel: Отменить
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
ru:
|
ru:
|
||||||
|
|
||||||
errors:
|
errors:
|
||||||
messages:
|
messages:
|
||||||
domain_taken: "%{value} уже занято"
|
domain_taken: "%{value} уже занято"
|
||||||
@ -8,16 +7,15 @@ ru:
|
|||||||
protected_page: "Вы не можете удалять стартовую или 404 страницы"
|
protected_page: "Вы не можете удалять стартовую или 404 страницы"
|
||||||
extname_changed: "Новый файл не имеет оригинального расширения"
|
extname_changed: "Новый файл не имеет оригинального расширения"
|
||||||
array_too_short: "слишком мал (минимальное число элементов %{count})"
|
array_too_short: "слишком мал (минимальное число элементов %{count})"
|
||||||
liquid_syntax: "Ошибка синтаксиса Liquid ('%{error}')"
|
|
||||||
invalid_theme_file: "не может быть пустым или не является zip файлом"
|
invalid_theme_file: "не может быть пустым или не является zip файлом"
|
||||||
|
site:
|
||||||
too_short: "слишком короткий (не менее %{count} символов)"
|
default_locale_removed: Предыдущая локаль не может быть удалена.
|
||||||
blank: "не может быть пустым"
|
|
||||||
invalid: "имеет неверное значение"
|
|
||||||
confirmation: "не совпадает с подтверждением"
|
|
||||||
page:
|
page:
|
||||||
liquid_syntax: "Ошибка синтаксиса Liquid ('%{error}' в '%{fullpath}')"
|
liquid_syntax: "Ошибка синтаксиса Liquid ('%{error}' в '%{fullpath}')"
|
||||||
liquid_extend: "Страница '%{fullpath}' расширяет шаблон, который не существует"
|
liquid_extend: "Страница '%{fullpath}' наследует (расширяет) несуществующий шаблон"
|
||||||
|
liquid_translation: "Страница '%{fullpath}' наследует (расширяет) непереведенный шаблон"
|
||||||
|
too_few_custom_fields: "По крайней мере одно поле является обязательным"
|
||||||
|
security: "проблема безопасности"
|
||||||
|
|
||||||
attributes:
|
attributes:
|
||||||
defaults:
|
defaults:
|
||||||
|
@ -7,7 +7,7 @@ ru:
|
|||||||
|
|
||||||
devise:
|
devise:
|
||||||
failure:
|
failure:
|
||||||
locomotive:
|
locomotive_account:
|
||||||
unauthenticated: 'Вам необходимо войти или зарегистрироваться перед тем, как продолжить.'
|
unauthenticated: 'Вам необходимо войти или зарегистрироваться перед тем, как продолжить.'
|
||||||
unconfirmed: 'Вы должны подтвердить аккаунт перед продолжением.'
|
unconfirmed: 'Вы должны подтвердить аккаунт перед продолжением.'
|
||||||
locked: 'Ваш аккаунт заблокирован.'
|
locked: 'Ваш аккаунт заблокирован.'
|
||||||
@ -17,34 +17,34 @@ ru:
|
|||||||
timeout: 'Срок действия вашей сессии истек, пожалуйста залогиньтесь для продолжения.'
|
timeout: 'Срок действия вашей сессии истек, пожалуйста залогиньтесь для продолжения.'
|
||||||
inactive: 'Ваш аккаунт еще не был активирован.'
|
inactive: 'Ваш аккаунт еще не был активирован.'
|
||||||
sessions:
|
sessions:
|
||||||
locomotive:
|
locomotive_account:
|
||||||
signed_in: 'Вход выполнен успешно.'
|
signed_in: 'Вход выполнен успешно.'
|
||||||
signed_out: 'Выход выполнен успешно.'
|
signed_out: 'Выход выполнен успешно.'
|
||||||
passwords:
|
passwords:
|
||||||
locomotive:
|
locomotive_account:
|
||||||
send_instructions: 'Вы получите письмо с инструкциями о том, как сбросить ваш пароль, через несколько минут.'
|
send_instructions: 'Вы получите письмо с инструкциями о том, как сбросить ваш пароль, через несколько минут.'
|
||||||
updated: 'Ваш пароль был успешно изменен. Вы вошли в систему.'
|
updated: 'Ваш пароль был успешно изменен. Вы вошли в систему.'
|
||||||
confirmations:
|
confirmations:
|
||||||
locomotive:
|
locomotive_account:
|
||||||
send_instructions: 'Вы получите письмо с инструкциями о том, как подтвердить ваш аккаунт, через несколько минут.'
|
send_instructions: 'Вы получите письмо с инструкциями о том, как подтвердить ваш аккаунт, через несколько минут.'
|
||||||
confirmed: 'Ваша учетная запись была успешно подтверждена. Вы вошли в систему.'
|
confirmed: 'Ваша учетная запись была успешно подтверждена. Вы вошли в систему.'
|
||||||
registrations:
|
registrations:
|
||||||
locomotive:
|
locomotive_account:
|
||||||
signed_up: 'Вы успешно зарегистрировались.'
|
signed_up: 'Вы успешно зарегистрировались.'
|
||||||
updated: 'Вы успешно обновили ваш аккаунт.'
|
updated: 'Вы успешно обновили ваш аккаунт.'
|
||||||
destroyed: 'До свидания! Ваш аккаунт был успешно отменен. Мы надеемся скоро увидеть вас снова.'
|
destroyed: 'До свидания! Ваш аккаунт был успешно отменен. Мы надеемся скоро увидеть вас снова.'
|
||||||
unlocks:
|
unlocks:
|
||||||
locomotive:
|
locomotive_account:
|
||||||
send_instructions: 'Вам будет отправлено письмо с инструкциями о том, как разблокировать ваш аккаунт, в течение нескольких минут.'
|
send_instructions: 'Вам будет отправлено письмо с инструкциями о том, как разблокировать ваш аккаунт, в течение нескольких минут.'
|
||||||
unlocked: 'Ваша учетная запись была успешно разблокирована. Вы вошли в систему.'
|
unlocked: 'Ваша учетная запись была успешно разблокирована. Вы вошли в систему.'
|
||||||
mailer:
|
mailer:
|
||||||
locomotive:
|
locomotive_account:
|
||||||
confirmation_instructions: 'Инструкции подтверждения'
|
confirmation_instructions: 'Инструкции подтверждения'
|
||||||
reset_password_instructions: 'Инструкции по сбросу пароля'
|
reset_password_instructions: 'Инструкции по сбросу пароля'
|
||||||
unlock_instructions: 'Инструкции по разблокированию'
|
unlock_instructions: 'Инструкции по разблокированию'
|
||||||
|
|
||||||
|
|
||||||
locomotive:
|
locomotive_account:
|
||||||
mailer:
|
mailer:
|
||||||
common:
|
common:
|
||||||
hello: Здравствуйте
|
hello: Здравствуйте
|
||||||
|
@ -33,35 +33,39 @@ ru:
|
|||||||
custom_fields:
|
custom_fields:
|
||||||
field:
|
field:
|
||||||
name: Алиас
|
name: Алиас
|
||||||
import:
|
|
||||||
new:
|
|
||||||
source: Файл
|
|
||||||
samples: Копировать образцы
|
|
||||||
reset: Сбросить сайт
|
|
||||||
default_site_template: "Используйте шаблон сайта по умолчанию. Нажмите <a href='#'>здесь</a> для загрузки шаблона сайта в виде zip файла."
|
|
||||||
content_type:
|
content_type:
|
||||||
item_template: Шаблон элемента
|
raw_item_template: Шаблон элемента
|
||||||
api_accounts: Уведомленные аккаунты
|
public_submission_enabled: Публичное представление
|
||||||
|
public_submission_accounts: Уведомленные аккаунты
|
||||||
|
"custom_fields/field":
|
||||||
|
select_options: "Опции"
|
||||||
content_entry:
|
content_entry:
|
||||||
_slug: Постоянная ссылка
|
_slug: Постоянная ссылка
|
||||||
account:
|
account:
|
||||||
edit:
|
edit:
|
||||||
|
locale: Язык интерфейса пользователя
|
||||||
password: Новый пароль
|
password: Новый пароль
|
||||||
password_confirmation: Подтверждение нового пароля
|
password_confirmation: Подтверждение нового пароля
|
||||||
page:
|
page:
|
||||||
seo_title: Название
|
seo_title: Название
|
||||||
|
target_klass_name: Model
|
||||||
|
site:
|
||||||
|
locales: Языки
|
||||||
|
|
||||||
hints:
|
hints:
|
||||||
page:
|
page:
|
||||||
|
handle: "Уникальный идентификатор для поиска этой страницы из экземпляра внешнего rails-контроллера"
|
||||||
published: "Только аутентифицированным пользователям разрешается просматривать неопубликованные страницы."
|
published: "Только аутентифицированным пользователям разрешается просматривать неопубликованные страницы."
|
||||||
cache_strategy: "Кэшировать страницу для лучшей производительности. Вариант 'Простое' является хорошим компромиссом."
|
cache_strategy: "Кэшировать страницу для лучшей производительности. Вариант 'Простое' является хорошим компромиссом."
|
||||||
listed: "Контролируйте возможность показа страницы из сгенерированных меню."
|
listed: "Контролируйте возможность показа страницы из сгенерированных меню."
|
||||||
|
target_klass_name: "Тип контента (модели), для которого эта страница будет выступать в качестве шаблона."
|
||||||
seo_title: "Определите заголовок страницы, который будет использоваться как значение тэга title в секции head. Оставьте пустым, если вы хотите использовать значение по умолчанию из настроек сайта."
|
seo_title: "Определите заголовок страницы, который будет использоваться как значение тэга title в секции head. Оставьте пустым, если вы хотите использовать значение по умолчанию из настроек сайта."
|
||||||
meta_keywords: "Переопределяет meta keywords сайта, используемые внутри тэга head страницы. Они разделены запятыми."
|
meta_keywords: "Переопределяет meta keywords сайта, используемые внутри тэга head страницы. Они разделены запятыми."
|
||||||
meta_description: "Переопределяет meta description сайта, используемые внутри тэга head страницы."
|
meta_description: "Переопределяет meta description сайта, используемые внутри тэга head страницы."
|
||||||
snippet:
|
snippet:
|
||||||
slug: "Вам необходимо знать это для вставки сниппета в страницу"
|
slug: "Вам необходимо знать это для вставки сниппета в страницу"
|
||||||
site:
|
site:
|
||||||
|
locales: "Перетащите и отпустите флаг на первую позицию, чтобы сделать ее локалью по умолчанию."
|
||||||
seo_title: "Задайте глобальное значение здесь, которое будет использовано как значение для тэга title в секции head."
|
seo_title: "Задайте глобальное значение здесь, которое будет использовано как значение для тэга title в секции head."
|
||||||
meta_keywords: "Meta keywords используются внутри тэга head страницы. Они разделяются запятыми. Требуется для SEO."
|
meta_keywords: "Meta keywords используются внутри тэга head страницы. Они разделяются запятыми. Требуется для SEO."
|
||||||
meta_description: "Meta description используются для тэга head страницы. Необходимо для SEO."
|
meta_description: "Meta description используются для тэга head страницы. Необходимо для SEO."
|
||||||
@ -77,10 +81,6 @@ ru:
|
|||||||
source: "Текущий файл доступен здесь %{url}"
|
source: "Текущий файл доступен здесь %{url}"
|
||||||
update:
|
update:
|
||||||
source: "Текущий файл доступен здесь %{url}"
|
source: "Текущий файл доступен здесь %{url}"
|
||||||
custom_fields:
|
|
||||||
field:
|
|
||||||
name: "Свойство, доступное в шаблонах liquid"
|
|
||||||
hint: "Текст, отображенный в форме модели, находится ниже поля"
|
|
||||||
content_entry:
|
content_entry:
|
||||||
_slug: "Свойство, используемое для генерации ссылки (url) на страницу, работающей как шаблон для этого типа содержимого (ex: \"template_page/{{ your_object._permalink }})\"."
|
_slug: "Свойство, используемое для генерации ссылки (url) на страницу, работающей как шаблон для этого типа содержимого (ex: \"template_page/{{ your_object._permalink }})\"."
|
||||||
seo_title: "Значение, вводимое вами, будет заменять SEO заголовок шаблонизированной страницы, связанной с вашей моделью."
|
seo_title: "Значение, вводимое вами, будет заменять SEO заголовок шаблонизированной страницы, связанной с вашей моделью."
|
||||||
@ -91,7 +91,12 @@ ru:
|
|||||||
samples: "Если включено, процесс импорта также скопирует содержимое и файлы"
|
samples: "Если включено, процесс импорта также скопирует содержимое и файлы"
|
||||||
reset: "Если включено, все данные вашего сайта будут уничтожены перед импортом нового сайта"
|
reset: "Если включено, все данные вашего сайта будут уничтожены перед импортом нового сайта"
|
||||||
content_type:
|
content_type:
|
||||||
item_template: "Вы можете задавать текст, отображаемый для каждого элемента в списке. Просто используйте Liquid. Пр.: {{ entry.name }})"
|
name: "Необходимо вводить название модели во множественном числе. Например: Projects, Recipes, Posts, Articles, ...и т.д."
|
||||||
api_enabled: "Это используется для того, чтобы дать людям извне возможность создавать новые экземляры (пример: сообщения в форме контакта)"
|
slug: "Поле будет использовано как имя коллекции в шаблонах liquid. Пр.: <span class='code'>{{ contents.my_projects }}</span>"
|
||||||
api_accounts: "Письмо с уведомлением будет отправлено на каждый аккаунт из списка выше, когда создан новый экземпляр"
|
raw_item_template: "Вы можете задавать текст, отображаемый для каждого элемента в списке. Просто используйте Liquid. Пр.: {{ entry.name }})"
|
||||||
|
public_submission_enabled: "Это используется для того, чтобы дать людям извне возможность создавать новые экземляры (пример: сообщения в форме контакта)"
|
||||||
|
public_submission_accounts: "Письмо с уведомлением будет отправлено на каждый аккаунт из списка выше каждый раз, когда создается новый экземпляр (если включена опция публичного представления)"
|
||||||
|
"custom_fields/field":
|
||||||
|
name: "Имя свойства для шаблонов liquid. Пр.: <span class='code'>{{ your_object.<name_of_your_field> }}</span>"
|
||||||
|
hint: "Текст-подсказка, отображаемый на форме модели под полем"
|
||||||
|
|
||||||
|
422
doc/TODO
422
doc/TODO
@ -9,3 +9,425 @@ x page with regexp url => wildcards
|
|||||||
- find_spec
|
- find_spec
|
||||||
- features
|
- features
|
||||||
- clean code
|
- clean code
|
||||||
|
x namespace assets
|
||||||
|
x bugs:
|
||||||
|
x toggler
|
||||||
|
x advanced options (redirect url missing)
|
||||||
|
x locomotive_media (not animating on open)
|
||||||
|
x undefined method `_selector' for #<Locomotive::Page:0x00000107434768>
|
||||||
|
x editable_elements => view + handlebar template
|
||||||
|
x editable_short_text => tinymce
|
||||||
|
x editable_file =>
|
||||||
|
x backbone / handlebar
|
||||||
|
x new formtastic inputs
|
||||||
|
x menu / submenu in full css3 (no images)
|
||||||
|
x fix css in firefox
|
||||||
|
x update page in ajax
|
||||||
|
x edit my site
|
||||||
|
x css
|
||||||
|
x robots.txt
|
||||||
|
x domains
|
||||||
|
x roles
|
||||||
|
x save
|
||||||
|
x fix other sections
|
||||||
|
x edit my account
|
||||||
|
x create a new site
|
||||||
|
x create a new accounts
|
||||||
|
x theme assets
|
||||||
|
x polish the page
|
||||||
|
x snippets
|
||||||
|
x delete in ajax
|
||||||
|
x upload many files at once
|
||||||
|
x import/export
|
||||||
|
x export
|
||||||
|
x site picker
|
||||||
|
x content types
|
||||||
|
x move content instances into their own collection
|
||||||
|
x manage custom_fields
|
||||||
|
x automatic name
|
||||||
|
x required
|
||||||
|
x editable plugin: add class depending on the type => surrounding span instead
|
||||||
|
x position
|
||||||
|
x open the nested form
|
||||||
|
x remove an entry
|
||||||
|
x look n feel
|
||||||
|
x display errors
|
||||||
|
x slugify
|
||||||
|
x refactor highlighted_field (field id instead of name)
|
||||||
|
x other content type options
|
||||||
|
x show / hide options of a field based on its type
|
||||||
|
x select: add/edit/remove options
|
||||||
|
x text: formatting
|
||||||
|
x change in main menu
|
||||||
|
x manage contents
|
||||||
|
x list (highlighted field)
|
||||||
|
x slugify
|
||||||
|
x crud
|
||||||
|
x new
|
||||||
|
x date
|
||||||
|
x checkbox
|
||||||
|
x html
|
||||||
|
x file
|
||||||
|
x edit
|
||||||
|
x destroy
|
||||||
|
x public_form (previously api something)
|
||||||
|
x bug text formatting
|
||||||
|
x custom_fields: use the appropriate icon to drag select options
|
||||||
|
x bug ui with contents popup
|
||||||
|
x use list_or_group_entries instead of ordered_entries
|
||||||
|
x i18n
|
||||||
|
x add locales a site responds to
|
||||||
|
x locale switcher
|
||||||
|
x constraint: one locale at least
|
||||||
|
x front
|
||||||
|
x pages
|
||||||
|
x inline-editor
|
||||||
|
x back to default locale (if changed in settings) and when creating new pages / entries
|
||||||
|
- inline editor
|
||||||
|
x rack
|
||||||
|
x iframe
|
||||||
|
(- remove inline-editor tag)
|
||||||
|
x save editable elements
|
||||||
|
x notification (growl)
|
||||||
|
x change page
|
||||||
|
x i18n
|
||||||
|
- style the "ADMIN" button
|
||||||
|
- aloha:
|
||||||
|
x remove sidebar
|
||||||
|
- i18n
|
||||||
|
- insert image
|
||||||
|
x deployment
|
||||||
|
x fix integration problems
|
||||||
|
x pre-compile assets
|
||||||
|
x API
|
||||||
|
x authentication from a token + controller to deliver a token
|
||||||
|
x api routes
|
||||||
|
x change api location
|
||||||
|
(- add a way to custom the as_json method within the presenters (by default as_json ?) + custom responder ?)
|
||||||
|
x REST actions:
|
||||||
|
x CRUD theme assets
|
||||||
|
x CRUD snippets
|
||||||
|
x CRUD content assets
|
||||||
|
x CRUD pages
|
||||||
|
x CRUD content types
|
||||||
|
x data ?
|
||||||
|
x script to migrate existing site
|
||||||
|
x i18n
|
||||||
|
x upgrade to rails 3.2 (https://github.com/locomotivecms/engine/pull/281/files)
|
||||||
|
x missing custom_fields
|
||||||
|
x belongs_to
|
||||||
|
x has_many
|
||||||
|
x many_to_many
|
||||||
|
x simplify cells integration when modifying a menu from the main app
|
||||||
|
x heroku module for locomotive
|
||||||
|
x refactoring
|
||||||
|
x remove the import / export scripts
|
||||||
|
x remove the cross domain authentication (use auth_token instead)
|
||||||
|
x where to put Locomotive::InlineEditorMiddleware ?
|
||||||
|
x global regions: keyword in editable element (http://www.mongodb.org/display/DOCS/Updating)
|
||||||
|
x override sort for contents
|
||||||
|
|
||||||
|
- bugs / ui tweaks
|
||||||
|
x unable to toggle the "required" check_boxes for content types
|
||||||
|
x unable to sign out
|
||||||
|
x unable to remove a field
|
||||||
|
x "back to admin" link does not work if inline editor disabled
|
||||||
|
x unable to delete memberships
|
||||||
|
x disallow to click twice on the submit form button (spinner ?)
|
||||||
|
x weird behaviour when changing the default locale of a site
|
||||||
|
- editable_elements does not display the first time they get created (and if there are no existing ones)
|
||||||
|
- display by categories does not work when localized
|
||||||
|
- message to notify people if their browser is too old
|
||||||
|
|
||||||
|
? install a site by default at the first installation (without asking)
|
||||||
|
|
||||||
|
BACKLOG:
|
||||||
|
|
||||||
|
- custom_fields:
|
||||||
|
- validation: regexp (pre-defined regexps ?)
|
||||||
|
x new type: belongs_to => association
|
||||||
|
- inline editing (http://www.aloha-editor.com/wiki/index.php/Aloha_PHP_Example)
|
||||||
|
- html view in the aloha popup
|
||||||
|
- editable elements should wrap a tag: div, h1, ...etc (default span)
|
||||||
|
- edit images (upload new ones, ...etc) => wait for aloha or send them an email ?
|
||||||
|
- cucumber features for admin pages (in progress)
|
||||||
|
(- duostack/doutcloud version)
|
||||||
|
- write my first tutorial about locomotive
|
||||||
|
- upgrade warning if new version of locomotive (maybe based on the commit id)
|
||||||
|
- deploying workflow:
|
||||||
|
- roll back a bad update
|
||||||
|
- conflicts with content types
|
||||||
|
- dev -> staging -> production
|
||||||
|
- sync data
|
||||||
|
- import only theme assets
|
||||||
|
- endless pagination
|
||||||
|
|
||||||
|
- tooltip to explain the difference between 1.) Admin 2.) Author 3.) Designer?
|
||||||
|
- [bushido] guiders / welcome page / devise cas authentication (SSO)
|
||||||
|
|
||||||
|
REFACTORING:
|
||||||
|
|
||||||
|
- move content_type and content_instances in the CustomFields plugin (much more appropriate)
|
||||||
|
|
||||||
|
BUGS:
|
||||||
|
x mode author: settings KO + editable elements non visibles
|
||||||
|
x locales pour le locomotive editor => KO
|
||||||
|
! impossible de sauvegarder une page
|
||||||
|
|
||||||
|
|
||||||
|
NICE TO HAVE:
|
||||||
|
- export site
|
||||||
|
- super_finder
|
||||||
|
- traffic statistics
|
||||||
|
- asset picker (content instance)
|
||||||
|
- page with regexp url ?
|
||||||
|
- automatic update !
|
||||||
|
- page not found (front) => if logged in, link to create the page
|
||||||
|
- switch to list (theme assets / assets ?). delete all in once (with checkbox) or see details (updated_at, size, ...etc)
|
||||||
|
- code completion ? http://blog.quplo.com/2010/06/common-sense-code-completion/
|
||||||
|
|
||||||
|
DONE:
|
||||||
|
|
||||||
|
x tiny mce or similar for custom field text type.
|
||||||
|
x refactor custom field types
|
||||||
|
x new custom field types
|
||||||
|
x boolean
|
||||||
|
x enable/disable text formatting
|
||||||
|
x custom fields for asset collections
|
||||||
|
x [BUG] impossible to remove many assets in an asset collection
|
||||||
|
x new custom field type: date
|
||||||
|
x missing key: en, admin, theme_assets, images, no_items
|
||||||
|
x new custom field type: file
|
||||||
|
x update custom_fields plugin
|
||||||
|
x locomotive ui
|
||||||
|
x liquid templates
|
||||||
|
x rss parser
|
||||||
|
x localize application in French
|
||||||
|
x default
|
||||||
|
x devise
|
||||||
|
x carrierwave
|
||||||
|
x localize devise emails
|
||||||
|
x admin
|
||||||
|
x change credits in the admin footer
|
||||||
|
x license
|
||||||
|
x textile filter
|
||||||
|
x [bug] varnish can not be refreshed in heroku so "max-age" has to be disabled => modify cache strategy
|
||||||
|
x "remember me" should always be enabled
|
||||||
|
x sitemap
|
||||||
|
x refactoring admin crud (pages + layouts + snippets)
|
||||||
|
x flash messages in French
|
||||||
|
x save layout / snippet / page / stylesheet / javascript with CMD + S (ajax)
|
||||||
|
x change action icons according to the right action [Sacha]
|
||||||
|
x publish event when saving form in ajax (for instance, in order to update account name or site name)
|
||||||
|
x page templatized (bound to a model)
|
||||||
|
x theme asset picker when editing layout / snippet
|
||||||
|
x templatized: do not display content with visible / active set to false
|
||||||
|
x theme assets: disable version if not image (handled by the new version of Carrierwave)
|
||||||
|
x rack app to map pretty asset url to S3 => shortcut urls instead
|
||||||
|
x site selector (cross domain authentication)
|
||||||
|
x nice error page
|
||||||
|
x nice 404 page (admin section)
|
||||||
|
x liquid inheritance
|
||||||
|
x bug editable_xxx disabled for nil block
|
||||||
|
! duplicated block name
|
||||||
|
x display liquid errors
|
||||||
|
x theme assets selector in page editor
|
||||||
|
x saving page in ajax
|
||||||
|
x editable_long_text tag
|
||||||
|
x blocking issue when modifying the parent of 2 templates => one of the 2 children has reference of the first child
|
||||||
|
x editable_file tag
|
||||||
|
x stylish file field
|
||||||
|
x remove not used editable element all in once
|
||||||
|
x default content from parent editable element
|
||||||
|
x unable to upload/remove editable file
|
||||||
|
x customize tinyMCE: no html popup => div popup, nice icons
|
||||||
|
x add images / files inside long text element (back-office side at first ?)
|
||||||
|
x create a repo for a tool "a la" vision
|
||||||
|
x asset collections => liquid
|
||||||
|
x images tag to write
|
||||||
|
! apply http://github.com/flori/json/commit/2c0f8d2c9b15a33b8d10ffcb1959aef54d320b57
|
||||||
|
x snippet dependencies => do not work correctly
|
||||||
|
? google analytics tag
|
||||||
|
x mask internal asset_collections
|
||||||
|
x refactor ui for the theme assets page
|
||||||
|
x fix assets liquid tags / filters
|
||||||
|
x upload and insert new images in a css or js from the ui is broken
|
||||||
|
x proxy for fonts (http://markevans.github.com/dragonfly/file.Rails3.html)
|
||||||
|
x order yaml file (http://www.ruby-forum.com/topic/120295)
|
||||||
|
x fix tests
|
||||||
|
x inline editing (http://www.aloha-editor.com/wiki/index.php/Aloha_PHP_Example)
|
||||||
|
x spinner
|
||||||
|
x save automatically (callback) => store modifications
|
||||||
|
x admin buttons
|
||||||
|
x edit page
|
||||||
|
x save / cancel
|
||||||
|
x back to back-office => admin settings of the page
|
||||||
|
(- duplicate page ?)
|
||||||
|
(- super bonus statistics)
|
||||||
|
x locale
|
||||||
|
x store page toolbar status in cookie
|
||||||
|
x trim short text content
|
||||||
|
x namespace js functions
|
||||||
|
x import tool:
|
||||||
|
x select field (see custom fields and nocoffee theme) ?
|
||||||
|
x disable sub tasks by passing options
|
||||||
|
x exceptions
|
||||||
|
x page to import theme
|
||||||
|
x contents: group_by, oder_by, api_enabled
|
||||||
|
x folders for theme assets
|
||||||
|
x theme assets whitelist
|
||||||
|
x fonts
|
||||||
|
x asset collections
|
||||||
|
x rewrite the unzip process (for the import)
|
||||||
|
x bug with asset collections (assets disappear if we save the collection ?!)
|
||||||
|
x import tool:
|
||||||
|
x asset whitelist
|
||||||
|
x do not override existing site name
|
||||||
|
x add samples option
|
||||||
|
x content types
|
||||||
|
x asset collections
|
||||||
|
x page templatized (tied to content type)
|
||||||
|
x remove existing pages / contents option => reset
|
||||||
|
x give choice to reset site / add samples
|
||||||
|
x french translatations
|
||||||
|
x cosmetic / ui bugs / bugs:
|
||||||
|
x segmentation fault with with_scope
|
||||||
|
x paginate is not working
|
||||||
|
x redirection in dev does not work correctly for cross domain
|
||||||
|
x drag&drop for assets ('last' class issue)
|
||||||
|
x increase the input field width for domain names
|
||||||
|
x assets within custom contents are not deleted when the whole content type gets destroyed (after_destroy callback ?)
|
||||||
|
x api
|
||||||
|
x handle html request (for now, it's just json)
|
||||||
|
x installation guide
|
||||||
|
x detect if new installation
|
||||||
|
x no-site error redirects to the first step
|
||||||
|
x steps:
|
||||||
|
x welcome: domains, ...etc
|
||||||
|
x Create account
|
||||||
|
x Create new site (name, subdomain) / Import theme (worker or list of sites from fs)
|
||||||
|
x import:
|
||||||
|
x ordered pages ?
|
||||||
|
x order_by for content_types ? created_at, updated_at
|
||||||
|
x liquid:
|
||||||
|
x nav
|
||||||
|
x no_wrapper option
|
||||||
|
x regexp to get rid of some pages
|
||||||
|
x filters
|
||||||
|
x default_pagination: labels
|
||||||
|
x [content types] the "display column" selector should not include file types
|
||||||
|
x Worker => Heroku / S3 (not so sure finally)
|
||||||
|
x jammit-s3: assets
|
||||||
|
x copy assets.yml config file when using it as gem (http://asciicasts.com/episodes/218-making-generators-in-rails-3)
|
||||||
|
x import theme without delayed_job
|
||||||
|
x rspec 2.3
|
||||||
|
x ruby 1.9.2:
|
||||||
|
x DelayedJob not working
|
||||||
|
x new version of Aloha-Editor
|
||||||
|
x locomotive gem: test with staging
|
||||||
|
x nav tag:
|
||||||
|
x site | page | parent
|
||||||
|
x retrieve only important page information from mongodb
|
||||||
|
x published by default when importing pages
|
||||||
|
x page redirection
|
||||||
|
x notify accounts when new instance of models (opt): none, one or many accounts. Used for contact form.
|
||||||
|
x implementation
|
||||||
|
x emails
|
||||||
|
x tests
|
||||||
|
x fix bug issue about (custom fields)
|
||||||
|
x moving to mongoid 2.0.0 rc.6
|
||||||
|
x accepts_nested_attributes (javascript part)
|
||||||
|
x check the theme uploader
|
||||||
|
x release new version of CustomFields, ActsAsTree gems
|
||||||
|
x add metadata to sites
|
||||||
|
x pull requests #31 et #32
|
||||||
|
x password / new_password
|
||||||
|
x bugs
|
||||||
|
x custom_fields not deleted (doesn't use index anymore)
|
||||||
|
? editable_elements slug becomes nil
|
||||||
|
x editable_elements not updated (doesn't use index anymore)
|
||||||
|
x uploading videos http://groups.google.com/group/carrierwave/browse_thread/thread/6e211d98f1ff4bc0/51717c2167695ca2?lnk=gst&q=version#51717c2167695ca2
|
||||||
|
x custom fields: accepts_nested_attributes weird behaviour when creating new content type + adding random fields
|
||||||
|
x better icons for mime type (css3)
|
||||||
|
x validation for custom fields: required done
|
||||||
|
x pull request #44
|
||||||
|
x bug on dates (https://github.com/locomotivecms/engine/issues#issue/48)
|
||||||
|
x generated sitemaps are invalid (url + date)
|
||||||
|
x integrate new locomotivecms home
|
||||||
|
x seo section for the page form: seo title, seo keywords, seo description
|
||||||
|
x bugs: #50, #51
|
||||||
|
x 2 different sites on the same main domain (one in www, the other one in something else) (Raphael Costa)
|
||||||
|
! asset collections: custom resizing if image
|
||||||
|
x bushido version
|
||||||
|
x default template
|
||||||
|
~ editable_elements: inheritable: false (Mattias) => seems to be fixed by Dirk's last pull request (#44) => content tag
|
||||||
|
x resizing images on the fly
|
||||||
|
x locomedia tinyMCE plugin (Bernd)
|
||||||
|
x remove asset_collections
|
||||||
|
x site templates
|
||||||
|
x tinyMCE plugin
|
||||||
|
x vignette.rb
|
||||||
|
x code
|
||||||
|
x helpers
|
||||||
|
x ui
|
||||||
|
x rake task
|
||||||
|
x internal collection
|
||||||
|
x assign same _id
|
||||||
|
x pick up a theme_asset
|
||||||
|
x pull request locomedia
|
||||||
|
x refactor slugify method (use parameterize + create a module)
|
||||||
|
x contents permalink (UI)
|
||||||
|
x BUG: has_one / has_many. Delete an author
|
||||||
|
x bushido changes in the master
|
||||||
|
? edit sidebar (inline editor). Unable to reset it
|
||||||
|
x SEO: support and support/ should be 2 different pages. Remove trailing slash
|
||||||
|
x issue #91: httparty
|
||||||
|
x issue #90: seo metadata
|
||||||
|
x issue #57: seo page title
|
||||||
|
x issue #56
|
||||||
|
x tweak ui: form, quick link to edit a model in the popup menu
|
||||||
|
x Has_one => group by in the select
|
||||||
|
x better hints:
|
||||||
|
x notify the user that after changing the page title, they still have to click "update" for the change to be saved
|
||||||
|
x created_by ASC => "Creation date ascending"
|
||||||
|
x cancan: (authors / designers / admin)
|
||||||
|
x model
|
||||||
|
x ui
|
||||||
|
x controllers / views:
|
||||||
|
x page
|
||||||
|
x content / content type
|
||||||
|
x asset
|
||||||
|
x site
|
||||||
|
x account
|
||||||
|
x snippet
|
||||||
|
x theme asset
|
||||||
|
x features / specs
|
||||||
|
x enable rack-cache only for a specific url
|
||||||
|
x more cucumber tests for the content types
|
||||||
|
x check hosting:
|
||||||
|
x heroku
|
||||||
|
x bushi.do
|
||||||
|
x unable to reach the console
|
||||||
|
x deploy => okay
|
||||||
|
x unable to set a new subdomain
|
||||||
|
x liquid tag: Date.today (now), add a test to compare 2 dates
|
||||||
|
? better ui: increase text field length (auto sizable ?) + refactor error message
|
||||||
|
- trigger refresh at startup
|
||||||
|
x bugs
|
||||||
|
x heroku: unable to upload a new file => okay
|
||||||
|
x import => okay
|
||||||
|
x delete an item => okay
|
||||||
|
x bug: duplicate fields (new entry) when errors in the content type form
|
||||||
|
x tinyMCE => fullscreen
|
||||||
|
x export site
|
||||||
|
x rake task to import a remote template
|
||||||
|
x MERGE
|
||||||
|
x remove withelist for assets since we've got now roles
|
||||||
|
x admin role is not correctly set when creating a new website
|
||||||
|
x the required star for file field is not shown
|
||||||
|
x Rights to set roles (ticket #104)
|
||||||
|
x export: problems with templatized pages (source => multi levels pages)
|
||||||
|
x do not rename files for fonts
|
||||||
|
x icon for redirection page in the pages section (back-office)
|
||||||
|
x installed on heroku with source
|
||||||
|
x test and/or convert existing templates (the 2 of the themes section)
|
||||||
|
19
features/api/authentication.feature
Normal file
19
features/api/authentication.feature
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Feature: Authentication
|
||||||
|
In order to consume the API
|
||||||
|
As an admin
|
||||||
|
I need to get an authentication token
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given I have the site: "test site" set up
|
||||||
|
|
||||||
|
Scenario: Fail to get a token without an email and a password
|
||||||
|
When I post to "/locomotive/api/tokens.json"
|
||||||
|
Then the JSON response at "message" should be "The request must contain the user email and password."
|
||||||
|
|
||||||
|
Scenario: Get a token
|
||||||
|
When I post to "/locomotive/api/tokens.json" with:
|
||||||
|
"""
|
||||||
|
{ "email": "admin@locomotiveapp.org", "password": "easyone" }
|
||||||
|
"""
|
||||||
|
Then the JSON response at "token" should be a string
|
||||||
|
And the JSON response should not have "message"
|
29
features/api/pages.feature
Normal file
29
features/api/pages.feature
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
Feature: Pages
|
||||||
|
In order to access the Page resources
|
||||||
|
As an admin
|
||||||
|
I will perform the basic RESTFUL actions on them
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given I have the site: "test site" set up
|
||||||
|
And I have an "admin" API token
|
||||||
|
And a page named "hello world" with the template:
|
||||||
|
"""
|
||||||
|
Hello world :-)
|
||||||
|
"""
|
||||||
|
And a page named "goodbye-world" with the template:
|
||||||
|
"""
|
||||||
|
Goodbye world :-(
|
||||||
|
"""
|
||||||
|
|
||||||
|
Scenario: Protect the pages resources if not authenticated
|
||||||
|
Given I do not have an API token
|
||||||
|
When I visit "/locomotive/api/pages.json"
|
||||||
|
Then the JSON response at "error" should be "You need to sign in or sign up before continuing."
|
||||||
|
|
||||||
|
Scenario: Accessing pages
|
||||||
|
When I visit "/locomotive/api/pages.json"
|
||||||
|
Then the JSON should have the following:
|
||||||
|
| 0/fullpath | "index" |
|
||||||
|
| 1/fullpath | "hello-world" |
|
||||||
|
| 2/fullpath | "404" |
|
||||||
|
| 3/fullpath | "goodbye-world" |
|
13
features/backoffice/mounting.feature
Normal file
13
features/backoffice/mounting.feature
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
Feature: Mounting Locomotive CMS
|
||||||
|
As an administrator
|
||||||
|
In order to gain some flexibility when mounting locomotive CMS
|
||||||
|
I want to be able to mount locomotove on any given path
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given I have a site set up
|
||||||
|
|
||||||
|
@javascript
|
||||||
|
Scenario: Accessing the backend when mounted on a custom path
|
||||||
|
Given the engine is mounted on a non standard path
|
||||||
|
And I am an authenticated "admin"
|
||||||
|
Then I should be able to access the backend
|
62
features/public/contact_form.feature
Normal file
62
features/public/contact_form.feature
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
Feature: Contact form
|
||||||
|
As a visitor
|
||||||
|
In order to keep in touch with the site
|
||||||
|
I want to be able to send them a message
|
||||||
|
|
||||||
|
Background:
|
||||||
|
Given I have the site: "test site" set up
|
||||||
|
And I have a custom model named "Messages" with
|
||||||
|
| label | type | required |
|
||||||
|
| Email | string | true |
|
||||||
|
| Message | text | true |
|
||||||
|
And I enable the public submission of the "Messages" model
|
||||||
|
And a page named "contact" with the template:
|
||||||
|
"""
|
||||||
|
<html>
|
||||||
|
<head></head>
|
||||||
|
<body>
|
||||||
|
<form action="{{ contents.messages.public_submission_url }}" method="post">
|
||||||
|
<input type="hidden" value="/success" name="success_callback" />
|
||||||
|
<input type="hidden" value="/contact" name="error_callback" />
|
||||||
|
<label for="email">E-Mail Address</label>
|
||||||
|
<input type="text" id="email" name="content[email]" />
|
||||||
|
{% if message.errors.email %}Email is required{% endif %}
|
||||||
|
<label for="message">Message</label>
|
||||||
|
<textarea name="content[message]" id="message"></textarea>
|
||||||
|
<input name="submit" type="submit" id="submit" value="Submit" />
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
"""
|
||||||
|
And a page named "success" with the template:
|
||||||
|
"""
|
||||||
|
Thanks {{ message.email }}
|
||||||
|
"""
|
||||||
|
|
||||||
|
Scenario: Setting the right url for the contact form
|
||||||
|
When I view the rendered page at "/contact"
|
||||||
|
Then the rendered output should look like:
|
||||||
|
"""
|
||||||
|
<form action="http://test.example.com/entry_submissions/messages" method="post">
|
||||||
|
"""
|
||||||
|
|
||||||
|
Scenario: Prevents users to post messages if the public submission option is disabled
|
||||||
|
Given I disable the public submission of the "Messages" model
|
||||||
|
When I view the rendered page at "/contact"
|
||||||
|
And I fill in "E-Mail Address" with "did@locomotivecms.com"
|
||||||
|
And I fill in "Message" with "LocomotiveCMS rocks"
|
||||||
|
And I press "Submit"
|
||||||
|
Then I should not see "Thanks did@locomotivecms.com"
|
||||||
|
|
||||||
|
Scenario: Sending a message with success
|
||||||
|
When I view the rendered page at "/contact"
|
||||||
|
And I fill in "E-Mail Address" with "did@locomotivecms.com"
|
||||||
|
And I fill in "Message" with "LocomotiveCMS rocks"
|
||||||
|
And I press "Submit"
|
||||||
|
Then I should see "Thanks did@locomotivecms.com"
|
||||||
|
|
||||||
|
Scenario: Display errors
|
||||||
|
When I view the rendered page at "/contact"
|
||||||
|
And I fill in "Message" with "LocomotiveCMS rocks"
|
||||||
|
And I press "Submit"
|
||||||
|
Then I should see "Email is required"
|
38
features/step_definitions/api_steps.rb
Normal file
38
features/step_definitions/api_steps.rb
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
def last_json
|
||||||
|
@json_response.try(:body) || page.source
|
||||||
|
end
|
||||||
|
|
||||||
|
Given /^I have an? "([^"]*)" API token$/ do |role|
|
||||||
|
@membership = Locomotive::Site.first.memberships.where(:role => role.downcase).first \
|
||||||
|
|| FactoryGirl.create(role.downcase.to_sym, :site => Locomotive::Site.first)
|
||||||
|
|
||||||
|
login_params = {
|
||||||
|
'email' => @membership.account.email,
|
||||||
|
'password' => 'easyone'
|
||||||
|
}
|
||||||
|
|
||||||
|
response = post("http://#{@site.domains.first}/locomotive/api/tokens.json", login_params.to_json, { 'CONTENT_TYPE' => 'application/json' })
|
||||||
|
|
||||||
|
if response.status == 200
|
||||||
|
@auth_token = JSON.parse(response.body)['token']
|
||||||
|
else
|
||||||
|
raise JSON.parse(response.body)['message']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Given /^I do not have an API token$/ do
|
||||||
|
@auth_token = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
When /^I visit "([^"]*)"$/ do |path|
|
||||||
|
@json_response = get("http://#{@site.domains.first}#{path}", { auth_token: @auth_token }, { 'CONTENT_TYPE' => 'application/json' })
|
||||||
|
end
|
||||||
|
|
||||||
|
# http://stackoverflow.com/questions/9009392/racktest-put-method-with-json-fails-to-convert-json-to-params
|
||||||
|
When /^I post to "([^"]*)"$/ do |path|
|
||||||
|
@json_response = post("http://#{@site.domains.first}#{path}", '', { 'CONTENT_TYPE' => 'application/json' })
|
||||||
|
end
|
||||||
|
|
||||||
|
When /^I post to "([^"]*)" with:$/ do |path, json_string|
|
||||||
|
@json_response = post("http://#{@site.domains.first}#{path}", json_string, { 'CONTENT_TYPE' => 'application/json' })
|
||||||
|
end
|
19
features/step_definitions/backoffice/mounting_steps.rb
Normal file
19
features/step_definitions/backoffice/mounting_steps.rb
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Given /^the engine is mounted on a non standard path$/ do
|
||||||
|
Rails.application.routes.draw do
|
||||||
|
mount Locomotive::Engine => '/my-custom-path', :as => 'locomotive'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Then /^I should be able to access the backend$/ do
|
||||||
|
# Ensure we can access the backend
|
||||||
|
visit '/my-custom-path'
|
||||||
|
page.should have_content 'LocomotiveCMS'
|
||||||
|
|
||||||
|
# Ensure we can update the homepage content
|
||||||
|
click_link 'Home page'
|
||||||
|
click_button 'Save'
|
||||||
|
page.should have_content 'Page was successfully updated'
|
||||||
|
|
||||||
|
# Reset the routes back to normal once we are done
|
||||||
|
Rails.application.reload_routes!
|
||||||
|
end
|
@ -39,6 +39,14 @@ Given %r{^I have entries for "([^"]*)" with$} do |name, entries|
|
|||||||
content_type.save.should be_true
|
content_type.save.should be_true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Given %r{^I (enable|disable) the public submission of the "([^"]*)" model$} do |action, name|
|
||||||
|
enabled = action == 'enable'
|
||||||
|
content_type = Locomotive::ContentType.where(:name => name).first
|
||||||
|
content_type.public_submission_enabled = enabled
|
||||||
|
content_type.public_submission_accounts = enabled ? [Locomotive::Account.first._id] : []
|
||||||
|
content_type.save.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
When %r{^I change the presentation of the "([^"]*)" model by grouping items by "([^"]*)"$} do |name, field|
|
When %r{^I change the presentation of the "([^"]*)" model by grouping items by "([^"]*)"$} do |name, field|
|
||||||
content_type = Locomotive::ContentType.where(:name => name).first
|
content_type = Locomotive::ContentType.where(:name => name).first
|
||||||
field = content_type.entries_custom_fields.detect { |f| f.label == field }
|
field = content_type.entries_custom_fields.detect { |f| f.label == field }
|
||||||
|
@ -54,7 +54,8 @@ end
|
|||||||
|
|
||||||
# checks if the rendered body matches a string
|
# checks if the rendered body matches a string
|
||||||
Then /^the rendered output should look like:$/ do |body_contents|
|
Then /^the rendered output should look like:$/ do |body_contents|
|
||||||
page.source.should == body_contents
|
# page.source.should == body_contents
|
||||||
|
page.source.index(body_contents).should_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^I should see delete page buttons$/ do
|
Then /^I should see delete page buttons$/ do
|
||||||
|
@ -19,6 +19,8 @@ require 'capybara/rails'
|
|||||||
require 'capybara/cucumber'
|
require 'capybara/cucumber'
|
||||||
require 'capybara/session'
|
require 'capybara/session'
|
||||||
|
|
||||||
|
require 'json_spec/cucumber'
|
||||||
|
|
||||||
require 'resolv'
|
require 'resolv'
|
||||||
require 'uri'
|
require 'uri'
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ The Locomotive Engine has been correctly installed in your Rails application.
|
|||||||
|
|
||||||
> open localhost:8080
|
> open localhost:8080
|
||||||
|
|
||||||
4. Follow the installation wizzard steps
|
4. Follow the installation wizard steps
|
||||||
|
|
||||||
5. Enjoy !
|
5. Enjoy !
|
||||||
|
|
||||||
|
@ -9,6 +9,18 @@ module Locomotive
|
|||||||
super || has_errors?
|
super || has_errors?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def options
|
||||||
|
current_site = self.controller.send(:current_site)
|
||||||
|
current_account = self.controller.send(:current_locomotive_account)
|
||||||
|
ability = current_account.nil? ? nil : self.controller.send(:current_ability)
|
||||||
|
|
||||||
|
super.merge({
|
||||||
|
:current_site => current_site,
|
||||||
|
:current_account => current_account,
|
||||||
|
:ability => ability
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
def to_json
|
def to_json
|
||||||
if get?
|
if get?
|
||||||
display resource
|
display resource
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
class String #:nodoc
|
class String #:nodoc
|
||||||
|
|
||||||
def permalink
|
def permalink
|
||||||
self.parameterize('-')
|
self.to_ascii.parameterize('-')
|
||||||
end
|
end
|
||||||
|
|
||||||
def permalink!
|
def permalink!
|
||||||
|
@ -19,6 +19,7 @@ require 'cancan'
|
|||||||
require 'RMagick'
|
require 'RMagick'
|
||||||
require 'cells'
|
require 'cells'
|
||||||
require 'sanitize'
|
require 'sanitize'
|
||||||
|
require 'unidecoder'
|
||||||
|
|
||||||
require 'compass'
|
require 'compass'
|
||||||
require 'codemirror/rails'
|
require 'codemirror/rails'
|
||||||
|
@ -7,6 +7,8 @@ module Locomotive
|
|||||||
if source.is_a?(String) || source.is_a?(Hash) # simple string or theme asset
|
if source.is_a?(String) || source.is_a?(Hash) # simple string or theme asset
|
||||||
source = source['url'] if source.is_a?(Hash)
|
source = source['url'] if source.is_a?(Hash)
|
||||||
|
|
||||||
|
source.strip!
|
||||||
|
|
||||||
if source =~ /^http/
|
if source =~ /^http/
|
||||||
file = self.app.fetch_url(source)
|
file = self.app.fetch_url(source)
|
||||||
else
|
else
|
||||||
|
@ -17,13 +17,17 @@ module ActionView
|
|||||||
content_tag_without_haml(name, content_or_options_with_block, *args, &block)
|
content_tag_without_haml(name, content_or_options_with_block, *args, &block)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if preserve && content_or_options_with_block
|
if name == 'textarea'
|
||||||
|
tab_down(haml_buffer.tabulation)
|
||||||
|
elsif preserve && content_or_options_with_block
|
||||||
content_or_options_with_block = Haml::Helpers.preserve(content_or_options_with_block)
|
content_or_options_with_block = Haml::Helpers.preserve(content_or_options_with_block)
|
||||||
end
|
end
|
||||||
content = content_tag_without_haml(name, content_or_options_with_block, *args, &block)
|
content_tag_without_haml(name, content_or_options_with_block, *args, &block)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
alias_method :content_tag_without_haml_and_preserve, :content_tag
|
||||||
|
alias_method :content_tag, :content_tag_with_haml_and_preserve
|
||||||
alias_method :content_tag_with_haml, :content_tag_with_haml_and_preserve
|
alias_method :content_tag_with_haml, :content_tag_with_haml_and_preserve
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -63,12 +63,9 @@ module Locomotive
|
|||||||
conditions = HashWithIndifferentAccess.new(@context['with_scope'])
|
conditions = HashWithIndifferentAccess.new(@context['with_scope'])
|
||||||
order_by = conditions.delete(:order_by).try(:split)
|
order_by = conditions.delete(:order_by).try(:split)
|
||||||
|
|
||||||
if order_by.nil?
|
list.filtered(conditions, order_by)
|
||||||
list.where(conditions).ordered
|
|
||||||
else
|
|
||||||
list.where(conditions).order_by(order_by)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
|
# no filter, default order
|
||||||
list.ordered
|
list.ordered
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
21
lib/locomotive/liquid/drops/current_user.rb
Normal file
21
lib/locomotive/liquid/drops/current_user.rb
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
module Locomotive
|
||||||
|
module Liquid
|
||||||
|
module Drops
|
||||||
|
class CurrentUser < Base
|
||||||
|
|
||||||
|
def logged_in?
|
||||||
|
_source.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
_source.name if logged_in?
|
||||||
|
end
|
||||||
|
|
||||||
|
def email
|
||||||
|
_source.email if logged_in?
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -27,8 +27,10 @@ module Locomotive
|
|||||||
@context[:parent_page] = @context[:page].parent
|
@context[:parent_page] = @context[:page].parent
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
locale = ::Mongoid::Fields::I18n.locale
|
||||||
|
|
||||||
@context[:parent_page] = @context[:cached_pages].try(:[], @template_name) ||
|
@context[:parent_page] = @context[:cached_pages].try(:[], @template_name) ||
|
||||||
@context[:site].pages.where(:fullpath => @template_name).first
|
@context[:site].pages.where("fullpath.#{locale}" => @template_name).first
|
||||||
end
|
end
|
||||||
|
|
||||||
raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if @context[:parent_page].nil?
|
raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if @context[:parent_page].nil?
|
||||||
|
@ -8,7 +8,7 @@ module Locomotive
|
|||||||
|
|
||||||
controller = context.registers[:controller]
|
controller = context.registers[:controller]
|
||||||
|
|
||||||
plugins = 'common/format,common/table,common/list,common/link,common/highlighteditables,common/block,common/undo,common/contenthandler,common/paste,common/commands,common/abbr,common/horizontalruler'
|
plugins = 'common/format,common/table,common/list,common/link,common/highlighteditables,common/block,common/undo,common/contenthandler,common/paste,common/commands,common/abbr,common/align,common/horizontalruler,custom/locomotive_media'
|
||||||
|
|
||||||
%{
|
%{
|
||||||
<meta content="true" name="inline-editor" />
|
<meta content="true" name="inline-editor" />
|
||||||
|
@ -95,7 +95,7 @@ module Locomotive
|
|||||||
|
|
||||||
if render_children_for_page?(page, depth) && bootstrap?
|
if render_children_for_page?(page, depth) && bootstrap?
|
||||||
css += ' dropdown'
|
css += ' dropdown'
|
||||||
link_options = %{ class="dropdown-toggle" data-toogle="dropdown"}
|
link_options = %{ class="dropdown-toggle" data-toggle="dropdown"}
|
||||||
href = '#'
|
href = '#'
|
||||||
caret = %{ <b class="caret"></b>}
|
caret = %{ <b class="caret"></b>}
|
||||||
end
|
end
|
||||||
|
@ -55,7 +55,8 @@ module Locomotive
|
|||||||
'today' => Date.today,
|
'today' => Date.today,
|
||||||
'locale' => I18n.locale,
|
'locale' => I18n.locale,
|
||||||
'default_locale' => current_site.default_locale.to_s,
|
'default_locale' => current_site.default_locale.to_s,
|
||||||
'locales' => current_site.locales
|
'locales' => current_site.locales,
|
||||||
|
'current_user' => Locomotive::Liquid::Drops::CurrentUser.new(current_locomotive_account)
|
||||||
}
|
}
|
||||||
|
|
||||||
assigns.merge!(Locomotive.config.context_assign_extensions)
|
assigns.merge!(Locomotive.config.context_assign_extensions)
|
||||||
@ -85,6 +86,7 @@ module Locomotive
|
|||||||
fresh_when :etag => @page, :last_modified => @page.updated_at.utc, :public => true
|
fresh_when :etag => @page, :last_modified => @page.updated_at.utc, :public => true
|
||||||
|
|
||||||
if @page.cache_strategy != 'simple' # varnish
|
if @page.cache_strategy != 'simple' # varnish
|
||||||
|
response.headers['Editable'] = ''
|
||||||
response.cache_control[:max_age] = @page.cache_strategy
|
response.cache_control[:max_age] = @page.cache_strategy
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
module Locomotive #:nodoc
|
module Locomotive #:nodoc
|
||||||
VERSION = '2.0.0.rc4'
|
VERSION = '2.0.0.rc7'
|
||||||
end
|
end
|
||||||
|
1
lib/locomotive_cms.rb
Normal file
1
lib/locomotive_cms.rb
Normal file
@ -0,0 +1 @@
|
|||||||
|
require 'locomotive/engine'
|
@ -27,10 +27,10 @@ Gem::Specification.new do |s|
|
|||||||
|
|
||||||
s.add_dependency 'mongo', '~> 1.5.2'
|
s.add_dependency 'mongo', '~> 1.5.2'
|
||||||
s.add_dependency 'bson_ext', '~> 1.5.2'
|
s.add_dependency 'bson_ext', '~> 1.5.2'
|
||||||
s.add_dependency 'mongoid', '~> 2.4.6'
|
s.add_dependency 'mongoid', '~> 2.4.9'
|
||||||
s.add_dependency 'locomotive-mongoid-tree', '~> 0.6.2'
|
s.add_dependency 'locomotive-mongoid-tree', '~> 0.6.2'
|
||||||
|
|
||||||
s.add_dependency 'custom_fields', '~> 2.0.0.rc9'
|
s.add_dependency 'custom_fields', '~> 2.0.0.rc10'
|
||||||
|
|
||||||
s.add_dependency 'kaminari', '~> 0.13.0'
|
s.add_dependency 'kaminari', '~> 0.13.0'
|
||||||
|
|
||||||
@ -38,8 +38,8 @@ Gem::Specification.new do |s|
|
|||||||
s.add_dependency 'jquery-rails', '~> 1.0.16'
|
s.add_dependency 'jquery-rails', '~> 1.0.16'
|
||||||
s.add_dependency 'rails-backbone', '~> 0.6.1'
|
s.add_dependency 'rails-backbone', '~> 0.6.1'
|
||||||
s.add_dependency 'codemirror-rails', '~> 2.21'
|
s.add_dependency 'codemirror-rails', '~> 2.21'
|
||||||
s.add_dependency 'locomotive-tinymce-rails', '~> 3.4.7.1'
|
s.add_dependency 'locomotive-tinymce-rails', '~> 3.4.7.2'
|
||||||
s.add_dependency 'locomotive-aloha-rails', '~> 0.20.1.1'
|
s.add_dependency 'locomotive-aloha-rails', '~> 0.20.1.4'
|
||||||
s.add_dependency 'flash_cookie_session', '~> 1.1.1'
|
s.add_dependency 'flash_cookie_session', '~> 1.1.1'
|
||||||
|
|
||||||
s.add_dependency 'locomotive_liquid', '2.2.2'
|
s.add_dependency 'locomotive_liquid', '2.2.2'
|
||||||
@ -49,6 +49,7 @@ Gem::Specification.new do |s|
|
|||||||
s.add_dependency 'RedCloth', '~> 4.2.8'
|
s.add_dependency 'RedCloth', '~> 4.2.8'
|
||||||
s.add_dependency 'sanitize', '~> 2.0.3'
|
s.add_dependency 'sanitize', '~> 2.0.3'
|
||||||
s.add_dependency 'highline', '~> 1.6.2'
|
s.add_dependency 'highline', '~> 1.6.2'
|
||||||
|
s.add_dependency 'unidecoder', '~> 1.1.1'
|
||||||
|
|
||||||
s.add_dependency 'rmagick', '~> 2.12.2'
|
s.add_dependency 'rmagick', '~> 2.12.2'
|
||||||
s.add_dependency 'carrierwave-mongoid', '~> 0.1.3'
|
s.add_dependency 'carrierwave-mongoid', '~> 0.1.3'
|
||||||
@ -58,6 +59,7 @@ Gem::Specification.new do |s|
|
|||||||
s.add_dependency 'rack-cache', '~> 1.1'
|
s.add_dependency 'rack-cache', '~> 1.1'
|
||||||
s.add_dependency 'mimetype-fu', '~> 0.1.2'
|
s.add_dependency 'mimetype-fu', '~> 0.1.2'
|
||||||
|
|
||||||
|
s.add_dependency 'multi_json', '~> 1.3.4'
|
||||||
s.add_dependency 'httparty', '~> 0.8.1'
|
s.add_dependency 'httparty', '~> 0.8.1'
|
||||||
s.add_dependency 'actionmailer-with-request', '~> 0.3.0'
|
s.add_dependency 'actionmailer-with-request', '~> 0.3.0'
|
||||||
|
|
||||||
|
@ -18,36 +18,51 @@ end
|
|||||||
|
|
||||||
# ================ GLOBAL VARIABLES ==============
|
# ================ GLOBAL VARIABLES ==============
|
||||||
|
|
||||||
$database = 'locomotive_hosting_production'
|
$database_name = 'locomotive_engine_dev'
|
||||||
|
$database_host = 'localhost'
|
||||||
|
$database_port = '27017'
|
||||||
|
# $database_username = '<your username>'
|
||||||
|
# $database_password = '<your password>'
|
||||||
|
|
||||||
$default_locale = 'en'
|
$default_locale = 'en'
|
||||||
# $locale_exceptions = {}
|
$locale_exceptions = {}
|
||||||
|
|
||||||
# Example:
|
# Example:
|
||||||
$locale_exceptions = {
|
# $locale_exceptions = {
|
||||||
'4c082a9393d4330812000002' => 'fr',
|
# '4c082a9393d4330812000002' => 'fr',
|
||||||
'4c2330706f40d50ae2000005' => 'fr',
|
# '4c2330706f40d50ae2000005' => 'fr',
|
||||||
'4dc07643d800a53aea00035a' => 'fr',
|
# '4dc07643d800a53aea00035a' => 'fr',
|
||||||
'4eb6aca89a976a0001000ebb' => 'fr'
|
# '4eb6aca89a976a0001000ebb' => 'fr'
|
||||||
}
|
# }
|
||||||
|
|
||||||
def get_locale(site_id)
|
# no amazon S3
|
||||||
$locale_exceptions[site_id.to_s] || $default_locale
|
$s3 = false
|
||||||
end
|
|
||||||
|
# amazon S3 settings
|
||||||
|
# $s3 = true
|
||||||
|
# $s3_bucket = '<BUCKET_NAME>'
|
||||||
|
# $fog_storage_settings = {
|
||||||
|
# :provider => 'AWS',
|
||||||
|
# :aws_secret_access_key => '<AWS_SECRET_KEY>',
|
||||||
|
# :aws_access_key_id => '<AWS_ACCESS_KEY>'
|
||||||
|
# }
|
||||||
|
|
||||||
# ================ MONGODB ==============
|
# ================ MONGODB ==============
|
||||||
|
|
||||||
require 'mongoid'
|
require 'mongoid'
|
||||||
|
|
||||||
Mongoid.configure do |config|
|
Mongoid.configure do |config|
|
||||||
name = $database
|
db = config.master = Mongo::Connection.new($database_host, $database_port).db($database_name)
|
||||||
host = 'localhost'
|
if $database_username && $database_password
|
||||||
config.master = Mongo::Connection.new.db(name)
|
db.authenticate($database_username, $database_password)
|
||||||
# config.master = Mongo::Connection.new('localhost', '27017', :logger => Logger.new($stdout)).db(name)
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
db = Mongoid.config.master
|
db = Mongoid.config.master
|
||||||
|
|
||||||
|
def get_locale(site_id)
|
||||||
|
$locale_exceptions[site_id.to_s] || $default_locale
|
||||||
|
end
|
||||||
|
|
||||||
puts "***************************************"
|
puts "***************************************"
|
||||||
puts "[LocomotiveCMS] Upgrade from 1.0 to 2.0"
|
puts "[LocomotiveCMS] Upgrade from 1.0 to 2.0"
|
||||||
@ -85,7 +100,6 @@ if collection = db.collections.detect { |c| c.name == 'content_types' }
|
|||||||
locale = get_locale(content_type['site_id'])
|
locale = get_locale(content_type['site_id'])
|
||||||
label_field_name = ''
|
label_field_name = ''
|
||||||
recipe = { 'name' => "Entry#{content_type['_id']}", 'version' => content_type['content_custom_fields_version'], 'rules' => [] }
|
recipe = { 'name' => "Entry#{content_type['_id']}", 'version' => content_type['content_custom_fields_version'], 'rules' => [] }
|
||||||
rule_options = {}
|
|
||||||
operations = { '$set' => {}, '$unset' => {} }
|
operations = { '$set' => {}, '$unset' => {} }
|
||||||
contents = content_type['contents']
|
contents = content_type['contents']
|
||||||
custom_fields = content_type['entries_custom_fields']
|
custom_fields = content_type['entries_custom_fields']
|
||||||
@ -93,6 +107,7 @@ if collection = db.collections.detect { |c| c.name == 'content_types' }
|
|||||||
# fields
|
# fields
|
||||||
custom_fields.each_with_index do |field, index|
|
custom_fields.each_with_index do |field, index|
|
||||||
name, type = field['_alias'], field['kind'].downcase
|
name, type = field['_alias'], field['kind'].downcase
|
||||||
|
rule_options = {}
|
||||||
class_name = "Locomotive::Entry#{field['target'][-24,24]}" if field['target']
|
class_name = "Locomotive::Entry#{field['target'][-24,24]}" if field['target']
|
||||||
|
|
||||||
case field['kind']
|
case field['kind']
|
||||||
@ -103,14 +118,15 @@ if collection = db.collections.detect { |c| c.name == 'content_types' }
|
|||||||
type = 'belongs_to'
|
type = 'belongs_to'
|
||||||
operations['$set'].merge!("entries_custom_fields.#{index}.type" => 'belongs_to')
|
operations['$set'].merge!("entries_custom_fields.#{index}.type" => 'belongs_to')
|
||||||
when 'has_many'
|
when 'has_many'
|
||||||
if field['reverse_lookup']
|
if !field['reverse_lookup'].blank?
|
||||||
type = 'has_many'
|
type = 'has_many'
|
||||||
operations['$set'].merge!("entries_custom_fields.#{index}.type" => 'has_many')
|
operations['$set'].merge!("entries_custom_fields.#{index}.type" => 'has_many')
|
||||||
|
|
||||||
# reverse_lookup -> inverse_of => hmmmmmmm
|
# reverse_lookup -> inverse_of => hmmmmmmm
|
||||||
if _content_type = collection.find('_id' => BSON::ObjectId(field['target'][-24,24]).first)
|
if _content_type = collection.find('_id' => BSON::ObjectId(field['target'][-24,24])).first
|
||||||
if _field = _content_type['entries_custom_fields'].detect { |f| f['_name'] == field['reverse_lookup'] }
|
if _field = _content_type['entries_custom_fields'].detect { |f| f['_name'] == field['reverse_lookup'] }
|
||||||
operations['$set'].merge!("entries_custom_fields.#{index}.inverse_of" => _field['_alias'])
|
operations['$set'].merge!("entries_custom_fields.#{index}.inverse_of" => _field['_alias'])
|
||||||
|
rule_options['inverse_of'] = _field['_alias']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -125,6 +141,7 @@ if collection = db.collections.detect { |c| c.name == 'content_types' }
|
|||||||
"entries_custom_fields.#{index}.target" => '1',
|
"entries_custom_fields.#{index}.target" => '1',
|
||||||
"entries_custom_fields.#{index}.reverse_lookup" => '1'
|
"entries_custom_fields.#{index}.reverse_lookup" => '1'
|
||||||
})
|
})
|
||||||
|
rule_options['class_name'] = class_name
|
||||||
end
|
end
|
||||||
|
|
||||||
if content_type['highlighted_field_name'] == field['_name']
|
if content_type['highlighted_field_name'] == field['_name']
|
||||||
@ -185,7 +202,7 @@ if collection = db.collections.detect { |c| c.name == 'content_types' }
|
|||||||
|
|
||||||
# contents
|
# contents
|
||||||
(contents || []).each_with_index do |content|
|
(contents || []).each_with_index do |content|
|
||||||
attributes = content.clone.keep_if { |k, v| %w(_id _slug seo_title meta_description meta_keywords _visible created_at updated_at).include?(k) }
|
attributes = content.clone.keep_if { |k, v| %w(_id _slug _visible created_at updated_at).include?(k) }
|
||||||
attributes.merge!({
|
attributes.merge!({
|
||||||
'content_type_id' => content_type['_id'],
|
'content_type_id' => content_type['_id'],
|
||||||
'site_id' => content_type['site_id'],
|
'site_id' => content_type['site_id'],
|
||||||
@ -195,21 +212,28 @@ if collection = db.collections.detect { |c| c.name == 'content_types' }
|
|||||||
'custom_fields_recipe' => recipe
|
'custom_fields_recipe' => recipe
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# localized attributes
|
||||||
|
%w(seo_title meta_description meta_keywords).each do |name|
|
||||||
|
attributes[name] = { locale => content[name] }
|
||||||
|
end
|
||||||
|
|
||||||
custom_fields.each do |field|
|
custom_fields.each do |field|
|
||||||
name, _name = field['_alias'], field['_name']
|
name, _name = field['_alias'], field['_name']
|
||||||
|
|
||||||
case field['kind'] # string, text, boolean, date, file, category, has_many, has_one
|
case field['kind'] # string, text, boolean, date, file, category, has_many, has_one
|
||||||
when 'string', 'text', 'boolean', 'date'
|
when 'string', 'text', 'date'
|
||||||
attributes[name] = content[_name]
|
attributes[name] = content[_name]
|
||||||
|
when 'boolean'
|
||||||
|
attributes[name] = content[_name] == '1'
|
||||||
when 'file'
|
when 'file'
|
||||||
attributes[name] = content["#{_name}_filename"]
|
attributes[name] = content["#{_name}_filename"]
|
||||||
when 'category', 'has_one'
|
when 'category', 'has_one'
|
||||||
attributes["#{name}_id"] = content[_name]
|
attributes["#{name}_id"] = content[_name]
|
||||||
when 'has_many'
|
when 'has_many'
|
||||||
if field['reverse_lookup']
|
if !field['reverse_lookup'].blank?
|
||||||
# nothing to do
|
# nothing to do
|
||||||
else
|
else
|
||||||
attributes["#{name}_ids"] = content[_name]
|
attributes["#{name.singularize}_ids"] = (content[_name] || []).map { |_id| BSON::ObjectId(_id) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -287,6 +311,9 @@ if collection = db.collections.detect { |c| c.name == 'pages' }
|
|||||||
|
|
||||||
modifications, removals = {}, {}
|
modifications, removals = {}, {}
|
||||||
|
|
||||||
|
modifications['locales'] = [locale]
|
||||||
|
modifications['response_type'] = 'text/html'
|
||||||
|
|
||||||
%w(title slug fullpath raw_template serialized_template template_dependencies snippet_dependencies seo_title meta_keywords meta_description).each do |attr|
|
%w(title slug fullpath raw_template serialized_template template_dependencies snippet_dependencies seo_title meta_keywords meta_description).each do |attr|
|
||||||
modifications[attr] = { locale => page[attr] }
|
modifications[attr] = { locale => page[attr] }
|
||||||
end
|
end
|
||||||
@ -300,11 +327,23 @@ if collection = db.collections.detect { |c| c.name == 'pages' }
|
|||||||
(page['editable_elements'] || []).each_with_index do |editable_element, index|
|
(page['editable_elements'] || []).each_with_index do |editable_element, index|
|
||||||
modifications["editable_elements.#{index}._type"] = "Locomotive::#{editable_element['_type']}"
|
modifications["editable_elements.#{index}._type"] = "Locomotive::#{editable_element['_type']}"
|
||||||
modifications["editable_elements.#{index}.content"] = { locale => editable_element['content'] }
|
modifications["editable_elements.#{index}.content"] = { locale => editable_element['content'] }
|
||||||
|
modifications["editable_elements.#{index}.locales"] = [locale]
|
||||||
|
|
||||||
if editable_element['_type'] == 'EditableFile'
|
if editable_element['_type'] == 'EditableFile'
|
||||||
modifications["editable_elements.#{index}.source"] = { locale => editable_element['source_filename'] }
|
modifications["editable_elements.#{index}.source"] = { locale => editable_element['source_filename'] }
|
||||||
removals["editable_elements.#{index}.source_filename"] = '1'
|
removals["editable_elements.#{index}.source_filename"] = '1'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# FIXME: do not remember why I needed to run this code.
|
||||||
|
# Locomotive::Page.each do |page|
|
||||||
|
# page.editable_elements.each_with_index do |el, index|
|
||||||
|
# next if el._type != 'Locomotive::EditableFile' || el.attributes['source'].is_a?(Hash)
|
||||||
|
#
|
||||||
|
# value = el.attributes['source']
|
||||||
|
#
|
||||||
|
# page.collection.update({ '_id' => page._id }, { '$set' => { "editable_elements.#{index}.source" => { 'en' => value } } })
|
||||||
|
# end
|
||||||
|
# end
|
||||||
end
|
end
|
||||||
|
|
||||||
if page['depth'] == 0 && page['fullpath'] == '404'
|
if page['depth'] == 0 && page['fullpath'] == '404'
|
||||||
@ -333,3 +372,60 @@ end
|
|||||||
%w(asset_collections liquid_templates delayed_backend_mongoid_jobs).each do |name|
|
%w(asset_collections liquid_templates delayed_backend_mongoid_jobs).each do |name|
|
||||||
db.drop_collection name
|
db.drop_collection name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# content entry assets
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# old sites/4c34fc86cc85f01e47000005/contents/content_instance/4dc15162ceedba763500011a/files/didier_plate.png
|
||||||
|
# new sites/4c34fc86cc85f01e47000005/content_entry{content_type_id}/4dc15162ceedba763500011a/files/didier_plate.png
|
||||||
|
|
||||||
|
collection = db.collections.detect { |c| c.name == 'locomotive_content_entries' }
|
||||||
|
|
||||||
|
if $s3
|
||||||
|
# Amazon S3 (AWS)
|
||||||
|
require 'fog'
|
||||||
|
|
||||||
|
connection = Fog::Storage.new($fog_storage_settings)
|
||||||
|
|
||||||
|
bucket = connection.directories.detect { |d| d.key == $s3_bucket }
|
||||||
|
|
||||||
|
bucket.files.each do |file|
|
||||||
|
if file.key =~ /^sites\/([a-f0-9]+)\/contents\/content_instance\/([a-f0-9]+)\/files/
|
||||||
|
content_type_id = collection.find('_id' => BSON::ObjectId($2)).first['content_type_id'].to_s
|
||||||
|
new_key = file.key.gsub('contents/content_instance', "content_entry#{content_type_id}")
|
||||||
|
|
||||||
|
puts "new file #{new_key}"
|
||||||
|
|
||||||
|
# rename file by copying the original file to its new folder
|
||||||
|
bucket.files.create(
|
||||||
|
:key => new_key,
|
||||||
|
:body => file.body,
|
||||||
|
:public => true
|
||||||
|
)
|
||||||
|
|
||||||
|
file.destroy # delete the file forever
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Dir[File.join(File.dirname(__FILE__), '..', 'public', 'sites', '**/*')].each do |path|
|
||||||
|
next if File.directory?(path)
|
||||||
|
|
||||||
|
if path =~ /public\/sites\/([a-f0-9]+)\/contents\/content_instance\/([a-f0-9]+)\/files/
|
||||||
|
content_type_id = collection.find('_id' => BSON::ObjectId($2)).first['content_type_id'].to_s
|
||||||
|
new_path = path.gsub('contents/content_instance', "content_entry#{content_type_id}")
|
||||||
|
|
||||||
|
puts "new file #{new_path}"
|
||||||
|
|
||||||
|
# create the target folder
|
||||||
|
FileUtils.mkdir_p(File.dirname(new_path))
|
||||||
|
|
||||||
|
FileUtils.mv(path, new_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# do some cleaning
|
||||||
|
Dir[File.join(File.dirname(__FILE__), '..', 'public', 'sites', '*', 'contents')].each do |folder|
|
||||||
|
puts "remove folder #{folder}"
|
||||||
|
FileUtils.rm_rf folder
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,2 @@
|
|||||||
|
# FIXME: just to demonstrate how easy it is to change the tinymce settings for the LocomotiveCMS back-office
|
||||||
|
# window.Locomotive.tinyMCE.defaultSettings.theme_advanced_buttons2 = 'formatselect,fontselect,fontsizeselect'
|
@ -0,0 +1 @@
|
|||||||
|
= javascript_include_tag 'locomotive_misc'
|
@ -1,2 +1,2 @@
|
|||||||
Haml::Template.options[:ugly] = true
|
|
||||||
Haml::Template.options[:format] = :html5
|
Haml::Template.options[:format] = :html5
|
||||||
|
Haml::Template.options[:ugly] = true # improve performance in dev
|
||||||
|
@ -10,11 +10,14 @@ defaults: &defaults
|
|||||||
development:
|
development:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
database: locomotive_engine_dev
|
database: locomotive_engine_dev
|
||||||
|
identity_map_enabled: true
|
||||||
|
|
||||||
test:
|
test:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
database: locomotive_engine_test
|
database: locomotive_engine_test
|
||||||
|
identity_map_enabled: true
|
||||||
|
|
||||||
production:
|
production:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
|
identity_map_enabled: true
|
||||||
database: locomotive_engine_production
|
database: locomotive_engine_production
|
||||||
|
@ -21,8 +21,7 @@ describe Locomotive::Liquid::Drops::ContentEntry do
|
|||||||
it 'filters the list' do
|
it 'filters the list' do
|
||||||
template = %({% with_scope order_by: 'name ASC', active: true %}{% for project in category.projects %}{{ project }},{% endfor %}{% endwith_scope %})
|
template = %({% with_scope order_by: 'name ASC', active: true %}{% for project in category.projects %}{{ project }},{% endfor %}{% endwith_scope %})
|
||||||
|
|
||||||
@list.expects(:order_by).with(['name', 'ASC']).returns(%w(a b))
|
@list.expects(:filtered).with({ 'active' => true }, ['name', 'ASC']).returns(%w(a b))
|
||||||
@list.expects(:where).with({ 'active' => true }).returns(@list)
|
|
||||||
|
|
||||||
render(template, { 'category' => @category }).should == 'a,b,'
|
render(template, { 'category' => @category }).should == 'a,b,'
|
||||||
end
|
end
|
||||||
@ -30,8 +29,7 @@ describe Locomotive::Liquid::Drops::ContentEntry do
|
|||||||
it 'filters the list and uses the default order' do
|
it 'filters the list and uses the default order' do
|
||||||
template = %({% with_scope active: true %}{% for project in category.projects %}{{ project }},{% endfor %}{% endwith_scope %})
|
template = %({% with_scope active: true %}{% for project in category.projects %}{{ project }},{% endfor %}{% endwith_scope %})
|
||||||
|
|
||||||
@list.expects(:ordered).returns(%w(a b))
|
@list.expects(:filtered).with({ 'active' => true }, nil).returns(%w(a b))
|
||||||
@list.expects(:where).with({ 'active' => true }).returns(@list)
|
|
||||||
|
|
||||||
render(template, { 'category' => @category }).should == 'a,b,'
|
render(template, { 'category' => @category }).should == 'a,b,'
|
||||||
end
|
end
|
||||||
|
63
spec/lib/locomotive/liquid/drops/current_user.rb
Normal file
63
spec/lib/locomotive/liquid/drops/current_user.rb
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Locomotive::Liquid::Drops::CurrentUser do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@page = FactoryGirl.build(:sub_page)
|
||||||
|
|
||||||
|
@site = @page.site
|
||||||
|
@site.pages.expects(:any_in).returns([@page])
|
||||||
|
|
||||||
|
@controller = Locomotive::TestController.new
|
||||||
|
@controller.stubs(:flash).returns(ActionDispatch::Flash::FlashHash.new())
|
||||||
|
@controller.stubs(:params).returns(:url => '/subpage')
|
||||||
|
@controller.stubs(:request).returns(OpenStruct.new(:url => '/subpage', :fullpath => '/subpage'))
|
||||||
|
@controller.current_site = @site
|
||||||
|
|
||||||
|
@admin = FactoryGirl.build(:admin).account
|
||||||
|
end
|
||||||
|
|
||||||
|
def expect_render(template, text)
|
||||||
|
@page.raw_template = template
|
||||||
|
@page.send(:serialize_template)
|
||||||
|
@controller.expects(:render).with(:text => text, :layout => false, :status => :ok).returns(true)
|
||||||
|
@controller.send(:render_locomotive_page)
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#logged_in?' do
|
||||||
|
it 'returns false when no user is logged in' do
|
||||||
|
expect_render('{{ current_user.logged_in? }}', 'false')
|
||||||
|
end
|
||||||
|
it 'returns true when there is a user logged in' do
|
||||||
|
@controller.expects(:current_admin).twice.returns(true)
|
||||||
|
expect_render('{{ current_user.logged_in? }}', 'true')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#name' do
|
||||||
|
it 'returns nothing when no user is logged in' do
|
||||||
|
expect_render('{{ current_user.name }}', '')
|
||||||
|
end
|
||||||
|
it 'returns the username when the user is logged in' do
|
||||||
|
@controller.expects(:current_admin).twice.returns(@admin)
|
||||||
|
expect_render('{{ current_user.name }}', 'Admin')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#email' do
|
||||||
|
it 'returns nothing when no user is logged in' do
|
||||||
|
expect_render('{{ current_user.email }}', '')
|
||||||
|
end
|
||||||
|
it 'returns the username when the user is logged in' do
|
||||||
|
@controller.expects(:current_admin).twice.returns(@admin)
|
||||||
|
expect_render('{{ current_user.email }}', 'admin@locomotiveapp.org')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#logout_path' do
|
||||||
|
it 'returns the logout url' do
|
||||||
|
expect_render('{{ current_user.logout_path }}', '/admin/sign_out')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user