listing all entries (done) + fix bugs + tweak ui
This commit is contained in:
parent
81fc524fdc
commit
0f1b4f59d3
2
Gemfile
2
Gemfile
@ -31,7 +31,7 @@ gem 'flash_cookie_session', '~> 1.1.1'
|
|||||||
|
|
||||||
gem 'locomotive_liquid', '2.2.2', :require => 'liquid'
|
gem 'locomotive_liquid', '2.2.2', :require => 'liquid'
|
||||||
gem 'formtastic', '~> 2.0.2'
|
gem 'formtastic', '~> 2.0.2'
|
||||||
gem 'responders', '~> 0.6.0'
|
gem 'responders', '~> 0.6.4'
|
||||||
gem 'cells', '~> 3.7.0'
|
gem 'cells', '~> 3.7.0'
|
||||||
gem 'RedCloth', '~> 4.2.8'
|
gem 'RedCloth', '~> 4.2.8'
|
||||||
gem 'sanitize', '~> 2.0.3'
|
gem 'sanitize', '~> 2.0.3'
|
||||||
|
@ -341,7 +341,7 @@ DEPENDENCIES
|
|||||||
rails (~> 3.1.3)
|
rails (~> 3.1.3)
|
||||||
rails-backbone (= 0.5.4)
|
rails-backbone (= 0.5.4)
|
||||||
rake (= 0.9.2)
|
rake (= 0.9.2)
|
||||||
responders (~> 0.6.0)
|
responders (~> 0.6.4)
|
||||||
rmagick (= 2.12.2)
|
rmagick (= 2.12.2)
|
||||||
rspec-cells
|
rspec-cells
|
||||||
rspec-rails (= 2.6.1)
|
rspec-rails (= 2.6.1)
|
||||||
|
@ -20,6 +20,7 @@ class Locomotive.Models.ContentEntry extends Backbone.Model
|
|||||||
|
|
||||||
toJSON: ->
|
toJSON: ->
|
||||||
_.tap super, (hash) =>
|
_.tap super, (hash) =>
|
||||||
|
hash['_slug'] = '' if hash['_slug'] == null # avoid empty hash
|
||||||
_.each _.keys(hash), (key) =>
|
_.each _.keys(hash), (key) =>
|
||||||
unless _.include(@get('safe_attributes'), key)
|
unless _.include(@get('safe_attributes'), key)
|
||||||
delete hash[key]
|
delete hash[key]
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
Locomotive.Views.ContentEntries ||= {}
|
||||||
|
|
||||||
|
class Locomotive.Views.ContentEntries.IndexView extends Backbone.View
|
||||||
|
|
||||||
|
el: '#content'
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
@make_sortable()
|
||||||
|
|
||||||
|
return @
|
||||||
|
|
||||||
|
make_sortable: ->
|
||||||
|
self = @
|
||||||
|
|
||||||
|
@$('ul#entries-list.sortable').sortable
|
||||||
|
handle: 'span.handle'
|
||||||
|
items: 'li.item'
|
||||||
|
axis: 'y'
|
||||||
|
update: (event, ui) -> self.call_sort $(@)
|
||||||
|
|
||||||
|
call_sort: (folder) ->
|
||||||
|
$.rails.ajax
|
||||||
|
url: folder.attr('data-url')
|
||||||
|
type: 'post'
|
||||||
|
dataType: 'json'
|
||||||
|
data:
|
||||||
|
entries: (_.map folder.sortable('toArray'), (el) -> el.replace('entry-', ''))
|
||||||
|
_method: 'put'
|
||||||
|
success: @.on_successful_sort
|
||||||
|
error: @.on_failed_sort
|
||||||
|
|
||||||
|
on_successful_sort: (data, status, xhr) ->
|
||||||
|
$.growl('success', xhr.getResponseHeader('X-Message'))
|
||||||
|
|
||||||
|
on_failed_sort: (data, status, xhr) ->
|
||||||
|
$.growl('error', xhr.getResponseHeader('X-Message'))
|
@ -1,4 +1,4 @@
|
|||||||
Locomotive.Views.Contents ||= {}
|
Locomotive.Views.ContentEntries ||= {}
|
||||||
|
|
||||||
class Locomotive.Views.ContentEntries.NewView extends Locomotive.Views.ContentEntries.FormView
|
class Locomotive.Views.ContentEntries.NewView extends Locomotive.Views.ContentEntries.FormView
|
||||||
|
|
||||||
|
@ -33,7 +33,6 @@ class Locomotive.Views.Pages.ListView extends Backbone.View
|
|||||||
success: @.on_successful_sort
|
success: @.on_successful_sort
|
||||||
error: @.on_failed_sort
|
error: @.on_failed_sort
|
||||||
|
|
||||||
# on_sort: (data) ->
|
|
||||||
on_successful_sort: (data, status, xhr) ->
|
on_successful_sort: (data, status, xhr) ->
|
||||||
$.growl('success', xhr.getResponseHeader('X-Message'))
|
$.growl('success', xhr.getResponseHeader('X-Message'))
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ class Locomotive.Views.Shared.ListItemView extends Backbone.View
|
|||||||
tagName: 'li'
|
tagName: 'li'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click a.remove': 'remove_snippet'
|
'click a.remove': 'remove_item'
|
||||||
|
|
||||||
template: ->
|
template: ->
|
||||||
# please overide template
|
# please overide template
|
||||||
@ -15,7 +15,7 @@ class Locomotive.Views.Shared.ListItemView extends Backbone.View
|
|||||||
|
|
||||||
return @
|
return @
|
||||||
|
|
||||||
remove_snippet: (event) ->
|
remove_item: (event) ->
|
||||||
event.stopPropagation() & event.preventDefault()
|
event.stopPropagation() & event.preventDefault()
|
||||||
|
|
||||||
if confirm $(event.target).attr('data-confirm')
|
if confirm $(event.target).attr('data-confirm')
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
height: 30px;
|
height: 30px;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
|
|
||||||
padding: 0 10px;
|
padding: 0 13px;
|
||||||
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@include border-radius(16px);
|
@include border-radius(16px);
|
||||||
@ -70,6 +70,14 @@
|
|||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.handle {
|
||||||
|
display: none;
|
||||||
|
position: relative;
|
||||||
|
top: 3px;
|
||||||
|
margin-right: 5px;
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
color: #17171D;
|
color: #17171D;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@ -100,7 +108,7 @@
|
|||||||
div.more, span.actions {
|
div.more, span.actions {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
right: 10px;
|
right: 13px;
|
||||||
|
|
||||||
color: #8B8D9A;
|
color: #8B8D9A;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
@ -137,6 +145,14 @@
|
|||||||
}
|
}
|
||||||
} // li
|
} // li
|
||||||
|
|
||||||
|
&.sortable {
|
||||||
|
li {
|
||||||
|
span.handle {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> hr {
|
> hr {
|
||||||
margin: 10px 0px;
|
margin: 10px 0px;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
@mixin light-button {
|
@mixin light-button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
|
||||||
font-family: "Lucida Grande";
|
// font-family: "Lucida Grande";
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -65,6 +65,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin red-button {
|
||||||
|
@include light-button;
|
||||||
|
|
||||||
|
@include background-image(linear-gradient(top, #EE5F5B, #C43C35));
|
||||||
|
@include box-shadow(rgba(0, 0, 0, 0.4) 1px 1px 0px 0px);
|
||||||
|
|
||||||
|
@include text-shadow(rgba(0, 0, 0, 0.7) 0px -1px 0px);
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
&:hover, &.hover {
|
||||||
|
background: #C43C35;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@mixin gray-button {
|
@mixin gray-button {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 2px 10px 3px 31px;
|
padding: 2px 10px 3px 31px;
|
||||||
|
@ -102,36 +102,6 @@ ul.list {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// em {
|
|
||||||
// display: block;
|
|
||||||
// float: left;
|
|
||||||
// height: 31px;
|
|
||||||
// width: 18px;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// strong {
|
|
||||||
// display: block;
|
|
||||||
// height: 31px;
|
|
||||||
// margin-left: 18px;
|
|
||||||
//
|
|
||||||
// a {
|
|
||||||
// position: relative;
|
|
||||||
// top: 2px;
|
|
||||||
// left: 15px;
|
|
||||||
//
|
|
||||||
// text-decoration: none;
|
|
||||||
// color: #1f82bc;
|
|
||||||
// font-size: 13px;
|
|
||||||
// @include single-text-shadow(#fff, 1px, 1px, 1px);
|
|
||||||
//
|
|
||||||
// &:hover {
|
|
||||||
// text-decoration: underline;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// &.sortable li strong a { left: 10px; }
|
|
||||||
|
|
||||||
div.more {
|
div.more {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
@ -146,41 +116,68 @@ ul.list {
|
|||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// span.handle {
|
|
||||||
// position: relative;
|
|
||||||
// top: 5px;
|
|
||||||
// margin: 0 0 0 15px;
|
|
||||||
// cursor: move;
|
|
||||||
// }
|
|
||||||
} // li div.more
|
} // li div.more
|
||||||
} // ul.list li
|
} // ul.list li
|
||||||
}
|
}
|
||||||
|
|
||||||
// ul.theme-assets {
|
#entries-list.list {
|
||||||
// margin-left: 40px;
|
|
||||||
//
|
|
||||||
// li.hidden strong a { font-style: italic; color: #8B8D9A; font-weight: normal; }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #contents-list li {
|
li.item {
|
||||||
// background: none;
|
a {
|
||||||
//
|
@include single-text-shadow(#fff, 1px, 1px, 1px);
|
||||||
// li {
|
}
|
||||||
// em {
|
|
||||||
// background-position: left -31px;
|
span.handle {
|
||||||
// cursor: move;
|
display: none;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// strong {
|
.more {
|
||||||
// display: block;
|
|
||||||
// height: 31px;
|
a.remove {
|
||||||
//
|
display: inline-block;
|
||||||
// margin-left: 18px;
|
width: 16px;
|
||||||
//
|
height: 16px;
|
||||||
// background: transparent image-url("locomotive/list/item-right.png") no-repeat right 0;
|
|
||||||
// }
|
margin-left: 7px;
|
||||||
// }
|
outline: none;
|
||||||
// }
|
|
||||||
|
background: transparent image-url("locomotive/list/icons/trash_off.png") repeat 0 0;
|
||||||
|
|
||||||
|
text-indent: -9999px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-image: image-url("locomotive/list/icons/trash.png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // li div.more
|
||||||
|
} // li.item
|
||||||
|
|
||||||
|
&.sortable {
|
||||||
|
|
||||||
|
li.item {
|
||||||
|
span.handle {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 0px;
|
||||||
|
|
||||||
|
height: 22px;
|
||||||
|
width: 18px;
|
||||||
|
text-indent: -9999px;
|
||||||
|
|
||||||
|
background: transparent image-url("locomotive/list/item-left.png") no-repeat 0 0;
|
||||||
|
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
margin-left: 26px;
|
||||||
|
}
|
||||||
|
} // .sortable li.item
|
||||||
|
|
||||||
|
} // .list.sortable
|
||||||
|
|
||||||
|
} // #entries-list.list
|
||||||
|
|
||||||
#pages-list {
|
#pages-list {
|
||||||
margin: 0px 0 20px 0;
|
margin: 0px 0 20px 0;
|
||||||
|
@ -336,6 +336,13 @@ form.formtastic {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.no-label {
|
||||||
|
> textarea, .CodeMirror, .CodeMirror-scroll {
|
||||||
|
margin-top: 12px;
|
||||||
|
width: 868px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // li.code
|
} // li.code
|
||||||
|
|
||||||
&.toggle {
|
&.toggle {
|
||||||
@ -423,10 +430,14 @@ form.formtastic {
|
|||||||
input[type=text] {
|
input[type=text] {
|
||||||
width: 868px;
|
width: 868px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
div.inline-errors {
|
> .inline-hints {
|
||||||
margin-left: 0px;
|
margin-left: 0px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .inline-errors {
|
||||||
|
margin-left: 0px !important;
|
||||||
}
|
}
|
||||||
} // li.no-label
|
} // li.no-label
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ body {
|
|||||||
> div.inner {
|
> div.inner {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0px 8px;
|
margin: 0px 8px;
|
||||||
padding: 10px 15px 20px 15px;
|
padding: 10px 15px 66px 15px;
|
||||||
|
|
||||||
// z-index: 100;
|
// z-index: 100;
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ body {
|
|||||||
@include box-shadow(rgba(0, 0, 0, 0.3) 0px 0px 6px 4px);
|
@include box-shadow(rgba(0, 0, 0, 0.3) 0px 0px 6px 4px);
|
||||||
@include border-bottom-radius(4px);
|
@include border-bottom-radius(4px);
|
||||||
|
|
||||||
min-height: 150px;
|
min-height: 290px;
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
@include locomotive-link;
|
@include locomotive-link;
|
||||||
@ -120,11 +120,9 @@ body {
|
|||||||
} // > div.inner h2
|
} // > div.inner h2
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
background: transparent image-url("locomotive/list/item.png") no-repeat 0 0;
|
|
||||||
|
|
||||||
padding: 7px 0 10px 20px;
|
padding: 7px 0 10px 20px;
|
||||||
|
|
||||||
font-size: 13px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #1e1f26;
|
color: #1e1f26;
|
||||||
@include single-text-shadow(#fff, 1px, 1px, 1px);
|
@include single-text-shadow(#fff, 1px, 1px, 1px);
|
||||||
@ -149,9 +147,10 @@ body {
|
|||||||
} // #content #local-actions-bar
|
} // #content #local-actions-bar
|
||||||
|
|
||||||
#local-actions-bottom-bar {
|
#local-actions-bottom-bar {
|
||||||
position: relative;
|
position: absolute;
|
||||||
top: 20px;
|
bottom: 0px;
|
||||||
left: -15px;
|
left: 0px;
|
||||||
|
height: 62px;
|
||||||
width: 950px;
|
width: 950px;
|
||||||
|
|
||||||
background: #8b8d9a;
|
background: #8b8d9a;
|
||||||
@ -162,8 +161,6 @@ body {
|
|||||||
padding: 15px;
|
padding: 15px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
|
||||||
line-height: 13px;
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 4px;
|
top: 4px;
|
||||||
@ -172,7 +169,10 @@ body {
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|
||||||
&.remove { color: #ff092c; }
|
&.remove {
|
||||||
|
@include red-button;
|
||||||
|
top: 0px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ module Locomotive
|
|||||||
before_filter :authorize_content
|
before_filter :authorize_content
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@content_entries = @content_type.entries
|
@content_entries = @content_type.list_or_group_entries
|
||||||
respond_with @content_entries
|
respond_with @content_entries
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -38,17 +38,14 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
def sort
|
def sort
|
||||||
# TODO
|
@content_type.klass_with_custom_fields(:entries).sort_entries!(params[:entries])
|
||||||
# @content_type.sort_contents!(params[:children])
|
|
||||||
# @page = current_site.pages.find(params[:id])
|
|
||||||
# @page.sort_children!(params[:children])
|
|
||||||
respond_with @content_type
|
respond_with @content_type
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@content_entry = @content_type.entries.find(params[:id])
|
@content_entry = @content_type.entries.find(params[:id])
|
||||||
@content_entry.destroy
|
@content_entry.destroy
|
||||||
respond_with @content_entry, :location => pages_url
|
respond_with @content_entry, :location => content_entries_url(@content_type.slug)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -18,6 +18,22 @@ module Locomotive::ContentTypesHelper
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def entry_label(content_type, entry)
|
||||||
|
if content_type.raw_item_template.blank?
|
||||||
|
entry._label # default one
|
||||||
|
else
|
||||||
|
assigns = { 'site' => current_site, 'entry' => entry }
|
||||||
|
|
||||||
|
registers = {
|
||||||
|
:controller => self,
|
||||||
|
:site => current_site,
|
||||||
|
:current_locomotive_account => current_locomotive_account
|
||||||
|
}
|
||||||
|
|
||||||
|
preserve(content_type.item_template.render(::Liquid::Context.new({}, assigns, registers)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# MAX_DISPLAYED_CONTENTS = 4
|
# MAX_DISPLAYED_CONTENTS = 4
|
||||||
#
|
#
|
||||||
# def fetch_content_types
|
# def fetch_content_types
|
||||||
|
@ -23,7 +23,7 @@ module Locomotive
|
|||||||
before_validation :set_slug
|
before_validation :set_slug
|
||||||
before_save :set_visibility
|
before_save :set_visibility
|
||||||
before_create :add_to_list_bottom
|
before_create :add_to_list_bottom
|
||||||
# after_create :send_notifications
|
after_create :send_notifications
|
||||||
|
|
||||||
## named scopes ##
|
## named scopes ##
|
||||||
scope :visible, :where => { :_visible => true }
|
scope :visible, :where => { :_visible => true }
|
||||||
@ -51,8 +51,17 @@ module Locomotive
|
|||||||
next_or_previous :lt
|
next_or_previous :lt
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.sort_entries!(ids)
|
||||||
|
list = self.any_in(:_id => ids.map { |id| BSON::ObjectId.from_string(id.to_s) }).to_a
|
||||||
|
ids.each_with_index do |id, position|
|
||||||
|
if entry = list.detect { |e| e._id.to_s == id.to_s }
|
||||||
|
entry.update_attributes :_position => position
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def to_liquid
|
def to_liquid
|
||||||
Locomotive::Liquid::Drops::Content.new(self)
|
Locomotive::Liquid::Drops::ContentEntry.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_presenter
|
def to_presenter
|
||||||
@ -66,37 +75,35 @@ module Locomotive
|
|||||||
protected
|
protected
|
||||||
|
|
||||||
def next_or_previous(matcher = :gt)
|
def next_or_previous(matcher = :gt)
|
||||||
attribute = self.content_type.order_by.to_sym
|
order_by = self.content_type.order_by_definition
|
||||||
direction = self.content_type.order_direction || 'asc'
|
|
||||||
criterion = attribute.send(matcher)
|
criterion = attribute.send(matcher)
|
||||||
|
|
||||||
self.class.where(criterion => self.send(attribute)).order_by([[attribute, direction]]).limit(1).first
|
self.class.where(criterion => self.send(attribute)).order_by([order_by]).limit(1).first
|
||||||
end
|
end
|
||||||
|
|
||||||
# Sets the slug of the instance by using the value of the highlighted field
|
# Sets the slug of the instance by using the value of the highlighted field
|
||||||
# (if available). If a sibling content instance has the same permalink then a
|
# (if available). If a sibling content instance has the same permalink then a
|
||||||
# unique one will be generated
|
# unique one will be generated
|
||||||
def set_slug
|
def set_slug
|
||||||
# self._slug = highlighted_field_value.dup if _slug.blank? && highlighted_field_value.present?
|
self._slug = self._label.dup if self._slug.blank? && self._label.present?
|
||||||
#
|
|
||||||
# if _slug.present?
|
if self._slug.present?
|
||||||
# self._slug.permalink!
|
self._slug.permalink!
|
||||||
# self._slug = next_unique_slug if slug_already_taken?
|
self._slug = self.next_unique_slug if self.slug_already_taken?
|
||||||
# end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return the next available unique slug as a string
|
# Return the next available unique slug as a string
|
||||||
def next_unique_slug
|
def next_unique_slug
|
||||||
# slug = _slug.gsub(/-\d*$/, '')
|
slug = self._slug.gsub(/-\d*$/, '')
|
||||||
# last_slug = _parent.contents.where(:_id.ne => _id, :_slug => /^#{slug}-?\d*?$/i).order_by(:_slug).last._slug
|
last_slug = self.class.where(:_id.ne => self._id, :_slug => /^#{slug}-?\d*?$/i).order_by(:_slug).last._slug
|
||||||
# next_number = last_slug.scan(/-(\d)$/).flatten.first.to_i + 1
|
next_number = last_slug.scan(/-(\d)$/).flatten.first.to_i + 1
|
||||||
#
|
[slug, next_number].join('-')
|
||||||
# [slug, next_number].join('-')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# def slug_already_taken?
|
def slug_already_taken?
|
||||||
# _parent.contents.where(:_id.ne => _id, :_slug => _slug).any?
|
self.class.where(:_id.ne => self._id, :_slug => self._slug).any?
|
||||||
# end
|
end
|
||||||
|
|
||||||
def set_visibility
|
def set_visibility
|
||||||
[:visible, :active].each do |meth|
|
[:visible, :active].each do |meth|
|
||||||
@ -111,19 +118,15 @@ module Locomotive
|
|||||||
self._position = self.class.max(:_position).to_i + 1
|
self._position = self.class.max(:_position).to_i + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
# def send_notifications
|
def send_notifications
|
||||||
# return unless self.content_type.api_enabled? && !self.content_type.api_accounts.blank?
|
return if !self.content_type.public_form_enabled? || self.content_type.public_form_accounts.blank?
|
||||||
#
|
|
||||||
# accounts = self.content_type.site.accounts.to_a
|
self.content_type.site.accounts.each do |account|
|
||||||
#
|
next unless self.content_type.public_form_accounts.include?(account._id.to_s)
|
||||||
# self.content_type.api_accounts.each do |account_id|
|
|
||||||
# next if account_id.blank?
|
Locomotive::Notifications.new_content_entry(account, self).deliver
|
||||||
#
|
end
|
||||||
# account = accounts.detect { |a| a.id.to_s == account_id.to_s }
|
end
|
||||||
#
|
|
||||||
# Locomotive::Notifications.new_content_instance(account, self).deliver
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -44,20 +44,33 @@ module Locomotive
|
|||||||
|
|
||||||
## methods ##
|
## methods ##
|
||||||
|
|
||||||
# def groupable?
|
|
||||||
# self.group_by_field && group_by_field.category?
|
|
||||||
# end
|
|
||||||
|
|
||||||
def group_by_field
|
|
||||||
self.entries_custom_fields.find(self.group_by_field_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def order_manually?
|
def order_manually?
|
||||||
self.order_by == '_position'
|
self.order_by == '_position'
|
||||||
end
|
end
|
||||||
|
|
||||||
def asc_order?
|
def order_by_definition
|
||||||
self.order_direction.blank? || self.order_direction == 'asc'
|
direction = self.order_manually? ? 'asc' : self.order_direction || 'asc'
|
||||||
|
[order_by_attribute, direction]
|
||||||
|
end
|
||||||
|
|
||||||
|
def ordered_entries
|
||||||
|
self.entries.order_by([order_by_definition])
|
||||||
|
end
|
||||||
|
|
||||||
|
def groupable?
|
||||||
|
!!self.group_by_field && group_by_field.type == 'select'
|
||||||
|
end
|
||||||
|
|
||||||
|
def group_by_field
|
||||||
|
self.entries_custom_fields.find(self.group_by_field_id) rescue nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def list_or_group_entries
|
||||||
|
if self.groupable?
|
||||||
|
self.entries.group_by_select_option(self.group_by_field.name, self.order_by_definition)
|
||||||
|
else
|
||||||
|
self.ordered_entries
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_presenter
|
def to_presenter
|
||||||
@ -135,6 +148,11 @@ module Locomotive
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def order_by_attribute
|
||||||
|
return self.order_by if %w(created_at updated_at _position).include?(self.order_by)
|
||||||
|
self.entries_custom_fields.find(self.order_by).name rescue 'created_at'
|
||||||
|
end
|
||||||
|
|
||||||
def set_default_values
|
def set_default_values
|
||||||
self.order_by ||= 'created_at'
|
self.order_by ||= 'created_at'
|
||||||
field = self.entries_custom_fields.find(self.label_field_id) rescue self.entries_custom_fields.first
|
field = self.entries_custom_fields.find(self.label_field_id) rescue self.entries_custom_fields.first
|
||||||
|
@ -38,7 +38,7 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
def accounts
|
def accounts
|
||||||
Account.criteria.in(:_id => self.memberships.collect(&:account_id))
|
Account.criteria.in(:_id => self.memberships.map(&:account_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
def admin_memberships
|
def admin_memberships
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
- if contents.empty?
|
- if entries.empty?
|
||||||
%p.no-items!= t('.no_items', :url => new_content_entry_url(@content_type.slug))
|
%p.no-items!= t('.no_items', :url => new_content_entry_url(content_type.slug))
|
||||||
- else
|
- else
|
||||||
%ul{ :id => 'contents-list', :class => "list #{'sortable' if @content_type.order_by == '_position'}", :'data-url' => sort_admin_contents_path(@content_type.slug, :json) }
|
%ul{ :id => 'entries-list', :class => "#{'list' unless content_type.groupable?} #{'sortable' if content_type.order_manually?}", :'data-url' => sort_content_entries_url(content_type.slug, :json) }
|
||||||
- contents.each do |content|
|
- entries.each do |entry|
|
||||||
%li.content{ :id => "content-#{content._id}" }
|
%li.item{ :id => "entry-#{entry._id}" }
|
||||||
%em
|
%span.handle
|
||||||
%strong
|
= image_tag 'locomotive/form/icons/drag.png'
|
||||||
= link_to content_label_for(content), edit_admin_content_path(@content_type.slug, content)
|
%strong= link_to entry_label(content_type, entry), edit_content_entry_url(content_type.slug, entry)
|
||||||
.more
|
.more
|
||||||
%span
|
%span
|
||||||
!= t('locomotive.contents.index.updated_at')
|
!= t('locomotive.content_entries.index.updated_at')
|
||||||
= l content.updated_at, :format => :short rescue 'n/a'
|
= l entry.updated_at, :format => :short rescue 'n/a'
|
||||||
|
|
||||||
= link_to image_tag('admin/list/icons/trash.png', :alt => t('locomotive.buttons.delete')), admin_content_path(@content_type.slug, content), :class => 'remove', :confirm => t('locomotive.messages.confirm'), :method => :delete
|
= link_to 'x', content_entry_url(content_type.slug, entry), :class => 'remove', :confirm => t('locomotive.messages.confirm'), :method => :delete
|
@ -6,9 +6,6 @@
|
|||||||
- content_for :actions do
|
- content_for :actions do
|
||||||
= render 'locomotive/shared/actions/contents'
|
= render 'locomotive/shared/actions/contents'
|
||||||
|
|
||||||
- content_for :head do
|
|
||||||
= include_javascripts :contents
|
|
||||||
|
|
||||||
- content_for :buttons do
|
- content_for :buttons do
|
||||||
- if can?(:manage, Locomotive::ContentType)
|
- if can?(:manage, Locomotive::ContentType)
|
||||||
= local_action_button :edit, edit_content_type_url(@content_type), :class => 'edit'
|
= local_action_button :edit, edit_content_type_url(@content_type), :class => 'edit'
|
||||||
@ -19,14 +16,15 @@
|
|||||||
%p= @content_type.description
|
%p= @content_type.description
|
||||||
|
|
||||||
- if @content_type.groupable?
|
- if @content_type.groupable?
|
||||||
- @contents.each do |group|
|
- @content_entries.each do |group|
|
||||||
%h3= group[:name] || t('.category_noname')
|
.box
|
||||||
= render 'list', :contents => group[:items]
|
%h3= group[:name] || t('.category_noname')
|
||||||
%br
|
.inner
|
||||||
|
= render 'list', :content_type => @content_type, :entries => group[:entries]
|
||||||
- else
|
- else
|
||||||
= render 'list', :contents => @contents
|
= render 'list', :content_type => @content_type, :entries => @content_entries
|
||||||
|
|
||||||
- if can?(:manage, Locomotive::ContentType)
|
- if can?(:manage, Locomotive::ContentType)
|
||||||
#local-actions-bottom-bar
|
#local-actions-bottom-bar
|
||||||
%p.tleft
|
%p.tleft
|
||||||
= link_to(content_tag(:em, escape_once(' ')) + t('.destroy'), content_type_url(@content_type), :confirm => t('locomotive.messages.confirm'), :method => :delete, :class => 'button small remove')
|
= link_to t('.destroy'), content_type_url(@content_type), :confirm => t('locomotive.messages.confirm'), :method => :delete, :class => 'button remove'
|
||||||
|
@ -30,4 +30,4 @@
|
|||||||
- if can?(:manage, current_site)
|
- if can?(:manage, current_site)
|
||||||
|
|
||||||
= f.inputs :name => :robots_txt, :class => "inputs foldable #{'folded' if inputs_folded?(@site)}" do
|
= f.inputs :name => :robots_txt, :class => "inputs foldable #{'folded' if inputs_folded?(@site)}" do
|
||||||
= f.input :robots_txt, :as => :'Locomotive::Code', :picker => false, :wrapper_html => { :class => 'small' }
|
= f.input :robots_txt, :as => :'Locomotive::Code', :picker => false, :wrapper_html => { :class => 'small no-label' }
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
!!!
|
!!!
|
||||||
%html{ :xmlns => 'http://www.w3.org/1999/xhtml' }
|
%html{ :xmlns => 'http://www.w3.org/1999/xhtml' }
|
||||||
%head
|
%head
|
||||||
%title= yield(:head_title) || escape_once("#{Locomotive.config.name} — #{current_site.name}")
|
%title= title || escape_once("#{Locomotive.config.name} — #{current_site.name}")
|
||||||
|
|
||||||
= javascript_include_tag 'jquery.js'
|
= javascript_include_tag 'jquery.js'
|
||||||
= stylesheet_link_tag 'locomotive/not_logged_in', :media => 'screen'
|
= stylesheet_link_tag 'locomotive/not_logged_in', :media => 'screen'
|
||||||
|
@ -250,7 +250,7 @@ en:
|
|||||||
lastest_entries: "Lastest entries"
|
lastest_entries: "Lastest entries"
|
||||||
updated_at: "Updated at"
|
updated_at: "Updated at"
|
||||||
list:
|
list:
|
||||||
no_entries: "There are no entries for now. Just click <a href=\"%{url}\">here</a> to create the first one."
|
no_items: "There are no entries for now. Just click <a href=\"%{url}\">here</a> to create the first one."
|
||||||
new:
|
new:
|
||||||
title: '%{type} — new entry'
|
title: '%{type} — new entry'
|
||||||
edit:
|
edit:
|
||||||
|
@ -94,7 +94,7 @@ en:
|
|||||||
content_type:
|
content_type:
|
||||||
name: "We suggest you to type the plural form of the model. Ex: Projects, Recipes, Posts, Articles, ...etc"
|
name: "We suggest you to type the plural form of the model. Ex: Projects, Recipes, Posts, Articles, ...etc"
|
||||||
slug: "It will be used as the name of the collection in the liquid templates. Ex: <span class='code'>{{ contents.my_projects }}</span>"
|
slug: "It will be used as the name of the collection in the liquid templates. Ex: <span class='code'>{{ contents.my_projects }}</span>"
|
||||||
raw_item_template: "You can customize the text displayed for each item in the list. Simply use Liquid. Ex: <span class='code'>{{ content.name }})</span>"
|
raw_item_template: "You can customize the text displayed for each item in the list. Simply use Liquid. Ex: <span class='code'>{{ entry.name }})</span>"
|
||||||
public_form_enabled: "It is used to let people from outside to create new instances (example: messages in a contact form)"
|
public_form_enabled: "It is used to let people from outside to create new instances (example: messages in a contact form)"
|
||||||
public_form_accounts: "A notification email will be sent to each of the accounts listed above when a new instance is created"
|
public_form_accounts: "A notification email will be sent to each of the accounts listed above when a new instance is created"
|
||||||
"custom_fields/field":
|
"custom_fields/field":
|
||||||
|
@ -79,6 +79,6 @@ es:
|
|||||||
samples: "Si se activa, la importación también copiará contenido multimedia y páginas"
|
samples: "Si se activa, la importación también copiará contenido multimedia y páginas"
|
||||||
reset: "Si se activa, toda la información del sitio será eliminada antes de importar"
|
reset: "Si se activa, toda la información del sitio será eliminada antes de importar"
|
||||||
content_type:
|
content_type:
|
||||||
raw_item_template: "Puede personalizar el texto mostrado para cada elemento de la lista. Simplemente utilice Liquid. Ej: {{ content.name }})"
|
raw_item_template: "Puede personalizar el texto mostrado para cada elemento de la lista. Simplemente utilice Liquid. Ej: {{ entry.name }})"
|
||||||
api_enabled: "Se utiliza para dejar crear elementos a gente externa a la aplicación (ejemplo: mensajes en un formulario de contacto)"
|
api_enabled: "Se utiliza para dejar crear elementos a gente externa a la aplicación (ejemplo: mensajes en un formulario de contacto)"
|
||||||
api_accounts: "Un email de notificación será enviado a las cuentas listadas más arriba cuando un nuevo elemento se cree"
|
api_accounts: "Un email de notificación será enviado a las cuentas listadas más arriba cuando un nuevo elemento se cree"
|
||||||
|
@ -94,6 +94,6 @@ fr:
|
|||||||
reset: "Si activé, toutes les données de votre site seront détruites avant l'import du nouveau site"
|
reset: "Si activé, toutes les données de votre site seront détruites avant l'import du nouveau site"
|
||||||
content_type:
|
content_type:
|
||||||
slug: Nom utilisé dans les templates liquid afin d'accéder aux enregistrements de ce modèle
|
slug: Nom utilisé dans les templates liquid afin d'accéder aux enregistrements de ce modèle
|
||||||
item_template: "Personnaliser le texte affiché pour chaque élément de la liste. Utilisez simplement du code Liquid. Ex: {{ content.name }}"
|
item_template: "Personnaliser le texte affiché pour chaque élément de la liste. Utilisez simplement du code Liquid. Ex: {{ entry.name }}"
|
||||||
api_enabled: "Utilisé pour autoriser la création de nouvelles instances de l'extérieur (ex.: les messages dans un formulaire de contact)"
|
api_enabled: "Utilisé pour autoriser la création de nouvelles instances de l'extérieur (ex.: les messages dans un formulaire de contact)"
|
||||||
api_accounts: "Un email de notification sera envoyé à chaque compte listé ci-dessus lors de la création d'une nouvelle instance"
|
api_accounts: "Un email de notification sera envoyé à chaque compte listé ci-dessus lors de la création d'une nouvelle instance"
|
||||||
|
@ -93,7 +93,7 @@ it:
|
|||||||
samples: "Se attivato, il processo di import copierà anche contenuti e risorse"
|
samples: "Se attivato, il processo di import copierà anche contenuti e risorse"
|
||||||
reset: "Se attivato, tutti i dati del tuo sito saranno cancellati prima di importare il nuovo sito"
|
reset: "Se attivato, tutti i dati del tuo sito saranno cancellati prima di importare il nuovo sito"
|
||||||
content_type:
|
content_type:
|
||||||
item_template: "Puoi personalizzare il testo visualizzato per ciascun elemento della lista semplicemente usando Liquid. Ex: {{ content.name }})"
|
item_template: "Puoi personalizzare il testo visualizzato per ciascun elemento della lista semplicemente usando Liquid. Ex: {{ entry.name }})"
|
||||||
api_enabled: "E' usato per lasciare che i visitatori, da fuori, possano creare nuove istanze (per esempio: i messaggi da un form 'contattaci')"
|
api_enabled: "E' usato per lasciare che i visitatori, da fuori, possano creare nuove istanze (per esempio: i messaggi da un form 'contattaci')"
|
||||||
api_accounts: "Quando viene creata una nuova istanza, una mail di notifica verrà inviata a tutti gli account elencati qui sopra"
|
api_accounts: "Quando viene creata una nuova istanza, una mail di notifica verrà inviata a tutti gli account elencati qui sopra"
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ nl:
|
|||||||
samples: "Het importeren zal ook de contents en bronbestanden copiëren als deze optie aanstaat"
|
samples: "Het importeren zal ook de contents en bronbestanden copiëren als deze optie aanstaat"
|
||||||
reset: "Alle data van uw website zal verwijderd worden voordat de nieuwe website wordt geimporteerd als deze optie aanstaat"
|
reset: "Alle data van uw website zal verwijderd worden voordat de nieuwe website wordt geimporteerd als deze optie aanstaat"
|
||||||
content_type:
|
content_type:
|
||||||
raw_item_template: "U kunt de tekst voor elk item in de lijst aanpassen. Ie: {{ content.name }})"
|
raw_item_template: "U kunt de tekst voor elk item in de lijst aanpassen. Ie: {{ entry.name }})"
|
||||||
api_enabled: "It is used to let people from outside to create new instances (example: messages in a contact form)"
|
api_enabled: "It is used to let people from outside to create new instances (example: messages in a contact form)"
|
||||||
api_enabled: "Wordt gebruikt om mensen van buiten nieuwe instanties te laten creëren (voorbeeld: berichten in een contactformulier)"
|
api_enabled: "Wordt gebruikt om mensen van buiten nieuwe instanties te laten creëren (voorbeeld: berichten in een contactformulier)"
|
||||||
api_accounts: "Een e-mail met een aankondiging zal worden verstuurd naar de bovenstaande accounts wanneer een nieuwe instantie wordt gecreëerd"
|
api_accounts: "Een e-mail met een aankondiging zal worden verstuurd naar de bovenstaande accounts wanneer een nieuwe instantie wordt gecreëerd"
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
samples: "Vil gjøre at importen kopierer innhold og assets"
|
samples: "Vil gjøre at importen kopierer innhold og assets"
|
||||||
reset: "Vil gjøre at alle data slettes for den nye siden importeres."
|
reset: "Vil gjøre at alle data slettes for den nye siden importeres."
|
||||||
content_type:
|
content_type:
|
||||||
item_template: "Du kan justere teksten som vises for hvert element i listen. Bruk liquid, f.eks: {{ content.name }}"
|
item_template: "Du kan justere teksten som vises for hvert element i listen. Bruk liquid, f.eks: {{ entry.name }}"
|
||||||
api_enabled: "Brukes for å la sidebrukere opprette ny elementer (f.eks: meldinger i et kontaktskjema)"
|
api_enabled: "Brukes for å la sidebrukere opprette ny elementer (f.eks: meldinger i et kontaktskjema)"
|
||||||
api_accounts: "En varslingsepost vil bli sendt til alle kontoene ovenfor når et nytt element blir opprettet."
|
api_accounts: "En varslingsepost vil bli sendt til alle kontoene ovenfor når et nytt element blir opprettet."
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ ru:
|
|||||||
samples: "Если включено, процесс импорта также скопирует содержимое и файлы"
|
samples: "Если включено, процесс импорта также скопирует содержимое и файлы"
|
||||||
reset: "Если включено, все данные вашего сайта будут уничтожены перед импортом нового сайта"
|
reset: "Если включено, все данные вашего сайта будут уничтожены перед импортом нового сайта"
|
||||||
content_type:
|
content_type:
|
||||||
item_template: "Вы можете задавать текст, отображаемый для каждого элемента в списке. Просто используйте Liquid. Пр.: {{ content.name }})"
|
item_template: "Вы можете задавать текст, отображаемый для каждого элемента в списке. Просто используйте Liquid. Пр.: {{ entry.name }})"
|
||||||
api_enabled: "Это используется для того, чтобы дать людям извне возможность создавать новые экземляры (пример: сообщения в форме контакта)"
|
api_enabled: "Это используется для того, чтобы дать людям извне возможность создавать новые экземляры (пример: сообщения в форме контакта)"
|
||||||
api_accounts: "Письмо с уведомлением будет отправлено на каждый аккаунт из списка выше, когда создан новый экземпляр"
|
api_accounts: "Письмо с уведомлением будет отправлено на каждый аккаунт из списка выше, когда создан новый экземпляр"
|
||||||
|
|
||||||
|
12
doc/TODO
12
doc/TODO
@ -34,7 +34,7 @@ x edit my site
|
|||||||
x site picker
|
x site picker
|
||||||
- content types
|
- content types
|
||||||
x move content instances into their own collection
|
x move content instances into their own collection
|
||||||
- manage custom_fields
|
x manage custom_fields
|
||||||
x automatic name
|
x automatic name
|
||||||
x required
|
x required
|
||||||
x editable plugin: add class depending on the type => surrounding span instead
|
x editable plugin: add class depending on the type => surrounding span instead
|
||||||
@ -50,17 +50,17 @@ x edit my site
|
|||||||
x select: add/edit/remove options
|
x select: add/edit/remove options
|
||||||
x text: formatting
|
x text: formatting
|
||||||
- change in main menu
|
- change in main menu
|
||||||
- manage contents
|
x manage contents
|
||||||
- list (highlighted field)
|
x list (highlighted field)
|
||||||
- slugify
|
x slugify
|
||||||
- crud
|
x crud
|
||||||
x new
|
x new
|
||||||
x date
|
x date
|
||||||
x checkbox
|
x checkbox
|
||||||
x html
|
x html
|
||||||
x file
|
x file
|
||||||
x edit
|
x edit
|
||||||
- destroy
|
x destroy
|
||||||
- public_form (previously api something)
|
- public_form (previously api something)
|
||||||
|
|
||||||
- disallow to click twice on the submit form button (spinner ?)
|
- disallow to click twice on the submit form button (spinner ?)
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
module Locomotive
|
module Locomotive
|
||||||
module Liquid
|
module Liquid
|
||||||
module Drops
|
module Drops
|
||||||
class Content < Base
|
class ContentEntry < Base
|
||||||
|
|
||||||
delegate :seo_title, :meta_keywords, :meta_description, :to => '_source'
|
delegate :_slug, :_permalink, :seo_title, :meta_keywords, :meta_description, :to => '_source'
|
||||||
|
|
||||||
def _id
|
def _id
|
||||||
self._source._id.to_s
|
self._source._id.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the next content for the parent content type.
|
# Returns the next content for the parent content type.
|
||||||
# If no content is found, nil is returned.
|
# If no content is found, nil is returned.
|
||||||
#
|
#
|
||||||
@ -21,7 +21,7 @@ module Locomotive
|
|||||||
def next
|
def next
|
||||||
self._source.next.to_liquid
|
self._source.next.to_liquid
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the previous content for the parent content type.
|
# Returns the previous content for the parent content type.
|
||||||
# If no content is found, nil is returned.
|
# If no content is found, nil is returned.
|
||||||
#
|
#
|
||||||
@ -43,8 +43,8 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def highlighted_field_value
|
def _label
|
||||||
self._source.highlighted_field_value
|
self._label
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
@ -15,91 +15,6 @@ end
|
|||||||
# Limit feature for embedded documents
|
# Limit feature for embedded documents
|
||||||
|
|
||||||
module Mongoid #:nodoc:
|
module Mongoid #:nodoc:
|
||||||
module Criterion #:nodoc:
|
|
||||||
module Exclusion
|
|
||||||
|
|
||||||
def only(*args)
|
|
||||||
clone.tap do |crit|
|
|
||||||
crit.options[:fields] ||= {}
|
|
||||||
crit.options[:fields][:only] = args.flatten if args.any?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
module Optional
|
|
||||||
|
|
||||||
# Adds a criterion to the +Criteria+ that specifies the maximum number of
|
|
||||||
# results to return. This is mostly used in conjunction with <tt>skip()</tt>
|
|
||||||
# to handle paginated results.
|
|
||||||
#
|
|
||||||
# Options:
|
|
||||||
#
|
|
||||||
# value: An +Integer+ specifying the max number of results. Defaults to 20.
|
|
||||||
# hash: A +Hash+ specifying the max number of results for the embedded collections.
|
|
||||||
#
|
|
||||||
# Example:
|
|
||||||
#
|
|
||||||
# <tt>criteria.limit(100)</tt>
|
|
||||||
# <tt>criteria.limit(100, { :contents => 5 })</tt>
|
|
||||||
# <tt>criteria.limit(:contents => 5)</tt>
|
|
||||||
#
|
|
||||||
# Returns: <tt>self</tt>
|
|
||||||
def limit(*args)
|
|
||||||
clone.tap do |crit|
|
|
||||||
arguments = args.first || 20
|
|
||||||
fields = nil # hash of embedded collections
|
|
||||||
|
|
||||||
case arguments
|
|
||||||
when Integer
|
|
||||||
crit.options[:limit] = arguments
|
|
||||||
fields = args[1] if args.size > 1
|
|
||||||
when Hash
|
|
||||||
fields = arguments
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields
|
|
||||||
crit.options[:fields] ||= {}
|
|
||||||
crit.options[:fields][:limit] = fields
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module Contexts #:nodoc:
|
|
||||||
class Mongo
|
|
||||||
|
|
||||||
# Filters the field list. If no fields have been supplied, then it will be
|
|
||||||
# empty. If fields have been defined then _type will be included as well.
|
|
||||||
def process_options
|
|
||||||
fields = options[:fields]
|
|
||||||
only = fields.delete(:only) if fields
|
|
||||||
limits = fields.delete(:limit) if fields
|
|
||||||
|
|
||||||
# only ?
|
|
||||||
if only && only.size > 0
|
|
||||||
only << :_type if !only.include?(:_type)
|
|
||||||
only.each do |field|
|
|
||||||
options[:fields].merge!(field => 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# limit for embedded collections ?
|
|
||||||
if limits && limits.size > 0
|
|
||||||
limits.each do |field, limit|
|
|
||||||
next if limit.blank?
|
|
||||||
options[:fields][field] = { '$slice' => limit }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
options.dup
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
# without callback feature
|
# without callback feature
|
||||||
module Callbacks
|
module Callbacks
|
||||||
|
@ -46,16 +46,16 @@ describe Locomotive::Import::Job do
|
|||||||
content_type = @site.content_types.where(:slug => 'projects').first
|
content_type = @site.content_types.where(:slug => 'projects').first
|
||||||
content_type.entries.size.should == 5
|
content_type.entries.size.should == 5
|
||||||
|
|
||||||
content = content_type.entries.first
|
entry = content_type.entries.first
|
||||||
content._permalink.should == 'locomotivecms'
|
entry._permalink.should == 'locomotivecms'
|
||||||
content.seo_title.should == 'My open source CMS'
|
entry.seo_title.should == 'My open source CMS'
|
||||||
content.meta_description.should == 'bla bla bla'
|
entry.meta_description.should == 'bla bla bla'
|
||||||
content.meta_keywords.should == 'cms ruby engine mongodb'
|
entry.meta_keywords.should == 'cms ruby engine mongodb'
|
||||||
content.name.should == 'Locomotive App'
|
entry.name.should == 'Locomotive App'
|
||||||
content.thumbnail.url.should_not be_nil
|
entry.thumbnail.url.should_not be_nil
|
||||||
content.featured.should == true
|
entry.featured.should == true
|
||||||
content.client.name.should == 'My client #1'
|
entry.client.name.should == 'My client #1'
|
||||||
content.team.first.name.should == 'Michael Scott'
|
entry.team.first.name.should == 'Michael Scott'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'inserts theme assets' do
|
it 'inserts theme assets' do
|
||||||
|
Loading…
Reference in New Issue
Block a user