refactoring the content types section (wip)
This commit is contained in:
parent
592a110fe5
commit
217000042a
4
Gemfile
4
Gemfile
@ -12,7 +12,9 @@ gem 'cancan', '~> 1.6.7'
|
|||||||
gem 'bson_ext', '~> 1.4.0'
|
gem 'bson_ext', '~> 1.4.0'
|
||||||
gem 'mongoid', '~> 2.3.3'
|
gem 'mongoid', '~> 2.3.3'
|
||||||
gem 'locomotive_mongoid_acts_as_tree', :git => 'git@github.com:locomotivecms/mongoid_acts_as_tree.git'
|
gem 'locomotive_mongoid_acts_as_tree', :git => 'git@github.com:locomotivecms/mongoid_acts_as_tree.git'
|
||||||
gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git'
|
# gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git'
|
||||||
|
# gem 'custom_fields', :path => '../gems/custom_fields' # DEV
|
||||||
|
gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git', :branch => 'experimental'
|
||||||
gem 'kaminari'
|
gem 'kaminari'
|
||||||
|
|
||||||
gem 'haml', '~> 3.1.3'
|
gem 'haml', '~> 3.1.3'
|
||||||
|
@ -9,12 +9,13 @@ GIT
|
|||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/locomotivecms/custom_fields.git
|
remote: git://github.com/locomotivecms/custom_fields.git
|
||||||
revision: af21782109d5b4f073949f8f123fb56c6c7227ef
|
revision: 9cc4a3ca7e2306a59a9ad0c8a837a35d8fc5dfc6
|
||||||
|
branch: experimental
|
||||||
specs:
|
specs:
|
||||||
custom_fields (1.1.0.rc1)
|
custom_fields (2.0.0.rc1)
|
||||||
activesupport (~> 3.1.1)
|
activesupport (~> 3.1.3)
|
||||||
carrierwave-mongoid (~> 0.1.3)
|
carrierwave-mongoid (~> 0.1.3)
|
||||||
mongoid (~> 2.3.3)
|
mongoid (~> 2.3.4)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/plataformatec/devise.git
|
remote: git://github.com/plataformatec/devise.git
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
class Locomotive.Models.ContentType extends Backbone.Model
|
||||||
|
|
||||||
|
paramRoot: 'content_type'
|
||||||
|
|
||||||
|
urlRoot: "#{Locomotive.mount_on}/content_types"
|
||||||
|
|
||||||
|
initialize: ->
|
||||||
|
@_normalize()
|
||||||
|
|
||||||
|
_normalize: ->
|
||||||
|
@set
|
||||||
|
contents_custom_fields: new Locomotive.Models.CustomFieldsCollection(@get('contents_custom_fields'))
|
||||||
|
|
||||||
|
toJSON: ->
|
||||||
|
_.tap super, (hash) =>
|
||||||
|
hash.contents_custom_fields = @get('contents_custom_fields').toJSONForSave() if @get('contents_custom_fields')
|
||||||
|
|
||||||
|
class Locomotive.Models.ContentTypesCollection extends Backbone.Collection
|
||||||
|
|
||||||
|
model: Locomotive.Models.ContentType
|
||||||
|
|
||||||
|
url: "#{Locomotive.mount_on}/content_types"
|
@ -0,0 +1,17 @@
|
|||||||
|
class Locomotive.Models.CustomField extends Backbone.Model
|
||||||
|
|
||||||
|
initialize: ->
|
||||||
|
unless @get('name')?
|
||||||
|
@set name: @get('label').slugify()
|
||||||
|
|
||||||
|
toJSONForSave: ->
|
||||||
|
_.tap {}, (hash) =>
|
||||||
|
for key, value of @.toJSON()
|
||||||
|
hash[key] = value unless _.include(['type_text', 'created_at', 'updated_at'], key)
|
||||||
|
|
||||||
|
class Locomotive.Models.CustomFieldsCollection extends Backbone.Collection
|
||||||
|
|
||||||
|
model: Locomotive.Models.CustomField
|
||||||
|
|
||||||
|
toJSONForSave: ->
|
||||||
|
@map (model) => model.toJSONForSave()
|
@ -0,0 +1,34 @@
|
|||||||
|
#= require ../shared/form_view
|
||||||
|
|
||||||
|
Locomotive.Views.ContentTypes ||= {}
|
||||||
|
|
||||||
|
class Locomotive.Views.ContentTypes.FormView extends Locomotive.Views.Shared.FormView
|
||||||
|
|
||||||
|
el: '#content'
|
||||||
|
|
||||||
|
events:
|
||||||
|
'submit': 'save'
|
||||||
|
|
||||||
|
initialize: ->
|
||||||
|
@model = new Locomotive.Models.ContentType(@options.content_type)
|
||||||
|
|
||||||
|
window.foo = @model
|
||||||
|
|
||||||
|
Backbone.ModelBinding.bind @
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
super()
|
||||||
|
|
||||||
|
@render_custom_fields()
|
||||||
|
|
||||||
|
return @
|
||||||
|
|
||||||
|
render_custom_fields: ->
|
||||||
|
@custom_fields_view = new Locomotive.Views.ContentTypes.CustomFieldsView model: @model #, errors: @options.errors
|
||||||
|
|
||||||
|
@$('#custom_fields_input').append(@custom_fields_view.render().el)
|
||||||
|
|
||||||
|
remove: ->
|
||||||
|
@custom_fields_view.remove()
|
||||||
|
super
|
||||||
|
|
@ -0,0 +1,35 @@
|
|||||||
|
Locomotive.Views.ContentTypes ||= {}
|
||||||
|
|
||||||
|
class Locomotive.Views.ContentTypes.CustomFieldEntryView extends Backbone.View
|
||||||
|
|
||||||
|
tagName: 'li'
|
||||||
|
|
||||||
|
className: 'custom-field'
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click a.edit': 'toggle_form'
|
||||||
|
'click a.remove': 'remove'
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
$(@el).html(ich.custom_field_entry(@model.toJSON()))
|
||||||
|
|
||||||
|
Backbone.ModelBinding.bind @, all: 'class'
|
||||||
|
|
||||||
|
return @
|
||||||
|
|
||||||
|
toggle_form: (event) ->
|
||||||
|
event.stopPropagation() & event.preventDefault()
|
||||||
|
form = @$('ol')
|
||||||
|
|
||||||
|
if form.is(':hidden')
|
||||||
|
form.slideDown()
|
||||||
|
else
|
||||||
|
form.slideUp()
|
||||||
|
|
||||||
|
remove: (event) ->
|
||||||
|
event.stopPropagation() & event.preventDefault()
|
||||||
|
|
||||||
|
if confirm($(event.target).attr('data-confirm'))
|
||||||
|
# @$('input[type=text]').editableField('destroy')
|
||||||
|
super()
|
||||||
|
@options.parent_view.remove_entry(@model, @)
|
@ -0,0 +1,95 @@
|
|||||||
|
Locomotive.Views.ContentTypes ||= {}
|
||||||
|
|
||||||
|
class Locomotive.Views.ContentTypes.CustomFieldsView extends Backbone.View
|
||||||
|
|
||||||
|
tagName: 'div'
|
||||||
|
|
||||||
|
className: 'list'
|
||||||
|
|
||||||
|
_entry_views = []
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click .new-entry a.add': 'add_entry'
|
||||||
|
'keypress .new-entry input[type=text]': 'add_on_entry_from_enter'
|
||||||
|
|
||||||
|
initialize: ->
|
||||||
|
_.bindAll(@, 'refresh_position_entries')
|
||||||
|
|
||||||
|
render: ->
|
||||||
|
$(@el).html(ich.custom_fields_list(@model.toJSON()))
|
||||||
|
|
||||||
|
@render_entries()
|
||||||
|
|
||||||
|
@make_list_sortable()
|
||||||
|
|
||||||
|
return @
|
||||||
|
|
||||||
|
make_list_sortable: ->
|
||||||
|
@sortable_list = @$('> ul').sortable
|
||||||
|
handle: 'span.handle'
|
||||||
|
items: 'li.custom-field'
|
||||||
|
axis: 'y'
|
||||||
|
update: @refresh_position_entries
|
||||||
|
|
||||||
|
refresh_position_entries: ->
|
||||||
|
_.each @_entry_views, (view) ->
|
||||||
|
view.model.set position: $(view.el).index()
|
||||||
|
|
||||||
|
add_entry: (event) ->
|
||||||
|
event.stopPropagation() & event.preventDefault()
|
||||||
|
|
||||||
|
labelInput = @$('.new-entry input[name=label]')
|
||||||
|
typeInput = @$('.new-entry select')
|
||||||
|
|
||||||
|
if labelInput.val() != ''
|
||||||
|
custom_field = new Locomotive.Models.CustomField label: labelInput.val(), type: typeInput.val()
|
||||||
|
|
||||||
|
window.bar = custom_field
|
||||||
|
|
||||||
|
@model.get('contents_custom_fields').add(custom_field)
|
||||||
|
|
||||||
|
@_insert_entry(custom_field)
|
||||||
|
|
||||||
|
@$('.empty').hide()
|
||||||
|
|
||||||
|
@sortable_list.sortable('refresh')
|
||||||
|
|
||||||
|
labelInput.val('') # reset for further entries
|
||||||
|
|
||||||
|
add_on_entry_from_enter: (event) ->
|
||||||
|
return if event.keyCode != 13
|
||||||
|
@add_entry(event)
|
||||||
|
|
||||||
|
remove_entry: (custom_field, view) ->
|
||||||
|
@_entry_views = _.reject @_entry_views, (_view) -> _view == view
|
||||||
|
@model.get('contents_custom_fields').remove(custom_field)
|
||||||
|
|
||||||
|
@refresh_position_entries()
|
||||||
|
|
||||||
|
@$('.empty').show() if @model.get('contents_custom_fields').length == 0
|
||||||
|
|
||||||
|
render_entries: ->
|
||||||
|
if @model.get('contents_custom_fields').length == 0
|
||||||
|
@$('.empty').show()
|
||||||
|
else
|
||||||
|
_.each @model.get('contents_custom_fields'), (custom_field) =>
|
||||||
|
@_insert_entry(custom_field)
|
||||||
|
|
||||||
|
#
|
||||||
|
# show_errors: ->
|
||||||
|
# _.each @options.errors.domain || [], (message) => @show_error(message)
|
||||||
|
#
|
||||||
|
# show_error: (message) ->
|
||||||
|
# _.each (@_entry_views || []), (view) ->
|
||||||
|
# if new RegExp("^#{view.model.get('name')}").test message
|
||||||
|
# html = $('<span></span>').addClass('inline-errors').html(message)
|
||||||
|
# view.$('input[type=text].path').after(html)
|
||||||
|
|
||||||
|
_insert_entry: (custom_field) ->
|
||||||
|
view = new Locomotive.Views.ContentTypes.CustomFieldEntryView model: custom_field, parent_view: @
|
||||||
|
|
||||||
|
(@_entry_views ||= []).push(view)
|
||||||
|
|
||||||
|
@$('ul').append(view.render().el)
|
||||||
|
|
||||||
|
@refresh_position_entries()
|
@ -0,0 +1,8 @@
|
|||||||
|
Locomotive.Views.ContentTypes ||= {}
|
||||||
|
|
||||||
|
class Locomotive.Views.ContentTypes.NewView extends Locomotive.Views.ContentTypes.FormView
|
||||||
|
|
||||||
|
save: (event) ->
|
||||||
|
@save_in_ajax event,
|
||||||
|
on_success: (response, xhr) ->
|
||||||
|
window.location.href = xhr.getResponseHeader('location')
|
@ -15,8 +15,6 @@ class Locomotive.Views.Sites.NewView extends Locomotive.Views.Shared.FormView
|
|||||||
|
|
||||||
Backbone.ModelBinding.bind @
|
Backbone.ModelBinding.bind @
|
||||||
|
|
||||||
window.foo = @model
|
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
super()
|
super()
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ form.formtastic {
|
|||||||
|
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@include single-text-shadow(#000, 0px, 1px, 1px);
|
@include single-text-shadow(rgba(0, 0, 0, 0.7), 0px, 1px, 1px);
|
||||||
}
|
}
|
||||||
} // div.inline-errors
|
} // div.inline-errors
|
||||||
|
|
||||||
|
@ -100,20 +100,25 @@ div#flash-notice {
|
|||||||
} // input
|
} // input
|
||||||
|
|
||||||
div.inline-errors {
|
div.inline-errors {
|
||||||
background: transparent image-url("locomotive/form/error-arrow.png") no-repeat 17px 0;
|
|
||||||
margin: 2px 0 0 0;
|
margin: 2px 0 0 0;
|
||||||
padding: 8px 0 0 0;
|
padding: 8px 0 0 0;
|
||||||
|
|
||||||
|
background: transparent image-url("locomotive/form/error-arrow.png") no-repeat 17px 0;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: auto;
|
width: auto;
|
||||||
|
line-height: 14px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 3px 12px 4px 30px;
|
padding: 3px 12px 4px 27px;
|
||||||
|
|
||||||
|
@include box-shadow(rgba(0, 0, 0, 0.4) 2px 2px 2px 0);
|
||||||
|
@include border-radius(3px);
|
||||||
|
background: #cd0f19 image-url("locomotive/form/icons/error.png") no-repeat 7px center;
|
||||||
|
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
text-shadow: #000 0px 1px;
|
font-size: 12px;
|
||||||
font-size: 11px;
|
@include single-text-shadow(rgba(0, 0, 0, 0.7), 0px, 1px, 1px);
|
||||||
padding-left: 30px;
|
|
||||||
background: #cd0f19 image-url("locomotive/form/icons/error.png") no-repeat 10px 6px;
|
|
||||||
}
|
}
|
||||||
} // div.inline-errors
|
} // div.inline-errors
|
||||||
|
|
||||||
@ -153,6 +158,7 @@ div#flash-notice {
|
|||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
|
|
||||||
background: #8b8d9a;
|
background: #8b8d9a;
|
||||||
|
border-top: 1px solid #5F6069;
|
||||||
@include border-bottom-radius(3px);
|
@include border-bottom-radius(3px);
|
||||||
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
@ -3,8 +3,36 @@ module Locomotive
|
|||||||
|
|
||||||
sections 'contents'
|
sections 'contents'
|
||||||
|
|
||||||
|
respond_to :json, :only => [:create, :update, :destroy]
|
||||||
|
|
||||||
|
helper 'Locomotive::CustomFields'
|
||||||
|
|
||||||
|
def new
|
||||||
|
@content_type = current_site.content_types.new
|
||||||
|
respond_with @content_type
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@content_type = current_site.content_types.create(params[:content_type])
|
||||||
|
logger.debug @content_type.contents_custom_fields.inspect
|
||||||
|
respond_with @content_type, :location => edit_content_type_url(@content_type._id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@content_type = current_site.content_types.find(params[:id])
|
||||||
|
respond_with @content_type
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@content_type = current_site.content_types.find(params[:id])
|
||||||
|
@content_type.update_attributes(params[:content_type])
|
||||||
|
respond_with @content_type, :location => edit_content_type_url(@content_type._id)
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
destroy! { pages_url }
|
@content_type = current_site.content_types.find(params[:id])
|
||||||
|
@content_type.destroy
|
||||||
|
respond_with @content_type, :location => pages_url
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,5 +1,23 @@
|
|||||||
module Locomotive::ContentTypesHelper
|
module Locomotive::ContentTypesHelper
|
||||||
|
|
||||||
|
def each_content_type_menu_item(&block)
|
||||||
|
current_site.content_types.ordered.only(:site_id, :name, :slug).each do |content_type|
|
||||||
|
next unless content_type.persisted?
|
||||||
|
|
||||||
|
item_on = (content_type.slug == @content_type.slug) rescue nil
|
||||||
|
|
||||||
|
label = truncate(content_type.name, :length => 15)
|
||||||
|
url = contents_url(content_type.slug)
|
||||||
|
css = @content_type && content_type.slug == @content_type.slug ? 'on' : ''
|
||||||
|
|
||||||
|
html = submenu_entry(label, url, :i18n => false, :css => css) do
|
||||||
|
yield(content_type)
|
||||||
|
end
|
||||||
|
|
||||||
|
haml_concat(html)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# MAX_DISPLAYED_CONTENTS = 4
|
# MAX_DISPLAYED_CONTENTS = 4
|
||||||
#
|
#
|
||||||
# def fetch_content_types
|
# def fetch_content_types
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
module Locomotive::CustomFieldsHelper
|
module Locomotive::CustomFieldsHelper
|
||||||
|
|
||||||
def options_for_field_kind
|
def options_for_custom_field_type
|
||||||
%w(string text category boolean date file has_one has_many).map do |kind|
|
# %w(string text category boolean date file has_one has_many).map do |kind|
|
||||||
[t("custom_fields.kind.#{kind}"), kind]
|
%w(string text category boolean date file).map do |type|
|
||||||
|
[t("custom_fields.kind.#{type}"), type]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
module Locomotive
|
module Locomotive
|
||||||
class ContentInstance
|
class ContentInstance
|
||||||
|
|
||||||
include ::Mongoid::Document
|
include Locomotive::Mongoid::Document
|
||||||
include ::Mongoid::Timestamps
|
|
||||||
|
|
||||||
## extensions ##
|
## extensions ##
|
||||||
include ::Mongoid::TargetCustomFields
|
include ::CustomFields::Target
|
||||||
include Extensions::Shared::Seo
|
include Extensions::Shared::Seo
|
||||||
|
|
||||||
## fields (dynamic fields) ##
|
## fields (dynamic fields) ##
|
||||||
|
@ -4,6 +4,7 @@ module Locomotive
|
|||||||
include Locomotive::Mongoid::Document
|
include Locomotive::Mongoid::Document
|
||||||
|
|
||||||
## extensions ##
|
## extensions ##
|
||||||
|
include CustomFields::Source
|
||||||
include Extensions::ContentType::ItemTemplate
|
include Extensions::ContentType::ItemTemplate
|
||||||
|
|
||||||
## fields ##
|
## fields ##
|
||||||
@ -19,7 +20,7 @@ module Locomotive
|
|||||||
|
|
||||||
## associations ##
|
## associations ##
|
||||||
belongs_to :site, :class_name => 'Locomotive::Site'
|
belongs_to :site, :class_name => 'Locomotive::Site'
|
||||||
has_many :contents
|
has_many :contents, :class_name => 'Locomotive::ContentInstance'
|
||||||
# embeds_many :contents, :class_name => 'Locomotive::ContentInstance', :validate => false do
|
# embeds_many :contents, :class_name => 'Locomotive::ContentInstance', :validate => false do
|
||||||
# def visible
|
# def visible
|
||||||
# @target.find_all { |c| c.visible? }
|
# @target.find_all { |c| c.visible? }
|
||||||
@ -35,7 +36,7 @@ module Locomotive
|
|||||||
## callbacks ##
|
## callbacks ##
|
||||||
before_validation :normalize_slug
|
before_validation :normalize_slug
|
||||||
before_save :set_default_values
|
before_save :set_default_values
|
||||||
after_destroy :remove_uploaded_files
|
# after_destroy :remove_uploaded_files
|
||||||
|
|
||||||
## validations ##
|
## validations ##
|
||||||
validates_presence_of :site, :name, :slug
|
validates_presence_of :site, :name, :slug
|
||||||
@ -47,9 +48,9 @@ module Locomotive
|
|||||||
|
|
||||||
## methods ##
|
## methods ##
|
||||||
|
|
||||||
def groupable?
|
# def groupable?
|
||||||
self.group_by_field && group_by_field.category?
|
# self.group_by_field && group_by_field.category?
|
||||||
end
|
# end
|
||||||
|
|
||||||
def order_manually?
|
def order_manually?
|
||||||
self.order_by == '_position_in_list'
|
self.order_by == '_position_in_list'
|
||||||
@ -59,70 +60,70 @@ module Locomotive
|
|||||||
self.order_direction.blank? || self.order_direction == 'asc'
|
self.order_direction.blank? || self.order_direction == 'asc'
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_or_group_contents
|
# def list_or_group_contents
|
||||||
if self.groupable?
|
# if self.groupable?
|
||||||
groups = self.contents.klass.send(:"group_by_#{self.group_by_field._alias}", :ordered_contents)
|
# groups = self.contents.klass.send(:"group_by_#{self.group_by_field._alias}", :ordered_contents)
|
||||||
|
#
|
||||||
|
# # look for items with no category or unknown ones
|
||||||
|
# items_without_category = self.contents.find_all { |c| !self.group_by_field.category_ids.include?(c.send(self.group_by_field_name)) }
|
||||||
|
# if not items_without_category.empty?
|
||||||
|
# groups << { :name => nil, :items => items_without_category }
|
||||||
|
# else
|
||||||
|
# groups
|
||||||
|
# end
|
||||||
|
# else
|
||||||
|
# self.ordered_contents
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
# look for items with no category or unknown ones
|
# def latest_updated_contents
|
||||||
items_without_category = self.contents.find_all { |c| !self.group_by_field.category_ids.include?(c.send(self.group_by_field_name)) }
|
# self.contents.latest_updated.reject { |c| !c.persisted? }
|
||||||
if not items_without_category.empty?
|
# end
|
||||||
groups << { :name => nil, :items => items_without_category }
|
|
||||||
else
|
|
||||||
groups
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self.ordered_contents
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def latest_updated_contents
|
# def ordered_contents(conditions = {})
|
||||||
self.contents.latest_updated.reject { |c| !c.persisted? }
|
# column = self.order_by.to_sym
|
||||||
end
|
#
|
||||||
|
# list = (if conditions.nil? || conditions.empty?
|
||||||
|
# self.contents
|
||||||
|
# else
|
||||||
|
# conditions_with_names = {}
|
||||||
|
#
|
||||||
|
# conditions.each do |key, value|
|
||||||
|
# # convert alias (key) to name
|
||||||
|
# field = self.contents_custom_fields.detect { |f| f._alias == key }
|
||||||
|
#
|
||||||
|
# case field.kind.to_sym
|
||||||
|
# when :category
|
||||||
|
# if (category_item = field.category_items.where(:name => value).first).present?
|
||||||
|
# conditions_with_names[field._name.to_sym] = category_item._id
|
||||||
|
# end
|
||||||
|
# else
|
||||||
|
# conditions_with_names[field._name.to_sym] = value
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# self.contents.where(conditions_with_names)
|
||||||
|
# end).sort { |a, b| (a.send(column) || 0) <=> (b.send(column) || 0) }
|
||||||
|
#
|
||||||
|
# return list if self.order_manually?
|
||||||
|
#
|
||||||
|
# self.asc_order? ? list : list.reverse
|
||||||
|
# end
|
||||||
|
|
||||||
def ordered_contents(conditions = {})
|
# def sort_contents!(ids)
|
||||||
column = self.order_by.to_sym
|
# ids.each_with_index do |id, position|
|
||||||
|
# self.contents.find(BSON::ObjectId(id))._position_in_list = position
|
||||||
|
# end
|
||||||
|
# self.save
|
||||||
|
# end
|
||||||
|
|
||||||
list = (if conditions.nil? || conditions.empty?
|
# def highlighted_field
|
||||||
self.contents
|
# self.contents_custom_fields.detect { |f| f._name == self.highlighted_field_name }
|
||||||
else
|
# end
|
||||||
conditions_with_names = {}
|
#
|
||||||
|
# def group_by_field
|
||||||
conditions.each do |key, value|
|
# @group_by_field ||= self.contents_custom_fields.detect { |f| f._name == self.group_by_field_name }
|
||||||
# convert alias (key) to name
|
# end
|
||||||
field = self.contents_custom_fields.detect { |f| f._alias == key }
|
|
||||||
|
|
||||||
case field.kind.to_sym
|
|
||||||
when :category
|
|
||||||
if (category_item = field.category_items.where(:name => value).first).present?
|
|
||||||
conditions_with_names[field._name.to_sym] = category_item._id
|
|
||||||
end
|
|
||||||
else
|
|
||||||
conditions_with_names[field._name.to_sym] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
self.contents.where(conditions_with_names)
|
|
||||||
end).sort { |a, b| (a.send(column) || 0) <=> (b.send(column) || 0) }
|
|
||||||
|
|
||||||
return list if self.order_manually?
|
|
||||||
|
|
||||||
self.asc_order? ? list : list.reverse
|
|
||||||
end
|
|
||||||
|
|
||||||
def sort_contents!(ids)
|
|
||||||
ids.each_with_index do |id, position|
|
|
||||||
self.contents.find(BSON::ObjectId(id))._position_in_list = position
|
|
||||||
end
|
|
||||||
self.save
|
|
||||||
end
|
|
||||||
|
|
||||||
def highlighted_field
|
|
||||||
self.contents_custom_fields.detect { |f| f._name == self.highlighted_field_name }
|
|
||||||
end
|
|
||||||
|
|
||||||
def group_by_field
|
|
||||||
@group_by_field ||= self.contents_custom_fields.detect { |f| f._name == self.group_by_field_name }
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
@ -1,30 +1,36 @@
|
|||||||
- content_for :head do
|
- content_for :head do
|
||||||
= include_javascripts :content_types, :custom_fields
|
= render 'locomotive/custom_fields/form', :f => f
|
||||||
= include_stylesheets :fancybox
|
|
||||||
|
- content_for :backbone_view_data do
|
||||||
|
:plain
|
||||||
|
{ content_type: #{@content_type.persisted? ? @content_type.to_json : 'null'} }
|
||||||
|
|
||||||
= f.inputs :name => :information do
|
= f.inputs :name => :information do
|
||||||
= f.input :name, :wrapper_html => { :class => 'highlighted' }
|
= f.input :name, :wrapper_html => { :class => 'highlighted' }
|
||||||
= f.input :slug
|
= f.input :slug
|
||||||
= f.input :description
|
= f.input :description
|
||||||
|
|
||||||
= render 'locomotive/custom_fields/index', :form => f, :collection_name => 'contents'
|
= f.inputs :name => :custom_fields, :class => "inputs foldable #{'folded' if inputs_folded?(@content_type)}" do
|
||||||
|
= f.input :contents_custom_fields, :as => :'Locomotive::Empty', :label => false, :wrapper_html => { :id => 'custom_fields_input' }
|
||||||
- unless f.object.new_record?
|
|
||||||
= f.foldable_inputs :name => :presentation, :class => 'switchable' do
|
|
||||||
= f.input :highlighted_field_name, :as => :select, :collection => options_for_highlighted_field(f.object, 'contents'), :include_blank => false
|
|
||||||
= f.input :group_by_field_name, :as => :select, :collection => options_for_group_by_field(f.object, 'contents')
|
|
||||||
= f.custom_input :item_template, :css => 'small-code' do
|
|
||||||
%code{ :class => 'html' }
|
|
||||||
= f.text_area :raw_item_template, :class => 'small'
|
|
||||||
|
|
||||||
= f.foldable_inputs :name => :options, :class => 'switchable' do
|
|
||||||
= f.input :order_by, :as => :select, :collection => options_for_order_by(f.object, 'contents'), :include_blank => false
|
|
||||||
= f.input :order_direction, :as => :select, :collection => options_for_order_direction, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if f.object.order_manually?}" }
|
|
||||||
= f.custom_input :api_enabled, :css => 'toggle' do
|
|
||||||
= f.check_box :api_enabled
|
|
||||||
= hidden_field_tag 'content_type[api_accounts][]', ''
|
|
||||||
= f.input :api_accounts, :as => :select, :collection => current_site.accounts.collect { |a| ["#{a.name} <#{a.email}>", a.id] }, :include_blank => false, :multiple => true, :wrapper_html => { :class => 'multiple', :style => (f.object.api_enabled? ? '' : 'display: none') }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/ = render 'locomotive/custom_fields/index', :form => f, :collection_name => 'contents'
|
||||||
|
/
|
||||||
|
/ - unless f.object.new_record?
|
||||||
|
/ = f.foldable_inputs :name => :presentation, :class => 'switchable' do
|
||||||
|
/ = f.input :highlighted_field_name, :as => :select, :collection => options_for_highlighted_field(f.object, 'contents'), :include_blank => false
|
||||||
|
/ = f.input :group_by_field_name, :as => :select, :collection => options_for_group_by_field(f.object, 'contents')
|
||||||
|
/ = f.custom_input :item_template, :css => 'small-code' do
|
||||||
|
/ %code{ :class => 'html' }
|
||||||
|
/ = f.text_area :raw_item_template, :class => 'small'
|
||||||
|
/
|
||||||
|
/ = f.foldable_inputs :name => :options, :class => 'switchable' do
|
||||||
|
/ = f.input :order_by, :as => :select, :collection => options_for_order_by(f.object, 'contents'), :include_blank => false
|
||||||
|
/ = f.input :order_direction, :as => :select, :collection => options_for_order_direction, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if f.object.order_manually?}" }
|
||||||
|
/ = f.custom_input :api_enabled, :css => 'toggle' do
|
||||||
|
/ = f.check_box :api_enabled
|
||||||
|
/ = hidden_field_tag 'content_type[api_accounts][]', ''
|
||||||
|
/ = f.input :api_accounts, :as => :select, :collection => current_site.accounts.collect { |a| ["#{a.name} <#{a.email}>", a.id] }, :include_blank => false, :multiple => true, :wrapper_html => { :class => 'multiple', :style => (f.object.api_enabled? ? '' : 'display: none') }
|
||||||
|
/
|
||||||
|
/
|
||||||
|
/
|
||||||
|
/
|
||||||
|
@ -14,4 +14,4 @@
|
|||||||
|
|
||||||
= render 'locomotive/shared/form_actions', :back_url => pages_url, :button_label => :create
|
= render 'locomotive/shared/form_actions', :back_url => pages_url, :button_label => :create
|
||||||
|
|
||||||
= render 'locomotive/custom_fields/edit_field', :content_type => @content_type
|
/ = render 'locomotive/custom_fields/edit_field', :content_type => @content_type
|
45
app/views/locomotive/custom_fields/_form.html.haml
Normal file
45
app/views/locomotive/custom_fields/_form.html.haml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
%script{ :type => 'text/html', :id => 'custom_fields_list' }
|
||||||
|
|
||||||
|
%p.empty{ :style => 'display: none' }!= t('.empty')
|
||||||
|
|
||||||
|
%ul
|
||||||
|
|
||||||
|
%hr
|
||||||
|
|
||||||
|
.new-entry
|
||||||
|
|
||||||
|
= text_field_tag 'label', '', :id => '', :placeholder => t('.default_label')
|
||||||
|
|
||||||
|
= select_tag 'type', options_for_select(options_for_custom_field_type)
|
||||||
|
|
||||||
|
%span.actions
|
||||||
|
= link_to t('locomotive.buttons.new_item'), '#', :class => 'add'
|
||||||
|
|
||||||
|
|
||||||
|
%script{ :type => 'text/html', :id => 'custom_field_entry' }
|
||||||
|
|
||||||
|
= f.semantic_fields_for :contents_custom_field, CustomFields::Field.new do |g|
|
||||||
|
|
||||||
|
%span.handle
|
||||||
|
= image_tag 'locomotive/form/icons/drag.png'
|
||||||
|
|
||||||
|
%span.label
|
||||||
|
= g.text_field :label, :class => 'label'
|
||||||
|
|
||||||
|
%span.type
|
||||||
|
= g.select :type, options_for_custom_field_type, {}, { :class => 'type' }
|
||||||
|
|
||||||
|
%span.required
|
||||||
|
= g.check_box :required, :class => 'required'
|
||||||
|
|
||||||
|
= g.label :required, t('.is_required')
|
||||||
|
|
||||||
|
%ol.nested{ :style => 'display: none' }
|
||||||
|
|
||||||
|
= g.input :name, :input_html => { :class => 'name' }
|
||||||
|
|
||||||
|
= g.input :hint, :input_html => { :class => 'hint' }
|
||||||
|
|
||||||
|
%span.actions
|
||||||
|
= link_to 'edit', '#', :class => 'edit'
|
||||||
|
= link_to 'x', '#', :class => 'remove', :confirm => t('locomotive.messages.confirm')
|
@ -18,17 +18,17 @@
|
|||||||
- if can? :manage, content_type
|
- if can? :manage, content_type
|
||||||
%p.edit= link_to t('locomotive.contents.index.edit'), edit_content_type_url(content_type)
|
%p.edit= link_to t('locomotive.contents.index.edit'), edit_content_type_url(content_type)
|
||||||
|
|
||||||
.inner
|
/ .inner
|
||||||
%h2!= t('locomotive.contents.index.lastest_items')
|
/ %h2!= t('locomotive.contents.index.lastest_items')
|
||||||
%ul
|
/ %ul
|
||||||
- content_type.latest_updated_contents.each do |content|
|
/ - content_type.latest_updated_contents.each do |content|
|
||||||
%li
|
/ %li
|
||||||
= link_to truncate(content.send(content_type.highlighted_field_name).to_s, :length => 20), edit_admin_content_path(content_type.slug, content)
|
/ = link_to truncate(content.send(content_type.highlighted_field_name).to_s, :length => 20), edit_admin_content_path(content_type.slug, content)
|
||||||
%span= time_ago_in_words(content.updated_at)
|
/ %span= time_ago_in_words(content.updated_at)
|
||||||
|
|
||||||
- other_content_types do |content_types|
|
/ - other_content_types do |content_types|
|
||||||
.inner
|
/ .inner
|
||||||
%ul.big-links
|
/ %ul.big-links
|
||||||
- content_types.each do |content_type|
|
/ - content_types.each do |content_type|
|
||||||
%li
|
/ %li
|
||||||
= link_to truncate(content_type.name, :length => 20), contents_url(content_type.slug)
|
/ = link_to truncate(content_type.name, :length => 20), contents_url(content_type.slug)
|
@ -74,7 +74,7 @@ en:
|
|||||||
delete_file: Delete file
|
delete_file: Delete file
|
||||||
has_many:
|
has_many:
|
||||||
empty: Empty
|
empty: Empty
|
||||||
index:
|
form:
|
||||||
is_required: is required
|
is_required: is required
|
||||||
default_label: Field name
|
default_label: Field name
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ fr:
|
|||||||
delete_file: Supprimer fichier
|
delete_file: Supprimer fichier
|
||||||
has_many:
|
has_many:
|
||||||
empty: Vide
|
empty: Vide
|
||||||
index:
|
form:
|
||||||
is_required: est obligatoire
|
is_required: est obligatoire
|
||||||
default_label: Nom du champ
|
default_label: Nom du champ
|
||||||
|
|
||||||
|
15
doc/TODO
15
doc/TODO
@ -33,11 +33,18 @@ x edit my site
|
|||||||
x export
|
x export
|
||||||
x site picker
|
x site picker
|
||||||
- content types
|
- content types
|
||||||
- change in main menu
|
x move content instances into their own collection
|
||||||
- manage custom_fields
|
- manage custom_fields
|
||||||
- list
|
x automatic name
|
||||||
- crud
|
x required
|
||||||
- move content instances into their own collection
|
x editable plugin: add class depending on the type => surrounding span instead
|
||||||
|
x position
|
||||||
|
x open the nested form
|
||||||
|
x remove an entry
|
||||||
|
- look n feel
|
||||||
|
- show / hide options of a field based on its type
|
||||||
|
- display errors
|
||||||
|
- change in main menu
|
||||||
- manage contents
|
- manage contents
|
||||||
- list
|
- list
|
||||||
- crud
|
- crud
|
||||||
|
@ -20,15 +20,15 @@ module CustomFields
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module Category
|
# module Category
|
||||||
class Item
|
# class Item
|
||||||
|
#
|
||||||
def to_liquid
|
# def to_liquid
|
||||||
{ 'id' => self._id.to_s, 'name' => self.name }
|
# { 'id' => self._id.to_s, 'name' => self.name }
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ module Locomotive
|
|||||||
included do
|
included do
|
||||||
include ::Mongoid::Document
|
include ::Mongoid::Document
|
||||||
include ::Mongoid::Timestamps
|
include ::Mongoid::Timestamps
|
||||||
include ::Mongoid::CustomFields
|
# include ::Mongoid::CustomFields
|
||||||
end
|
end
|
||||||
|
|
||||||
def as_json(options={})
|
def as_json(options={})
|
||||||
|
Loading…
Reference in New Issue
Block a user