content_instance becomes now content_entry with its shortcut content_type.entries + change references to the old custom_fields API
This commit is contained in:
parent
9130544516
commit
e9ef4d48c3
18
Gemfile.lock
18
Gemfile.lock
@ -7,16 +7,6 @@ GIT
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/locomotivecms/custom_fields.git
|
||||
revision: 1a8f26a379193c5a60f926eacadc0a9eee7ab5de
|
||||
branch: experimental
|
||||
specs:
|
||||
custom_fields (2.0.0.rc1)
|
||||
activesupport (~> 3.1.3)
|
||||
carrierwave-mongoid (~> 0.1.3)
|
||||
mongoid (~> 2.3.4)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/plataformatec/devise.git
|
||||
revision: ede004169c6af7416f8c4e3fc29a653bee133f60
|
||||
@ -38,6 +28,14 @@ GIT
|
||||
specs:
|
||||
locomotive_mongoid_acts_as_tree (0.1.5.7)
|
||||
|
||||
PATH
|
||||
remote: ../gems/custom_fields
|
||||
specs:
|
||||
custom_fields (2.0.0.rc1)
|
||||
activesupport (~> 3.1.3)
|
||||
carrierwave-mongoid (~> 0.1.3)
|
||||
mongoid (~> 2.3.4)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
|
2
Rakefile
2
Rakefile
@ -50,7 +50,7 @@ task :spec_nix do
|
||||
lib/locomotive/heroku_spec.rb
|
||||
lib/locomotive/import_spec.rb
|
||||
lib/locomotive/export_spec.rb
|
||||
models/content_instance_spec.rb
|
||||
models/content_entry_spec.rb
|
||||
models/editable_element_spec.rb
|
||||
models/account_spec.rb
|
||||
models/content_type_spec.rb
|
||||
|
@ -1,11 +0,0 @@
|
||||
class Locomotive.Models.Content extends Backbone.Model
|
||||
|
||||
paramRoot: 'content'
|
||||
|
||||
urlRoot: "#{Locomotive.mount_on}/content_type/:slug/contents"
|
||||
|
||||
class Locomotive.Models.ContentsCollection extends Backbone.Collection
|
||||
|
||||
model: Locomotive.Models.Content
|
||||
|
||||
url: "#{Locomotive.mount_on}/content_type/:slug/contents"
|
@ -0,0 +1,11 @@
|
||||
class Locomotive.Models.ContentEntry extends Backbone.Model
|
||||
|
||||
paramRoot: 'content_entry'
|
||||
|
||||
urlRoot: "#{Locomotive.mount_on}/content_type/:slug/entries"
|
||||
|
||||
class Locomotive.Models.ContentEntriesCollection extends Backbone.Collection
|
||||
|
||||
model: Locomotive.Models.Content
|
||||
|
||||
url: "#{Locomotive.mount_on}/content_type/:slug/entries"
|
@ -9,12 +9,12 @@ class Locomotive.Models.ContentType extends Backbone.Model
|
||||
|
||||
_normalize: ->
|
||||
@set
|
||||
contents_custom_fields: new Locomotive.Models.CustomFieldsCollection(@get('contents_custom_fields'))
|
||||
entries_custom_fields: new Locomotive.Models.CustomFieldsCollection(@get('entries_custom_fields'))
|
||||
|
||||
toJSON: ->
|
||||
_.tap super, (hash) =>
|
||||
delete hash.contents_custom_fields
|
||||
hash.contents_custom_fields_attributes = @get('contents_custom_fields').toJSONForSave() if @get('contents_custom_fields')
|
||||
delete hash.entries_custom_fields
|
||||
hash.entries_custom_fields_attributes = @get('entries_custom_fields').toJSONForSave() if @get('entries_custom_fields')
|
||||
|
||||
class Locomotive.Models.ContentTypesCollection extends Backbone.Collection
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
#= require ../shared/form_view
|
||||
|
||||
Locomotive.Views.ContentEntries ||= {}
|
||||
|
||||
class Locomotive.Views.ContentEntries.FormView extends Locomotive.Views.Shared.FormView
|
||||
|
||||
el: '#content'
|
||||
|
||||
events:
|
||||
'submit': 'save'
|
||||
|
||||
initialize: ->
|
||||
@model = new Locomotive.Models.ContentEntry(@options.content_entry)
|
||||
|
||||
Backbone.ModelBinding.bind @
|
||||
|
||||
render: ->
|
||||
super()
|
||||
|
||||
return @
|
||||
|
@ -0,0 +1,6 @@
|
||||
Locomotive.Views.ContentEntries ||= {}
|
||||
|
||||
class Locomotive.Views.ContentEntries.EditView extends Locomotive.Views.ContentEntries.FormView
|
||||
|
||||
save: (event) ->
|
||||
@save_in_ajax event
|
@ -1,6 +1,6 @@
|
||||
Locomotive.Views.Contents ||= {}
|
||||
|
||||
class Locomotive.Views.Contents.NewView extends Locomotive.Views.Contents.FormView
|
||||
class Locomotive.Views.ContentEntries.NewView extends Locomotive.Views.ContentEntries.FormView
|
||||
|
||||
save: (event) ->
|
||||
@save_in_ajax event,
|
@ -62,7 +62,7 @@ class Locomotive.Views.ContentTypes.FormView extends Locomotive.Views.Shared.For
|
||||
target.show()
|
||||
|
||||
show_error: (attribute, message, html) ->
|
||||
if attribute == 'contents_custom_fields'
|
||||
if attribute == 'entries_custom_fields'
|
||||
return if _.isEmpty(message)
|
||||
for _message, index in message
|
||||
@custom_fields_view._entry_views[index].show_error(_message[0])
|
||||
|
@ -44,7 +44,7 @@ class Locomotive.Views.ContentTypes.CustomFieldsView extends Backbone.View
|
||||
if labelInput.val() != ''
|
||||
custom_field = new Locomotive.Models.CustomField label: labelInput.val(), type: typeInput.val()
|
||||
|
||||
@model.get('contents_custom_fields').add(custom_field)
|
||||
@model.get('entries_custom_fields').add(custom_field)
|
||||
|
||||
@_insert_entry(custom_field)
|
||||
|
||||
@ -60,17 +60,17 @@ class Locomotive.Views.ContentTypes.CustomFieldsView extends Backbone.View
|
||||
|
||||
remove_entry: (custom_field, view) ->
|
||||
@_entry_views = _.reject @_entry_views, (_view) -> _view == view
|
||||
@model.get('contents_custom_fields').remove(custom_field)
|
||||
@model.get('entries_custom_fields').remove(custom_field)
|
||||
|
||||
@refresh_position_entries()
|
||||
|
||||
@$('> .empty').show() if @model.get('contents_custom_fields').length == 0
|
||||
@$('> .empty').show() if @model.get('entries_custom_fields').length == 0
|
||||
|
||||
render_entries: ->
|
||||
if @model.get('contents_custom_fields').length == 0
|
||||
if @model.get('entries_custom_fields').length == 0
|
||||
@$('> .empty').show()
|
||||
else
|
||||
@model.get('contents_custom_fields').each (custom_field) =>
|
||||
@model.get('entries_custom_fields').each (custom_field) =>
|
||||
@_insert_entry(custom_field)
|
||||
|
||||
_insert_entry: (custom_field) ->
|
||||
|
@ -1,21 +0,0 @@
|
||||
#= require ../shared/form_view
|
||||
|
||||
Locomotive.Views.Contents ||= {}
|
||||
|
||||
class Locomotive.Views.Contents.FormView extends Locomotive.Views.Shared.FormView
|
||||
|
||||
el: '#content'
|
||||
|
||||
events:
|
||||
'submit': 'save'
|
||||
|
||||
initialize: ->
|
||||
@model = new Locomotive.Models.Content(@options.content)
|
||||
|
||||
Backbone.ModelBinding.bind @
|
||||
|
||||
render: ->
|
||||
super()
|
||||
|
||||
return @
|
||||
|
@ -1,6 +0,0 @@
|
||||
Locomotive.Views.Contents ||= {}
|
||||
|
||||
class Locomotive.Views.Contents.EditView extends Locomotive.Views.Contents.FormView
|
||||
|
||||
save: (event) ->
|
||||
@save_in_ajax event
|
@ -1,6 +1,8 @@
|
||||
module Locomotive
|
||||
class ApiContentsController < ActionController::Base
|
||||
|
||||
# FIXME: NEED REFACTORING
|
||||
|
||||
include Locomotive::Routing::SiteDispatcher
|
||||
|
||||
before_filter :require_site
|
||||
@ -12,17 +14,17 @@ module Locomotive
|
||||
before_filter :sanitize_content_params, :only => :create
|
||||
|
||||
def create
|
||||
@content = @content_type.contents.build(params[:content])
|
||||
@entry = @content_type.entries.build(params[:entry])
|
||||
|
||||
respond_to do |format|
|
||||
if @content.save
|
||||
format.json { render :json => { :content => @content } }
|
||||
if @entry.save
|
||||
format.json { render :json => { :entry => @entry } }
|
||||
format.html do
|
||||
flash[@content_type.slug.singularize] = @content.aliased_attributes
|
||||
flash[@content_type.slug.singularize] = @entry.aliased_attributes
|
||||
redirect_to params[:success_callback]
|
||||
end
|
||||
else
|
||||
format.json { render :json => { :content => @content, :errors => @content.errors } }
|
||||
format.json { render :json => { :entry => @content, :errors => @content.errors } }
|
||||
format.html do
|
||||
flash[@content_type.slug.singularize] = @content.aliased_attributes
|
||||
flash['errors'] = @content.errors_to_hash
|
||||
|
@ -12,29 +12,29 @@ module Locomotive
|
||||
before_filter :authorize_content
|
||||
|
||||
def index
|
||||
@contents = @content_type.contents
|
||||
respond_with @contents
|
||||
@content_entries = @content_type.entries
|
||||
respond_with @content_entries
|
||||
end
|
||||
|
||||
def new
|
||||
@content = @content_type.contents.build
|
||||
@content_entry = @content_type.entries.build
|
||||
respond_with @content
|
||||
end
|
||||
|
||||
def create
|
||||
@content = @content_type.contents.create(params[:content])
|
||||
respond_with @content, :location => edit_content_url(@content_type.slug, @content._id)
|
||||
@content_entry = @content_type.entries.create(params[:content_entry])
|
||||
respond_with @content, :location => edit_content_entry_url(@content_type.slug, @content_entry._id)
|
||||
end
|
||||
|
||||
def edit
|
||||
@content = @content_type.contents.find(params[:id])
|
||||
@content_entry = @content_type.entries.find(params[:id])
|
||||
respond_with @content
|
||||
end
|
||||
|
||||
def update
|
||||
@content = @content_type.contents.find(params[:id])
|
||||
@content.update_attributes(params[:content])
|
||||
respond_with @content, :location => edit_content_url(@content_type.slug, @content._id)
|
||||
@content_entry = @content_type.entries.find(params[:id])
|
||||
@content_entry.update_attributes(params[:content_entry])
|
||||
respond_with @content, :location => edit_content_entry_url(@content_type.slug, @content_entry._id)
|
||||
end
|
||||
|
||||
def sort
|
||||
@ -46,8 +46,8 @@ module Locomotive
|
||||
end
|
||||
|
||||
def destroy
|
||||
@content = @content_type.contents.find(params[:id])
|
||||
@content.destroy
|
||||
@content_entry = @content_type.entries.find(params[:id])
|
||||
@content_entry.destroy
|
||||
respond_with @content, :location => pages_url
|
||||
end
|
||||
|
||||
@ -58,7 +58,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
def authorize_content
|
||||
authorize! params[:action].to_sym, ContentInstance
|
||||
authorize! params[:action].to_sym, ContentEntry
|
||||
end
|
||||
|
||||
end
|
@ -14,7 +14,6 @@ module Locomotive
|
||||
|
||||
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
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
module Locomotive
|
||||
class CustomFieldsController < BaseController
|
||||
|
||||
layout false
|
||||
|
||||
before_filter :set_parent_and_fields
|
||||
|
||||
skip_load_and_authorize_resource
|
||||
|
||||
def edit
|
||||
@field = @fields.find(params[:id])
|
||||
render :action => "edit_#{@field.kind.downcase}"
|
||||
end
|
||||
|
||||
def update
|
||||
@field = @fields.find(params[:id])
|
||||
|
||||
if @field.update_attributes(params[:custom_field])
|
||||
render :json => @field.to_json
|
||||
else
|
||||
render :json => { :error => t('flash.locomotive.custom_fields.update.alert') }
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def set_parent_and_fields
|
||||
@parent = current_site.content_types.where(:slug => params[:slug]).first
|
||||
@fields = @parent.contents_custom_fields
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -7,7 +7,7 @@ module Locomotive::ContentTypesHelper
|
||||
item_on = (content_type.slug == @content_type.slug) rescue nil
|
||||
|
||||
label = truncate(content_type.name, :length => 15)
|
||||
url = contents_url(content_type.slug)
|
||||
url = content_entries_url(content_type.slug)
|
||||
css = @content_type && content_type.slug == @content_type.slug ? 'on' : ''
|
||||
|
||||
html = submenu_entry(label, url, :i18n => false, :css => css) do
|
||||
|
@ -2,12 +2,12 @@ module Locomotive::CustomFieldsHelper
|
||||
|
||||
def options_for_custom_field_type
|
||||
%w(string text select boolean date file).map do |type|
|
||||
[t("custom_fields.kind.#{type}"), type]
|
||||
[t("custom_fields.types.#{type}"), type]
|
||||
end
|
||||
end
|
||||
|
||||
def options_for_highlighted_field(content_type)
|
||||
content_type.ordered_contents_custom_fields.find_all do |field|
|
||||
content_type.ordered_entries_custom_fields.find_all do |field|
|
||||
%w(string date select).include?(field.type)
|
||||
end.map do |field|
|
||||
[field.label, field._id]
|
||||
@ -15,7 +15,7 @@ module Locomotive::CustomFieldsHelper
|
||||
end
|
||||
|
||||
def options_for_group_by_field(content_type)
|
||||
content_type.ordered_contents_custom_fields.find_all do |field|
|
||||
content_type.ordered_entries_custom_fields.find_all do |field|
|
||||
%w(select).include?(field.type)
|
||||
end.map do |field|
|
||||
[field.label, field._id]
|
||||
@ -49,8 +49,8 @@ module Locomotive::CustomFieldsHelper
|
||||
# klass_name = my_content_type.content_klass.to_s
|
||||
#
|
||||
# [].tap do |options|
|
||||
# ContentType.where(:'contents_custom_fields.kind' => 'has_one', :'contents_custom_fields.target' => klass_name).each do |content_type|
|
||||
# content_type.contents_custom_fields.find_all { |f| f.has_one? && f.target == klass_name }.each do |field|
|
||||
# ContentType.where(:'entries_custom_fields.kind' => 'has_one', :'entries_custom_fields.target' => klass_name).each do |content_type|
|
||||
# content_type.entries_custom_fields.find_all { |f| f.has_one? && f.target == klass_name }.each do |field|
|
||||
# options << {
|
||||
# :klass => content_type.content_klass.to_s,
|
||||
# :label => field.label,
|
||||
|
@ -3,10 +3,10 @@ module Locomotive
|
||||
|
||||
default :from => Locomotive.config.mailer_sender
|
||||
|
||||
def new_content_instance(account, content)
|
||||
@account, @content = account, content
|
||||
def new_content_entry(account, entry)
|
||||
@account, @entry = account, entry
|
||||
|
||||
subject = t('locomotive.notifications.new_content_instance.subject', :type => content.content_type.name, :locale => account.locale)
|
||||
subject = t('locomotive.notifications.new_content_entry.subject', :type => entry.content_type.name, :locale => account.locale)
|
||||
|
||||
mail :subject => subject, :to => account.email
|
||||
end
|
||||
|
@ -32,7 +32,7 @@ module Locomotive
|
||||
can :touch, [Page, ThemeAsset]
|
||||
can :sort, Page
|
||||
|
||||
can :manage, [ContentInstance, ContentAsset]
|
||||
can :manage, [ContentEntry, ContentAsset]
|
||||
|
||||
can :touch, Site do |site|
|
||||
site == @site
|
||||
@ -42,7 +42,7 @@ module Locomotive
|
||||
def setup_designer_permissions!
|
||||
can :manage, Page
|
||||
|
||||
can :manage, ContentInstance
|
||||
can :manage, ContentEntry
|
||||
|
||||
can :manage, ContentType
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
module Locomotive
|
||||
class ContentInstance
|
||||
class ContentEntry
|
||||
|
||||
include Locomotive::Mongoid::Document
|
||||
|
||||
@ -72,7 +72,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
def to_presenter
|
||||
Locomotive::ContentPresenter.new(self)
|
||||
Locomotive::ContentEntryPresenter.new(self)
|
||||
end
|
||||
|
||||
def as_json(options = {})
|
@ -20,7 +20,7 @@ module Locomotive
|
||||
|
||||
## associations ##
|
||||
belongs_to :site, :class_name => 'Locomotive::Site'
|
||||
has_many :contents, :class_name => 'Locomotive::ContentInstance', :dependent => :destroy
|
||||
has_many :entries, :class_name => 'Locomotive::ContentEntry', :dependent => :destroy
|
||||
|
||||
## named scopes ##
|
||||
scope :ordered, :order_by => :updated_at.desc
|
||||
@ -37,10 +37,10 @@ module Locomotive
|
||||
## validations ##
|
||||
validates_presence_of :site, :name, :slug
|
||||
validates_uniqueness_of :slug, :scope => :site_id
|
||||
validates_size_of :contents_custom_fields, :minimum => 1, :message => :array_too_short
|
||||
validates_size_of :entries_custom_fields, :minimum => 1, :message => :array_too_short
|
||||
|
||||
## behaviours ##
|
||||
custom_fields_for :contents
|
||||
custom_fields_for :entries
|
||||
|
||||
## methods ##
|
||||
|
||||
@ -49,11 +49,11 @@ module Locomotive
|
||||
# end
|
||||
|
||||
def highlighted_field
|
||||
self.contents_custom_fields.find(self.highlighted_field_id)
|
||||
self.entries_custom_fields.find(self.highlighted_field_id)
|
||||
end
|
||||
|
||||
def group_by_field
|
||||
self.contents_custom_fields.find(self.group_by_field_id)
|
||||
self.entries_custom_fields.find(self.group_by_field_id)
|
||||
end
|
||||
|
||||
def order_manually?
|
||||
@ -102,7 +102,7 @@ module Locomotive
|
||||
#
|
||||
# conditions.each do |key, value|
|
||||
# # convert alias (key) to name
|
||||
# field = self.contents_custom_fields.detect { |f| f._alias == key }
|
||||
# field = self.entries_custom_fields.detect { |f| f._alias == key }
|
||||
#
|
||||
# case field.kind.to_sym
|
||||
# when :category
|
||||
@ -130,18 +130,18 @@ module Locomotive
|
||||
# end
|
||||
#
|
||||
# def highlighted_field
|
||||
# self.contents_custom_fields.detect { |f| f._name == self.highlighted_field_name }
|
||||
# self.entries_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 }
|
||||
# @group_by_field ||= self.entries_custom_fields.detect { |f| f._name == self.group_by_field_name }
|
||||
# end
|
||||
|
||||
protected
|
||||
|
||||
def set_default_values
|
||||
self.order_by ||= 'created_at'
|
||||
self.highlighted_field_id ||= self.contents_custom_fields.first._id
|
||||
self.highlighted_field_id ||= self.entries_custom_fields.first._id
|
||||
end
|
||||
|
||||
def normalize_slug
|
||||
@ -150,13 +150,13 @@ module Locomotive
|
||||
end
|
||||
|
||||
def bubble_fields_errors_up
|
||||
return if self.errors[:contents_custom_fields].empty?
|
||||
return if self.errors[:entries_custom_fields].empty?
|
||||
|
||||
self.errors.set(:contents_custom_fields, [])
|
||||
self.errors.set(:entries_custom_fields, [])
|
||||
|
||||
self.contents_custom_fields.each do |field|
|
||||
self.entries_custom_fields.each do |field|
|
||||
next if field.valid?
|
||||
self.errors.add(:contents_custom_fields, field.errors.to_a)
|
||||
self.errors.add(:entries_custom_fields, field.errors.to_a)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
module Locomotive
|
||||
class ContentPresenter < BasePresenter
|
||||
class ContentEntryPresenter < BasePresenter
|
||||
|
||||
# delegate :name, :description, :slug, :order_by, :order_direction, :highlighted_field_name, :group_by_field_name, :api_accounts, :to => :source
|
||||
|
@ -3,12 +3,12 @@ module Locomotive
|
||||
|
||||
delegate :name, :description, :slug, :order_by, :order_direction, :highlighted_field_name, :group_by_field_name, :api_accounts, :to => :source
|
||||
|
||||
def contents_custom_fields
|
||||
self.source.ordered_contents_custom_fields.collect(&:as_json)
|
||||
def entries_custom_fields
|
||||
self.source.ordered_entries_custom_fields.collect(&:as_json)
|
||||
end
|
||||
|
||||
def included_methods
|
||||
super + %w(name description slug order_by order_direction highlighted_field_name group_by_field_name api_accounts contents_custom_fields)
|
||||
super + %w(name description slug order_by order_direction highlighted_field_name group_by_field_name api_accounts entries_custom_fields)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
= f.inputs :name => :custom_fields, :class => "inputs foldable" do
|
||||
|
||||
= f.input :contents_custom_fields, :as => :'Locomotive::Empty', :label => false, :wrapper_html => { :id => 'custom_fields_input' }
|
||||
= f.input :entries_custom_fields, :as => :'Locomotive::Empty', :label => false, :wrapper_html => { :id => 'custom_fields_input' }
|
||||
|
||||
- if @content_type.persisted?
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
= render 'locomotive/shared/actions/contents'
|
||||
|
||||
- content_for :buttons do
|
||||
= local_action_button :show_items, contents_url(@content_type.slug_was), :class => 'show'
|
||||
= local_action_button :new_item, new_content_url(@content_type.slug_was), :class => 'new'
|
||||
= local_action_button :show_items, content_entries_url(@content_type.slug_was), :class => 'show'
|
||||
= local_action_button :new_item, new_content_entry_url(@content_type.slug_was), :class => 'new'
|
||||
|
||||
%p!= t('.help')
|
||||
|
||||
@ -16,4 +16,4 @@
|
||||
|
||||
= render 'form', :f => f
|
||||
|
||||
= render 'locomotive/shared/form_actions', :back_url => contents_url(@content_type.slug_was), :button_label => :update
|
||||
= render 'locomotive/shared/form_actions', :back_url => content_entries_url(@content_type.slug_was), :button_label => :update
|
||||
|
@ -1,21 +0,0 @@
|
||||
- title t('.title', :type => @content_type.name.capitalize)
|
||||
|
||||
- content_for :submenu do
|
||||
= render 'locomotive/shared/menu/contents'
|
||||
|
||||
- content_for :actions do
|
||||
= render 'locomotive/shared/actions/contents'
|
||||
|
||||
- content_for :buttons do
|
||||
- if can?(:manage, Locomotive::ContentType)
|
||||
= local_action_button t('locomotive.contents.index.edit'), edit_content_type_url(@content_type), :class => 'edit'
|
||||
|
||||
= local_action_button t('locomotive.contents.index.new'), new_content_url(@content_type.slug), :class => 'new'
|
||||
|
||||
%p= @content_type.description
|
||||
|
||||
= semantic_form_for @content, :as => :content, :url => content_url(@content_type.slug, @content), :html => { :multipart => true } do |form|
|
||||
|
||||
= render 'form', :f => form
|
||||
|
||||
= render 'locomotive/shared/form_actions', :back_url => contents_url(@content_type.slug), :button_label => :update
|
@ -1,5 +1,5 @@
|
||||
- if contents.empty?
|
||||
%p.no-items!= t('.no_items', :url => new_content_url(@content_type.slug))
|
||||
%p.no-items!= t('.no_items', :url => new_content_entry_url(@content_type.slug))
|
||||
- else
|
||||
%ul{ :id => 'contents-list', :class => "list #{'sortable' if @content_type.order_by == '_position_in_list'}", :'data-url' => sort_admin_contents_path(@content_type.slug, :json) }
|
||||
- contents.each do |content|
|
21
app/views/locomotive/contents_entries/edit.html.haml
Normal file
21
app/views/locomotive/contents_entries/edit.html.haml
Normal file
@ -0,0 +1,21 @@
|
||||
- title t('.title', :type => @content_type.name.capitalize)
|
||||
|
||||
- content_for :submenu do
|
||||
= render 'locomotive/shared/menu/contents'
|
||||
|
||||
- content_for :actions do
|
||||
= render 'locomotive/shared/actions/contents'
|
||||
|
||||
- content_for :buttons do
|
||||
- if can?(:manage, Locomotive::ContentType)
|
||||
= local_action_button t('locomotive.content_entries.index.edit'), edit_content_type_url(@content_type), :class => 'edit'
|
||||
|
||||
= local_action_button t('locomotive.content_entries.index.new'), new_content_entry_url(@content_type.slug), :class => 'new'
|
||||
|
||||
%p= @content_type.description
|
||||
|
||||
= semantic_form_for @content, :as => :content, :url => content_entry_url(@content_type.slug, @content), :html => { :multipart => true } do |form|
|
||||
|
||||
= render 'form', :f => form
|
||||
|
||||
= render 'locomotive/shared/form_actions', :back_url => content_entries_url(@content_type.slug), :button_label => :update
|
@ -13,7 +13,7 @@
|
||||
- if can?(:manage, Locomotive::ContentType)
|
||||
= local_action_button :edit, edit_content_type_url(@content_type), :class => 'edit'
|
||||
|
||||
= local_action_button :new, new_content_url(@content_type.slug), :class => 'new'
|
||||
= local_action_button :new, new_content_entry_url(@content_type.slug), :class => 'new'
|
||||
|
||||
- if @content_type.description.present?
|
||||
%p= @content_type.description
|
@ -8,12 +8,12 @@
|
||||
|
||||
- if can?(:manage, Locomotive::ContentType)
|
||||
- content_for :buttons do
|
||||
= local_action_button t('locomotive.contents.index.edit'), edit_content_type_url(@content_type), :class => 'edit'
|
||||
= local_action_button t('locomotive.content_entries.index.edit'), edit_content_type_url(@content_type), :class => 'edit'
|
||||
|
||||
%p= @content_type.description
|
||||
|
||||
= semantic_form_for @content, :as => :content, :url => contents_url(@content_type.slug), :html => { :multipart => true } do |form|
|
||||
= semantic_form_for @content, :as => :content, :url => content_entries_url(@content_type.slug), :html => { :multipart => true } do |form|
|
||||
|
||||
= render 'form', :f => form
|
||||
|
||||
= render 'locomotive/shared/form_actions', :back_url => contents_url(@content_type.slug), :button_label => :create
|
||||
= render 'locomotive/shared/form_actions', :back_url => content_entries_url(@content_type.slug), :button_label => :create
|
@ -0,0 +1,21 @@
|
||||
%p= t('.title', :name => @account.name, :date => I18n.l(Time.now), :locale => @account.locale)
|
||||
|
||||
%hr
|
||||
|
||||
%p
|
||||
%b= t('.type', :type => @content_entry.content_type.name, :locale => @account.locale)
|
||||
%br
|
||||
%i= @content_entry.content_type.description
|
||||
|
||||
%hr
|
||||
|
||||
%ul
|
||||
- @content_entry.custom_fields.each do |field|
|
||||
%li
|
||||
%strong= field.label
|
||||
-
|
||||
%i
|
||||
- if field.file?
|
||||
= link_to File.basename(@content_entry.send(field.name).url), @content_entry.send(field.name).url
|
||||
- else
|
||||
= @content_entry.send(field.name)
|
@ -1,21 +0,0 @@
|
||||
%p= t('.title', :name => @account.name, :date => I18n.l(Time.now), :locale => @account.locale)
|
||||
|
||||
%hr
|
||||
|
||||
%p
|
||||
%b= t('.type', :type => @content.content_type.name, :locale => @account.locale)
|
||||
%br
|
||||
%i= @content.content_type.description
|
||||
|
||||
%hr
|
||||
|
||||
%ul
|
||||
- @content.custom_fields.each do |field|
|
||||
%li
|
||||
%strong= field.label
|
||||
-
|
||||
%i
|
||||
- if field.file?
|
||||
= link_to File.basename(@content.send(field._name).url), @content.send(field._name).url
|
||||
- else
|
||||
= @content.send(field._alias)
|
@ -14,13 +14,13 @@
|
||||
- each_content_type_menu_item do |content_type|
|
||||
.wrapper
|
||||
.header
|
||||
%p= link_to t('locomotive.contents.index.new'), new_content_url(content_type.slug)
|
||||
%p= link_to t('locomotive.content_entries.index.new'), new_content_entry_url(content_type.slug)
|
||||
|
||||
- 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.content_entries.index.edit'), edit_content_type_url(content_type)
|
||||
|
||||
.inner
|
||||
%h2!= t('locomotive.contents.index.lastest_items')
|
||||
%h2!= t('locomotive.content_entries.index.lastest_items')
|
||||
/ %ul
|
||||
/ - content_type.latest_updated_contents.each do |content|
|
||||
/ %li
|
||||
|
@ -10,7 +10,7 @@ xml.urlset "xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9" do
|
||||
if not page.index_or_not_found?
|
||||
if page.templatized?
|
||||
|
||||
page.content_type.contents.visible.each do |c|
|
||||
page.content_type.entries.visible.each do |c|
|
||||
xml.url do
|
||||
xml.loc page_url(page, { :content => c, :host => true })
|
||||
xml.lastmod c.updated_at.to_date.to_s('%Y-%m-%d')
|
||||
|
@ -44,7 +44,7 @@ de:
|
||||
link: "→ Zurück zur Anwendung"
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: "[%{type}] neu"
|
||||
title: "Hi %{firstname}, nur damit du Bescheid weißt! Am %{date} wurde folgende neue Instanz erstellt."
|
||||
type: "Model: %{type}"
|
||||
@ -55,15 +55,7 @@ de:
|
||||
text_formatting:
|
||||
none: Keine
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Feld bearbeiten
|
||||
edit_category:
|
||||
title: Optionen
|
||||
help: Organisiere alle Optionen für die Auswahlbox.
|
||||
collection_label: Liste der Optionen
|
||||
types:
|
||||
category:
|
||||
edit_categories: Optionen
|
||||
file:
|
||||
delete_file: Datei löschen
|
||||
index:
|
||||
@ -239,7 +231,7 @@ de:
|
||||
asc: Aufsteigend
|
||||
desc: Absteigend
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: '"%{type}" anzeigen'
|
||||
edit: Baustein bearbeiten
|
||||
@ -247,18 +239,14 @@ de:
|
||||
download: Elemente herunterladen
|
||||
new: neues Element
|
||||
category_noname: "Kein Name"
|
||||
lastest_items: "Neueste Elemente"
|
||||
lastest_entries: "Neueste Elemente"
|
||||
updated_at: "Aktualisiert am"
|
||||
list:
|
||||
no_items: "Momentan gibt es keine Elemente. Klicke einfach <a href='%{url}'>hier</a>, um das erste Element zu erstellen."
|
||||
no_entries: "Momentan gibt es keine Elemente. Klicke einfach <a href='%{url}'>hier</a>, um das erste Element zu erstellen."
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — neues Element'
|
||||
breadcrumb: '%{root} » %{type} — Element bearbeiten'
|
||||
title: '%{type} — neues Element'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — editing item'
|
||||
breadcrumb: '%{root} » %{type} — Element bearbeiten'
|
||||
title: '%{type} — editing item'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Neues Element
|
||||
|
@ -47,7 +47,7 @@ en:
|
||||
link: "→ Back to the application"
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: "[%{type}] new"
|
||||
title: "Hi %{name}, just to let you know that a new instance has been created on %{date}"
|
||||
type: "Model: %{type}"
|
||||
@ -61,15 +61,7 @@ en:
|
||||
text_formatting:
|
||||
none: None
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Edit field
|
||||
edit_category:
|
||||
title: Edit options
|
||||
help: Manage the list of options for your select box.
|
||||
collection_label: List of options
|
||||
types:
|
||||
category:
|
||||
edit_categories: Edit options
|
||||
file:
|
||||
delete_file: Delete file
|
||||
has_many:
|
||||
@ -243,7 +235,7 @@ en:
|
||||
asc: Ascending
|
||||
desc: Descending
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: 'Listing "%{type}"'
|
||||
edit: edit model
|
||||
|
@ -46,7 +46,7 @@ es:
|
||||
send: Enviar
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: "[%{type}] nuevo"
|
||||
title: "Hola %{name}, queremos hacerte saber que una nueva instancia se creó el día %{date}"
|
||||
type: "Modelo: %{type}"
|
||||
@ -57,15 +57,7 @@ es:
|
||||
text_formatting:
|
||||
none: Ninguno
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Editar campo
|
||||
edit_category:
|
||||
title: Editar opciones
|
||||
help: Gestionar la lista de opciones que aparecerán en la lista desplegable.
|
||||
collection_label: Lista de opciones
|
||||
types:
|
||||
category:
|
||||
edit_categories: Editar opciones
|
||||
file:
|
||||
delete_file: Borrar fichero
|
||||
has_many:
|
||||
@ -236,7 +228,7 @@ es:
|
||||
asc: Ascendente
|
||||
desc: Descendente
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: 'Mostrando "%{type}"'
|
||||
edit: editar modelo
|
||||
@ -244,18 +236,14 @@ es:
|
||||
download: descargar elementos
|
||||
new: nuevo elemento
|
||||
category_noname: "Sin nombre"
|
||||
lastest_items: "Últimos elementos"
|
||||
lastest_entries: "Últimos elementos"
|
||||
updated_at: "Última actualización"
|
||||
list:
|
||||
no_items: "No hay ningún elemento. Haga click <a href=\"%{url}\">aquí</a> para crear el primero."
|
||||
no_entries: "No hay ningún elemento. Haga click <a href=\"%{url}\">aquí</a> para crear el primero."
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — nuevo elemento'
|
||||
breadcrumb: '%{root} » %{type} — nuevo elemento'
|
||||
title: '%{type} — nuevo elemento'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — editando elemento'
|
||||
breadcrumb: '%{root} » %{type} — editando elemento'
|
||||
title: '%{type} — editando elemento'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Nuevo elemento
|
||||
|
@ -46,7 +46,7 @@ fr:
|
||||
send: Envoyer
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: "[%{type}] nouveau"
|
||||
title: "Bonjour %{name}, nous voulions vous faire savoir qu'une nouvelle instance a été créée le %{date}"
|
||||
type: "Modèle: %{type}"
|
||||
@ -60,15 +60,7 @@ fr:
|
||||
text_formatting:
|
||||
none: Aucun
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Editer champ
|
||||
edit_category:
|
||||
title: Editer options
|
||||
help: Gèrer la liste des options de votre liste déroulante
|
||||
collection_label: Liste des options
|
||||
types:
|
||||
category:
|
||||
edit_categories: Editer options
|
||||
file:
|
||||
delete_file: Supprimer fichier
|
||||
has_many:
|
||||
@ -240,7 +232,7 @@ fr:
|
||||
asc: Ascendant
|
||||
desc: Descendant
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: 'Liste des "%{type}"'
|
||||
edit: éditer modèle
|
||||
@ -248,18 +240,14 @@ fr:
|
||||
download: télécharger éléments
|
||||
new: nouvel élément
|
||||
category_noname: "Pas de nom"
|
||||
lastest_items: "Eléments récents"
|
||||
lastest_entries: "Eléments récents"
|
||||
updated_at: "Mis à jour le"
|
||||
list:
|
||||
no_items: "Il n'existe pas d'éléments. Vous pouvez commencer par créer un <a href='%{url}'>ici</a>"
|
||||
no_entries: "Il n'existe pas d'éléments. Vous pouvez commencer par créer un <a href='%{url}'>ici</a>"
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — nouvel élément'
|
||||
breadcrumb: '%{root} » %{type} — nouvel élément'
|
||||
title: '%{type} — nouvel élément'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — édition élément'
|
||||
breadcrumb: '%{root} » %{type} — édition élément'
|
||||
title: '%{type} — édition élément'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Nouvel élément
|
||||
|
@ -46,7 +46,7 @@ it:
|
||||
link: "→ Ritorna all'applicazione"
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: "[%{type}] nuovo/a"
|
||||
title: "Ciao %{name}, solo per farti sapere che una nuova istanza è stata creata il %{date}"
|
||||
type: "Modello: %{type}"
|
||||
@ -60,15 +60,7 @@ it:
|
||||
text_formatting:
|
||||
none: Nessuno
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Modifica campo
|
||||
edit_category:
|
||||
title: Modifica opzioni
|
||||
help: Amministra la lista opzioni del select box.
|
||||
collection_label: Lista delle opzioni
|
||||
types:
|
||||
category:
|
||||
edit_categories: Modifica opzioni
|
||||
file:
|
||||
delete_file: Elimina file
|
||||
index:
|
||||
@ -235,7 +227,7 @@ it:
|
||||
asc: Ascendente
|
||||
desc: Discendente
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: 'Lista "%{type}"'
|
||||
edit: modifica modello
|
||||
@ -243,18 +235,14 @@ it:
|
||||
download: scarica elementi
|
||||
new: nuovo elemento
|
||||
category_noname: "Senza nome"
|
||||
lastest_items: "Ultimi elementi"
|
||||
lastest_entries: "Ultimi elementi"
|
||||
updated_at: "modificato il"
|
||||
list:
|
||||
no_items: "Per ora non ci sono elementi. Clicca <a href=\"%{url}\">qui</a> per creare il primo."
|
||||
no_entries: "Per ora non ci sono elementi. Clicca <a href=\"%{url}\">qui</a> per creare il primo."
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — nuovo elemento'
|
||||
breadcrumb: '%{root} » %{type} — nuovo elemento'
|
||||
title: '%{type} — nuovo elemento'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — modifica elemento'
|
||||
breadcrumb: '%{root} » %{type} — modifica elemento'
|
||||
title: '%{type} — modifica elemento'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Nuovo elemento
|
||||
|
@ -43,7 +43,7 @@ nl:
|
||||
link: "→ Terug naar de applicatie"
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: "[%{type}] nieuw"
|
||||
title: "Hallo %{name}, dit bericht is om te laten weten dat er een nieuwe instantie is gemaakt op %{date}"
|
||||
type: "Model: %{type}"
|
||||
@ -54,14 +54,7 @@ nl:
|
||||
text_formatting:
|
||||
none: Geen
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Bewerk veld
|
||||
edit_category:
|
||||
title: Bewerk opties
|
||||
help: Beheer de lijst met opties voor uw select box.
|
||||
collection_label: Lijst met opties
|
||||
custom_form:
|
||||
edit_categories: Bewerk opties
|
||||
delete_file: Verwijder bestand
|
||||
index:
|
||||
is_required: is verplicht
|
||||
@ -219,7 +212,7 @@ nl:
|
||||
asc: Oplopend
|
||||
desc: Aflopend
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: 'Toon "%{type}"'
|
||||
edit: wijzig model
|
||||
@ -227,18 +220,14 @@ nl:
|
||||
download: download items
|
||||
new: nieuw item
|
||||
category_noname: "Geen naam"
|
||||
lastest_items: "Laatste items"
|
||||
lastest_entries: "Laatste items"
|
||||
updated_at: "Gewijzigd op"
|
||||
list:
|
||||
no_items: "Er zijn momenteel geen items. Klik hier <a href=\"%{url}\">here</a> om de eerste te maken."
|
||||
no_entries: "Er zijn momenteel geen items. Klik hier <a href=\"%{url}\">here</a> om de eerste te maken."
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — nieuw item'
|
||||
breadcrumb: '%{root} » %{type} — nieuw item'
|
||||
title: '%{type} — nieuw item'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — wijzig item'
|
||||
breadcrumb: '%{root} » %{type} — wijzig item'
|
||||
title: '%{type} — wijzig item'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Nieuw item
|
||||
|
@ -46,7 +46,7 @@
|
||||
link: "→ Tilbake til applikasjonen"
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: "[%{type}] ny"
|
||||
title: "Hei %{name}, varsler om at en ny instanse ble opprettet %{date}"
|
||||
type: "Modell: %{type}"
|
||||
@ -60,15 +60,7 @@
|
||||
text_formatting:
|
||||
none: Ingen
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Rediger felt
|
||||
edit_category:
|
||||
title: Rediger innstillinger
|
||||
help: Rediger listen med innstillinger i select-boksen
|
||||
collection_label: Liste med innstillinger
|
||||
types:
|
||||
category:
|
||||
edit_categories: Rediger innstillinger
|
||||
file:
|
||||
delete_file: Slett fil
|
||||
has_many:
|
||||
@ -237,7 +229,7 @@
|
||||
asc: Stigende
|
||||
desc: Synkende
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: 'Viser alle "%{type}"'
|
||||
edit: rediger modell
|
||||
@ -245,18 +237,14 @@
|
||||
download: last ned elementer
|
||||
new: nytt element
|
||||
category_noname: "Navn mangler"
|
||||
lastest_items: "Siste elementer"
|
||||
lastest_entries: "Siste elementer"
|
||||
updated_at: "Sist oppdatert"
|
||||
list:
|
||||
no_items: "Det har ikke blitt opprettet noen elementer her ennå. Klikk <a href=\"%{url}\">her</a> for å opprette det første."
|
||||
no_entries: "Det har ikke blitt opprettet noen elementer her ennå. Klikk <a href=\"%{url}\">her</a> for å opprette det første."
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — nytt element'
|
||||
breadcrumb: '%{root} » %{type} — nytt element'
|
||||
title: '%{type} — nytt element'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — rediger element'
|
||||
breadcrumb: '%{root} » %{type} — rediger element'
|
||||
title: '%{type} — rediger element'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Nytt element
|
||||
|
@ -43,7 +43,7 @@ pt-BR:
|
||||
link: "→ Voltar a aplicação"
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: " Novo [%{type}] "
|
||||
title: "Olá %{name}, apenas informando que uma nova instância foi criada em %{date}"
|
||||
type: "Modelo: %{type}"
|
||||
@ -54,15 +54,7 @@ pt-BR:
|
||||
text_formatting:
|
||||
none: Nenhum
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Edita campo
|
||||
edit_category:
|
||||
title: Editar opções
|
||||
help: Gerenciar a lista de opções da sua caixa de seleçõa.
|
||||
collection_label: Lista de opções
|
||||
types:
|
||||
category:
|
||||
edit_categories: Editar opções
|
||||
file:
|
||||
delete_file: Excluir arquivo
|
||||
|
||||
@ -215,7 +207,7 @@ pt-BR:
|
||||
updated_at: 'Por "atualizado em" data'
|
||||
position_in_list: Manual
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: 'Listando "%{type}"'
|
||||
edit: editar modelo
|
||||
@ -223,18 +215,14 @@ pt-BR:
|
||||
download: download dos itens
|
||||
new: novo item
|
||||
category_noname: "Sem nome"
|
||||
lastest_items: "Últimos itens"
|
||||
lastest_entries: "Últimos itens"
|
||||
updated_at: "Atualizado em"
|
||||
list:
|
||||
no_items: "Não existem itens ainda. Clique <a href=\"%{url}\">aqui</a> para criar o primeiro."
|
||||
no_entries: "Não existem itens ainda. Clique <a href=\"%{url}\">aqui</a> para criar o primeiro."
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — novo item'
|
||||
breadcrumb: '%{root} » %{type} — novo item'
|
||||
title: '%{type} — novo item'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — editando item'
|
||||
breadcrumb: '%{root} » %{type} — editando item'
|
||||
title: '%{type} — editando item'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Novo item
|
||||
|
@ -46,7 +46,7 @@ ru:
|
||||
link: "→ Назад в приложение"
|
||||
|
||||
notifications:
|
||||
new_content_instance:
|
||||
new_content_entry:
|
||||
subject: "[%{type}] новый"
|
||||
title: "Привет %{name}, просто сообщаем, что новый элемент был создан %{date}"
|
||||
type: "Модель: %{type}"
|
||||
@ -60,15 +60,7 @@ ru:
|
||||
text_formatting:
|
||||
none: None
|
||||
html: HTML
|
||||
edit_field:
|
||||
title: Редактировать поле
|
||||
edit_category:
|
||||
title: Редактировать опции
|
||||
help: Управляйте списком опций для поля выбора select.
|
||||
collection_label: Списко опций
|
||||
types:
|
||||
category:
|
||||
edit_categories: Редактировать опции
|
||||
file:
|
||||
delete_file: Удалить файл
|
||||
has_many:
|
||||
@ -236,7 +228,7 @@ ru:
|
||||
asc: По возрастанию
|
||||
desc: По убыванию
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
index:
|
||||
title: 'Список "%{type}"'
|
||||
edit: редактировать модель
|
||||
@ -244,18 +236,14 @@ ru:
|
||||
download: скачать элементы
|
||||
new: новый элемент
|
||||
category_noname: "Без имени"
|
||||
lastest_items: "Элементы за последнее время"
|
||||
lastest_entries: "Элементы за последнее время"
|
||||
updated_at: "Обновлено"
|
||||
list:
|
||||
no_items: "На данный момент нет ни одного элемента. Нажмите <a href=\"%{url}\">здесь</a> для создания первого элемента."
|
||||
no_entries: "На данный момент нет ни одного элемента. Нажмите <a href=\"%{url}\">здесь</a> для создания первого элемента."
|
||||
new:
|
||||
title:
|
||||
default: '%{type} — новый элемент'
|
||||
breadcrumb: '%{root} » %{type} — новый элемент'
|
||||
title: '%{type} — новый элемент'
|
||||
edit:
|
||||
title:
|
||||
default: '%{type} — редактирование элемента'
|
||||
breadcrumb: '%{root} » %{type} — редактирование элемента'
|
||||
title: '%{type} — редактирование элемента'
|
||||
form:
|
||||
has_many:
|
||||
new_item: Новый элемент
|
||||
|
@ -95,7 +95,7 @@ es:
|
||||
access_password: "Clave"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
hint: Ayuda
|
||||
required: Obligatorio
|
||||
text_formatting: Formato
|
||||
|
@ -95,7 +95,7 @@ fr:
|
||||
access_password: "Mot de passe"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
hint: Aide
|
||||
required: Requis ?
|
||||
text_formatting: Formattage
|
||||
|
@ -100,7 +100,7 @@ it:
|
||||
access_password: Password
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
hint: Aiuto
|
||||
required: Obbligatorio
|
||||
text_formatting: Formattazione
|
||||
|
@ -13,7 +13,7 @@ de:
|
||||
destroy:
|
||||
notice: "Seite wurde erfolgreich gelöscht."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "Inhalt wurde erfolgreich erstellt."
|
||||
alert: "Inhalt wurde nicht erstellt."
|
||||
|
@ -13,17 +13,17 @@ en:
|
||||
destroy:
|
||||
notice: "Page was successfully deleted."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "Content was successfully created."
|
||||
alert: "Content was not created."
|
||||
notice: "Entry was successfully created."
|
||||
alert: "Entry was not created."
|
||||
update:
|
||||
notice: "Content was successfully updated."
|
||||
alert: "Content was not updated."
|
||||
notice: "Entry was successfully updated."
|
||||
alert: "Entry was not updated."
|
||||
sort:
|
||||
notice: "Contents were successfully sorted."
|
||||
notice: "Entries were successfully sorted."
|
||||
destroy:
|
||||
notice: "Content was successfully deleted."
|
||||
notice: "Entry was successfully deleted."
|
||||
|
||||
content_types:
|
||||
create:
|
||||
|
@ -13,7 +13,7 @@ es:
|
||||
destroy:
|
||||
notice: "Página borrada con éxito."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "Contenido multimedia creado con éxito."
|
||||
alert: "El contenido multimedia no se pudo crear."
|
||||
|
@ -13,7 +13,7 @@ fr:
|
||||
destroy:
|
||||
notice: "La page a été supprimée avec succès."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "L'élément a été crée avec succès."
|
||||
alert: "L'élément a été crée avec succès."
|
||||
|
@ -13,7 +13,7 @@ it:
|
||||
destroy:
|
||||
notice: "La pagina è stata eliminata con successo."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "Il contenuto è stato creato con successo."
|
||||
alert: "Il contenuto non è stato creato."
|
||||
|
@ -13,7 +13,7 @@ nl:
|
||||
destroy:
|
||||
notice: "Pagina is verwijderd."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "Inhoud is gemaakt."
|
||||
alert: "Inhoud is niet gemaakt."
|
||||
|
@ -13,7 +13,7 @@
|
||||
destroy:
|
||||
notice: "Siden har blitt slettet."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "Innholdet har blitt opprettet."
|
||||
alert: "Innholdet kunne ikke opprettes."
|
||||
|
@ -13,7 +13,7 @@ pt-BR:
|
||||
destroy:
|
||||
notice: "Páginas foram apagadas com sucesso."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "Conteúdo criado com sucesso."
|
||||
alert: "Conteúdo não foi criado."
|
||||
|
@ -13,7 +13,7 @@ ru:
|
||||
destroy:
|
||||
notice: "Страницы успешно удалены."
|
||||
|
||||
contents:
|
||||
content_entries:
|
||||
create:
|
||||
notice: "Контент успешно создан."
|
||||
alert: "Контент не создан."
|
||||
|
@ -30,7 +30,7 @@ de:
|
||||
source: Datei ersetzen
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
import:
|
||||
new:
|
||||
source: Datei
|
||||
@ -69,7 +69,7 @@ de:
|
||||
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Merkmal verfügbar in den liquid-Templates"
|
||||
name: "Merkmal verfügbar in den liquid-Templates"
|
||||
hint: "Hilfe-Text, der im Formular des Bausteins direkt unter dem jeweiligen Feld angezeigt wird"
|
||||
import:
|
||||
source: "Eine zip-Datei, die eine databse.yml, Assets und Templates enthält"
|
||||
|
@ -32,7 +32,7 @@ en:
|
||||
source: Replace file
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
import:
|
||||
new:
|
||||
source: File
|
||||
@ -44,7 +44,7 @@ en:
|
||||
public_form_accounts: Notified Accounts
|
||||
"custom_fields/field":
|
||||
select_options: "Options"
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: Permalink
|
||||
account:
|
||||
edit:
|
||||
@ -82,7 +82,7 @@ en:
|
||||
source: "The current file is available here %{url}"
|
||||
update:
|
||||
source: "The current file is available here %{url}"
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: "Property used to generate the url of a page working as a template for this content type (ex: \"template_page/{{ your_object._permalink }})\"."
|
||||
seo_title: "The value you fill in will replace the SEO title of the templatized page related to your model."
|
||||
meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma."
|
||||
|
@ -30,7 +30,7 @@ es:
|
||||
source: Reemplazar fichero
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
import:
|
||||
new:
|
||||
source: Fichero
|
||||
@ -72,7 +72,7 @@ es:
|
||||
source: "El fichero está disponible aquí: %{url}"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Propiedad disponible en plantillas Liquid"
|
||||
name: "Propiedad disponible en plantillas Liquid"
|
||||
hint: "Texto mostrado justo debajo del campo en el formulario de creación"
|
||||
import:
|
||||
source: "Un fichero zip conteniendo un fichero database.yml con plantillas y contenido multimedia."
|
||||
|
@ -34,7 +34,7 @@ fr:
|
||||
source: Nouveau fichier
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
import:
|
||||
new:
|
||||
source: Fichier
|
||||
@ -43,7 +43,7 @@ fr:
|
||||
content_type:
|
||||
item_template: Template d'affichage
|
||||
api_accounts: Comptes à notifier
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: Permalink
|
||||
account:
|
||||
edit:
|
||||
@ -81,9 +81,9 @@ fr:
|
||||
source: "Le fichier actuel est accessible ici %{url}"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Champ utilisable dans les templates liquid"
|
||||
name: "Champ utilisable dans les templates liquid"
|
||||
hint: "Texte affiché dans le formulaire de l'élément juste en dessous du champ."
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: "Propriété utilisée pour générer l'url d'une page faisant office de template pour ce modèle (ex: \"template_de_la_page/{{ votre_object._permalink }})\"."
|
||||
seo_title: "La valeur que vous rentrez sera utilisée comme titre SEO pour la page faisant office de template pour ce modèle."
|
||||
meta_keywords: "Redéfinit les mots-clés du site. Utilisés à l'intérieur de la balise HEAD. Ils sont séparés par une virgule."
|
||||
|
@ -32,7 +32,7 @@ it:
|
||||
source: Sostituire file
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
import:
|
||||
new:
|
||||
source: File
|
||||
@ -42,14 +42,14 @@ it:
|
||||
content_type:
|
||||
item_template: Template di elemento
|
||||
api_accounts: Destinatari notifiche
|
||||
content_instance:
|
||||
_slug: Permalink
|
||||
content_entry:
|
||||
_slug: Permalink
|
||||
account:
|
||||
edit:
|
||||
password: Nuova password
|
||||
password_confirmation: Conferma nuova password
|
||||
page:
|
||||
seo_title: Title
|
||||
seo_title: Title
|
||||
|
||||
hints:
|
||||
page:
|
||||
@ -81,9 +81,9 @@ it:
|
||||
source: "Il corrente file è disponibile qui %{url}"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Proprietà disponibile nei tamplate liquid"
|
||||
name: "Proprietà disponibile nei tamplate liquid"
|
||||
hint: "Testo visualizzato nel form del modello appena sotto il campo"
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: "Proprità utilizzata per generare l'url della pagina di template per questo contenuto (es: \"template_page/{{ your_object._permalink }})\"."
|
||||
seo_title: "Il valore del tag title della pagina che visualizza questo contenuto."
|
||||
meta_keywords: "Sovrascrive le meta keywords per questo contenuto. Separate da virgola."
|
||||
|
@ -30,7 +30,7 @@ nl:
|
||||
source: Vervang bestand
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
import:
|
||||
new:
|
||||
source: Bestand
|
||||
@ -72,7 +72,7 @@ nl:
|
||||
source: "Het huidige bestand is hier beschikbaar %{url}"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Eigenschap is beschikbaar in liquid templates"
|
||||
name: "Eigenschap is beschikbaar in liquid templates"
|
||||
hint: "Net beneden het veld staat de tekst in het model formulier"
|
||||
import:
|
||||
source: "Een .zip bestand met een database.yml met de bronbestanden en templates"
|
||||
|
@ -32,7 +32,7 @@
|
||||
source: Erstatt fil
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Alias
|
||||
name: Alias
|
||||
import:
|
||||
new:
|
||||
source: Fil
|
||||
@ -42,7 +42,7 @@
|
||||
content_type:
|
||||
item_template: Elementmal
|
||||
api_accounts: Varslede kontoer
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: Permalink
|
||||
account:
|
||||
edit:
|
||||
@ -81,9 +81,9 @@
|
||||
source: "Filen er tilgjengelig her: %{url}"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Verdi tilgjengelig i liquid-maler"
|
||||
name: "Verdi tilgjengelig i liquid-maler"
|
||||
hint: "Tekst som vises i skjemaet rett under feltet"
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: "Verdien brukes til å generere en url for en side som fungerer som en mal for denne innholdstypen (f.eks: \"template_page/{{ your_object._permalink }})\"."
|
||||
seo_title: "Verdien benyttes til å erstatte sidetittelen for malen knyttet til modellen. Leses av søkemotorer."
|
||||
meta_keywords: "Overstyrer sidens meta-nøkkelord som benyttes i head-seksjonen på siden og blir lest av søkemotorer. Separeres med komma."
|
||||
|
@ -29,7 +29,7 @@ pt-BR:
|
||||
source: Substituir arquivo
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Apelido
|
||||
name: Apelido
|
||||
import:
|
||||
new:
|
||||
source: Arquivo
|
||||
@ -59,7 +59,7 @@ pt-BR:
|
||||
source: "Você pode substituir por um arquivo com a mesma extensão."
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Propriedades disponíveis em templates líquidos."
|
||||
name: "Propriedades disponíveis em templates líquidos."
|
||||
hint: "Texto mostrado no formulário de modelo está abaixo do campo."
|
||||
import:
|
||||
source: "Um arquivo .zip contendo um database.yml com assets and templates"
|
||||
|
@ -32,7 +32,7 @@ ru:
|
||||
source: Заменить файл
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: Алиас
|
||||
name: Алиас
|
||||
import:
|
||||
new:
|
||||
source: Файл
|
||||
@ -42,7 +42,7 @@ ru:
|
||||
content_type:
|
||||
item_template: Шаблон элемента
|
||||
api_accounts: Уведомленные аккаунты
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: Постоянная ссылка
|
||||
account:
|
||||
edit:
|
||||
@ -81,9 +81,9 @@ ru:
|
||||
source: "Текущий файл доступен здесь %{url}"
|
||||
custom_fields:
|
||||
field:
|
||||
_alias: "Свойство, доступное в шаблонах liquid"
|
||||
name: "Свойство, доступное в шаблонах liquid"
|
||||
hint: "Текст, отображенный в форме модели, находится ниже поля"
|
||||
content_instance:
|
||||
content_entry:
|
||||
_slug: "Свойство, используемое для генерации ссылки (url) на страницу, работающей как шаблон для этого типа содержимого (ex: \"template_page/{{ your_object._permalink }})\"."
|
||||
seo_title: "Значение, вводимое вами, будет заменять SEO заголовок шаблонизированной страницы, связанной с вашей моделью."
|
||||
meta_keywords: "Переопределяет meta keywords сайта, используемые внутри тэга head страницы. Разделяются запятыми."
|
||||
|
@ -37,7 +37,7 @@ Locomotive::Engine.routes.draw do
|
||||
|
||||
resources :content_types
|
||||
|
||||
resources :contents, :path => 'content_types/:slug/contents' do
|
||||
resources :content_entries, :path => 'content_types/:slug/entries' do
|
||||
put :sort, :on => :collection
|
||||
end
|
||||
|
||||
|
1
doc/TODO
1
doc/TODO
@ -53,6 +53,7 @@ x edit my site
|
||||
- manage contents
|
||||
- list (highlighted field)
|
||||
- crud
|
||||
- public_form (previously api something)
|
||||
|
||||
- disallow to click twice on the submit form button (spinner ?)
|
||||
- message to notify people if their browser is too old
|
||||
|
@ -6,7 +6,7 @@ Feature: Editing a content type
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a custom model named "Projects" with
|
||||
| label | kind | required |
|
||||
| label | type | required |
|
||||
| Name | string | true |
|
||||
| Description | text | false |
|
||||
And I have a designer and an author
|
||||
|
@ -6,7 +6,7 @@ Feature: Pages
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a custom model named "Projects" with
|
||||
| label | kind | required |
|
||||
| label | type | required |
|
||||
| Name | string | true |
|
||||
| Description | text | false |
|
||||
And I have a designer and an author
|
||||
|
@ -6,7 +6,7 @@ Feature: Manage Content Types
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a custom model named "Projects" with
|
||||
| label | kind | required |
|
||||
| label | type | required |
|
||||
| Name | string | true |
|
||||
| Description | text | false |
|
||||
And I am an authenticated user
|
||||
|
@ -6,11 +6,11 @@ Feature: Create and manage has many relationships
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a custom model named "Projects" with
|
||||
| label | kind | required | target |
|
||||
| label | type | required | target |
|
||||
| Name | string | true | |
|
||||
| Description | text | false | |
|
||||
And I have a custom model named "Clients" with
|
||||
| label | kind | required | target |
|
||||
| label | type | required | target |
|
||||
| Name | string | true | |
|
||||
| Description | string | false | |
|
||||
| Projects | has_many | false | Projects |
|
||||
|
@ -6,11 +6,11 @@ Feature: Set up a has many reverse relationship
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a custom model named "Clients" with
|
||||
| label | kind | required |
|
||||
| label | type | required |
|
||||
| Name | string | true |
|
||||
| Description | string | false |
|
||||
And I have a custom model named "Projects" with
|
||||
| label | kind | required | target |
|
||||
| label | type | required | target |
|
||||
| Name | string | true | |
|
||||
| Description | text | false | |
|
||||
| Client | has_one | false | Clients |
|
||||
|
@ -6,10 +6,10 @@ Feature: Manage Contents
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a custom model named "Projects" with
|
||||
| label | kind | required |
|
||||
| label | type | required |
|
||||
| Name | string | true |
|
||||
| Description | text | false |
|
||||
| Category | category | false |
|
||||
| Category | select | false |
|
||||
And I have "Design, Development" as "Category" values of the "Projects" model
|
||||
And I am an authenticated user
|
||||
And I have entries for "Projects" with
|
||||
|
@ -5,7 +5,7 @@ Feature: TableRow liquid tags
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I have a custom model named "Projects" with
|
||||
| label | kind | required |
|
||||
| label | type | required |
|
||||
| Name | string | true |
|
||||
And I have entries for "Projects" with
|
||||
| name |
|
||||
|
@ -7,7 +7,7 @@ Given %r{^I have a custom model named "([^"]*)" with$} do |name, fields|
|
||||
field['target'] = target_content_type.content_klass.to_s
|
||||
end
|
||||
|
||||
content_type.contents_custom_fields.build field
|
||||
content_type.entries_custom_fields.build field
|
||||
end
|
||||
content_type.valid?
|
||||
content_type.save.should be_true
|
||||
@ -19,9 +19,9 @@ Given /^I set up a reverse has_many relationship between "([^"]*)" and "([^"]*)"
|
||||
content_type_1 = site.content_types.where(:name => name_1).first
|
||||
content_type_2 = site.content_types.where(:name => name_2).first
|
||||
|
||||
content_type_1.contents_custom_fields.build({
|
||||
content_type_1.entries_custom_fields.build({
|
||||
:label => name_2,
|
||||
:kind => 'has_many',
|
||||
:type => 'has_many',
|
||||
:target => content_type_2.content_klass.to_s,
|
||||
:reverse_lookup => content_type_2.content_klass.custom_field_alias_to_name(name_1.downcase.singularize)
|
||||
})
|
||||
@ -31,30 +31,30 @@ end
|
||||
|
||||
Given %r{^I have "([^"]*)" as "([^"]*)" values of the "([^"]*)" model$} do |values, field, name|
|
||||
content_type = Locomotive::ContentType.where(:name => name).first
|
||||
field = content_type.contents_custom_fields.detect { |f| f.label == field }
|
||||
field = content_type.entries_custom_fields.detect { |f| f.label == field }
|
||||
field.should_not be_nil
|
||||
|
||||
if field.category?
|
||||
if field.type == 'select'
|
||||
values.split(',').collect(&:strip).each do |name|
|
||||
field.category_items.build :name => name
|
||||
field.select_options.build :name => name
|
||||
end
|
||||
content_type.save.should be_true
|
||||
else
|
||||
raise "#{field.kind} field is not supported"
|
||||
raise "#{field.type} field is not supported"
|
||||
end
|
||||
end
|
||||
|
||||
Given %r{^I have entries for "([^"]*)" with$} do |name, entries|
|
||||
content_type = Locomotive::ContentType.where(:name => name).first
|
||||
entries.hashes.each do |entry|
|
||||
content_type.contents.create(entry)
|
||||
content_type.entries.create(entry)
|
||||
end
|
||||
content_type.save.should be_true
|
||||
end
|
||||
|
||||
When %r{^I change the presentation of the "([^"]*)" model by grouping items by "([^"]*)"$} do |name, field|
|
||||
content_type = Locomotive::ContentType.where(:name => name).first
|
||||
field = content_type.contents_custom_fields.detect { |f| f.label == field }
|
||||
field = content_type.entries_custom_fields.detect { |f| f.label == field }
|
||||
content_type.group_by_field_name = field._name
|
||||
content_type.save.should be_true
|
||||
end
|
||||
|
@ -1,15 +1,15 @@
|
||||
Given %r{^I have an? "([^"]*)" model which has many "([^"]*)"$} do |parent_model, child_model|
|
||||
@parent_model = FactoryGirl.build(:content_type, :site => @site, :name => parent_model).tap do |ct|
|
||||
ct.contents_custom_fields.build :label => 'Body', :kind => 'string', :required => false
|
||||
ct.entries_custom_fields.build :label => 'Body', :type => 'string', :required => false
|
||||
ct.save!
|
||||
end
|
||||
@child_model = FactoryGirl.build(:content_type, :site => @site, :name => child_model).tap do |ct|
|
||||
ct.contents_custom_fields.build :label => 'Body', :kind => 'string', :required => false
|
||||
ct.contents_custom_fields.build :label => parent_model.singularize, :kind => 'has_one', :required => false, :target => parent_model
|
||||
ct.entries_custom_fields.build :label => 'Body', :type => 'string', :required => false
|
||||
ct.entries_custom_fields.build :label => parent_model.singularize, :kind => 'has_one', :required => false, :target => parent_model
|
||||
ct.save!
|
||||
end
|
||||
|
||||
@parent_model.contents_custom_fields.build({
|
||||
@parent_model.entries_custom_fields.build({
|
||||
:label => child_model,
|
||||
:kind => 'has_many',
|
||||
:target => @child_model.content_klass.to_s,
|
||||
@ -22,12 +22,12 @@ Then /^I should be able to view a paginaed list of a has many association$/ do
|
||||
step %{I have an "Articles" model which has many "Comments"}
|
||||
|
||||
# Create contents
|
||||
article = @parent_model.contents.create!(:slug => 'parent', :body => 'Parent')
|
||||
@child_model.contents.create!(:slug => 'one', :body => 'One', :custom_field_2 => article.id.to_s)
|
||||
@child_model.contents.create!(:slug => 'two', :body => 'Two', :custom_field_2 => article.id.to_s)
|
||||
@child_model.contents.create!(:slug => 'three', :body => 'Three', :custom_field_2 => article.id.to_s)
|
||||
article = @parent_model.entries.create!(:slug => 'parent', :body => 'Parent')
|
||||
@child_model.entries.create!(:slug => 'one', :body => 'One', :custom_field_2 => article.id.to_s)
|
||||
@child_model.entries.create!(:slug => 'two', :body => 'Two', :custom_field_2 => article.id.to_s)
|
||||
@child_model.entries.create!(:slug => 'three', :body => 'Three', :custom_field_2 => article.id.to_s)
|
||||
|
||||
@child_model.contents.each do |comment|
|
||||
@child_model.entries.each do |comment|
|
||||
article.comments << comment
|
||||
end
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
Then /^I should be able to display paginated models$/ do
|
||||
# Create our article model and three articles
|
||||
@article_model = FactoryGirl.build(:content_type, :site => @site, :name => 'Articles').tap do |ct|
|
||||
ct.contents_custom_fields.build :label => 'Body', :kind => 'string', :required => false
|
||||
ct.entries_custom_fields.build :label => 'Body', :type => 'string', :required => false
|
||||
ct.save!
|
||||
end
|
||||
|
||||
%w(First Second Third).each do |body|
|
||||
@article_model.contents.create!(:body => body)
|
||||
@article_model.entries.create!(:body => body)
|
||||
end
|
||||
|
||||
# Create a page with template
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Custom options for CustomFields
|
||||
CustomFields.options = {
|
||||
:reserved_aliases => Mongoid.destructive_fields + %w(created_at updated_at)
|
||||
:reserved_names => Mongoid.destructive_fields + %w(created_at updated_at)
|
||||
}
|
||||
|
||||
# Set correct paths
|
||||
@ -20,15 +20,6 @@ module CustomFields
|
||||
end
|
||||
end
|
||||
|
||||
# module Category
|
||||
# class Item
|
||||
#
|
||||
# def to_liquid
|
||||
# { 'id' => self._id.to_s, 'name' => self.name }
|
||||
# end
|
||||
#
|
||||
# end
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -107,12 +107,14 @@ module Locomotive
|
||||
@site.content_types.each do |content_type|
|
||||
attributes = self.extract_attributes(content_type, %w(name description slug order_by order_direction group_by_field_name api_enabled))
|
||||
|
||||
attributes['highlighted_field_name'] = content_type.highlighted_field._alias
|
||||
attributes['highlighted_field_name'] = content_type.highlighted_field.name
|
||||
|
||||
# TODO: refactoring
|
||||
|
||||
# custom_fields
|
||||
fields = []
|
||||
content_type.contents_custom_fields.each do |field|
|
||||
field_attributes = self.extract_attributes(field, %w(label kind hint required))
|
||||
content_type.entries_custom_fields.each do |field|
|
||||
field_attributes = self.extract_attributes(field, %w(label type hint required))
|
||||
|
||||
if field.target.present?
|
||||
target_klass = field['target'].constantize
|
||||
@ -124,7 +126,7 @@ module Locomotive
|
||||
end
|
||||
end
|
||||
|
||||
fields << { field._alias => field_attributes }
|
||||
fields << { field.name => field_attributes }
|
||||
end
|
||||
|
||||
attributes['fields'] = fields
|
||||
@ -275,15 +277,17 @@ module Locomotive
|
||||
def extract_contents(content_type)
|
||||
data = []
|
||||
|
||||
# TODO (refactoring....)
|
||||
|
||||
highlighted_field_name = content_type.highlighted_field_name
|
||||
|
||||
content_type.contents.each do |content|
|
||||
content_type.entries.each do |content|
|
||||
hash = {}
|
||||
|
||||
content.custom_fields.each do |field|
|
||||
next if field._name == highlighted_field_name
|
||||
|
||||
value = (case field.kind
|
||||
value = (case field.type
|
||||
when 'file'
|
||||
uploader = content.send(field._name)
|
||||
unless uploader.blank?
|
||||
@ -296,16 +300,16 @@ module Locomotive
|
||||
when 'text'
|
||||
self.replace_asset_urls_in(content.send(field._name.to_sym) || '')
|
||||
when 'has_one'
|
||||
content.send(field.safe_alias.to_sym).highlighted_field_value rescue nil # no bound object
|
||||
content.send(field.name.to_sym).highlighted_field_value rescue nil # no bound object
|
||||
when 'has_many'
|
||||
unless field.reverse_has_many?
|
||||
content.send(field.safe_alias.to_sym).collect(&:highlighted_field_value)
|
||||
content.send(field.name.to_sym).collect(&:highlighted_field_value)
|
||||
end
|
||||
else
|
||||
content.send(field.safe_alias.to_sym)
|
||||
content.send(field.name.to_sym)
|
||||
end)
|
||||
|
||||
hash[field._alias] = value if value.present? || value == false # False values should be preserved in the export
|
||||
hash[field.name] = value if value.present? || value == false # False values should be preserved in the export
|
||||
end
|
||||
|
||||
data << { content.highlighted_field_value => hash }
|
||||
|
@ -11,8 +11,8 @@ module Locomotive
|
||||
protected
|
||||
|
||||
def add_theme_assets
|
||||
%w(images media fonts javascripts stylesheets).each do |kind|
|
||||
Dir[File.join(theme_path, 'public', kind, '**/*')].each do |asset_path|
|
||||
%w(images media fonts javascripts stylesheets).each do |type|
|
||||
Dir[File.join(theme_path, 'public', type, '**/*')].each do |asset_path|
|
||||
|
||||
next if File.directory?(asset_path)
|
||||
|
||||
|
@ -24,7 +24,7 @@ module Locomotive
|
||||
|
||||
self.add_or_update_fields(content_type, attributes['fields'])
|
||||
|
||||
if content_type.contents_custom_fields.any? { |f| ['has_many', 'has_one'].include?(f.kind) }
|
||||
if content_type.entries_custom_fields.any? { |f| ['has_many', 'has_one'].include?(f.type) }
|
||||
content_types_with_associations << content_type
|
||||
end
|
||||
|
||||
@ -80,17 +80,17 @@ module Locomotive
|
||||
|
||||
reverse_lookup = data.delete('reverse')
|
||||
|
||||
attributes = { :_alias => name, :label => name.humanize, :kind => 'string', :position => position }.merge(data).symbolize_keys
|
||||
attributes = { :name => name, :label => name.humanize, :type => 'string', :position => position }.merge(data).symbolize_keys
|
||||
|
||||
field = content_type.contents_custom_fields.detect { |f| f._alias == attributes[:_alias] }
|
||||
field = content_type.entries_custom_fields.detect { |f| f.name == attributes[:name] }
|
||||
|
||||
field ||= content_type.contents_custom_fields.build(attributes)
|
||||
field ||= content_type.entries_custom_fields.build(attributes)
|
||||
|
||||
field.send(:set_unique_name!) if field.new_record?
|
||||
|
||||
field.attributes = attributes
|
||||
|
||||
field[:kind] = field[:kind].downcase # old versions of the kind field are capitalized
|
||||
field[:type] = field[:type].downcase # old versions of the kind field are capitalized
|
||||
|
||||
field[:tmp_reverse_lookup] = reverse_lookup # use the ability in mongoid to set free attributes on the fly
|
||||
end
|
||||
@ -98,8 +98,8 @@ module Locomotive
|
||||
|
||||
def replace_target(content_types)
|
||||
content_types.each do |content_type|
|
||||
content_type.contents_custom_fields.each do |field|
|
||||
next unless ['has_many', 'has_one'].include?(field.kind)
|
||||
content_type.entries_custom_fields.each do |field|
|
||||
next unless ['has_many', 'has_one'].include?(field.type)
|
||||
|
||||
target_content_type = site.content_types.where(:slug => field.target).first
|
||||
|
||||
@ -125,6 +125,8 @@ module Locomotive
|
||||
|
||||
associations = []
|
||||
|
||||
# TODO (needs refactoring)
|
||||
|
||||
# build with default attributes
|
||||
content = content_type.contents.where(content_type.highlighted_field_name.to_sym => value).first
|
||||
|
||||
@ -141,24 +143,24 @@ module Locomotive
|
||||
end
|
||||
|
||||
attributes.each do |name, value|
|
||||
field = content_type.contents_custom_fields.detect { |f| f._alias == name }
|
||||
field = content_type.entries_custom_fields.detect { |f| f.name == name }
|
||||
|
||||
next if field.nil? # the attribute name is not related to a field (name misspelled ?)
|
||||
|
||||
kind = field.kind
|
||||
type = field.type
|
||||
|
||||
if ['has_many', 'has_one'].include?(kind)
|
||||
associations << OpenStruct.new(:name => name, :kind => kind, :value => value, :target => field.target)
|
||||
if ['has_many', 'has_one'].include?(type)
|
||||
associations << OpenStruct.new(:name => name, :type => type, :value => value, :target => field.target)
|
||||
next
|
||||
end
|
||||
|
||||
value = (case kind
|
||||
value = (case type
|
||||
when 'file' then self.open_sample_asset(value)
|
||||
when 'boolean' then Boolean.set(value)
|
||||
when 'date' then value.is_a?(Date) ? value : Date.parse(value)
|
||||
when 'category'
|
||||
if field.category_items.detect { |item| item.name == value }.nil?
|
||||
field.category_items.build :name => value
|
||||
when 'select'
|
||||
if field.select_options.detect { |item| item.name == value }.nil?
|
||||
field.select_options.build :name => value
|
||||
end
|
||||
value
|
||||
else # string, text
|
||||
@ -193,7 +195,7 @@ module Locomotive
|
||||
|
||||
next if target_content_type.nil?
|
||||
|
||||
value = (case association.kind
|
||||
value = (case association.type
|
||||
when 'has_one' then
|
||||
target_content_type.contents.detect { |c| c.highlighted_field_value == association.value }
|
||||
when 'has_many' then
|
||||
@ -210,7 +212,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
def set_highlighted_field_name(content_type)
|
||||
field = content_type.contents_custom_fields.detect { |f| f._alias == content_type.highlighted_field_name.to_s }
|
||||
field = content_type.entries_custom_fields.detect { |f| f.name == content_type.highlighted_field_name.to_s }
|
||||
|
||||
content_type.highlighted_field_name = field._name if field
|
||||
end
|
||||
@ -222,7 +224,7 @@ module Locomotive
|
||||
when 'manually', '_position_in_list' then '_position_in_list'
|
||||
when 'default', 'created_at' then 'created_at'
|
||||
else
|
||||
content_type.contents_custom_fields.detect { |f| f._alias == content_type.order_by }._name rescue nil
|
||||
content_type.entries_custom_fields.detect { |f| f.name == content_type.order_by }._name rescue nil
|
||||
end)
|
||||
|
||||
self.log "order by (after) #{order_by}"
|
||||
@ -233,7 +235,7 @@ module Locomotive
|
||||
def set_group_by_value(content_type)
|
||||
return if content_type.group_by_field_name.blank?
|
||||
|
||||
field = content_type.contents_custom_fields.detect { |f| f._alias == content_type.group_by_field_name }
|
||||
field = content_type.entries_custom_fields.detect { |f| f.name == content_type.group_by_field_name }
|
||||
|
||||
content_type.group_by_field_name = field._name if field
|
||||
end
|
||||
|
@ -3,6 +3,8 @@ module Locomotive
|
||||
module Drops
|
||||
class Contents < ::Liquid::Drop
|
||||
|
||||
# TODO: refactoring
|
||||
|
||||
def before_method(meth)
|
||||
type = @context.registers[:site].content_types.where(:slug => meth.to_s).first
|
||||
ProxyCollection.new(type)
|
||||
@ -52,7 +54,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
def before_method(meth)
|
||||
klass = @content_type.contents.klass # delegate to the proxy class
|
||||
klass = @content_type.entries.klass # delegate to the proxy class
|
||||
|
||||
if (meth.to_s =~ /^group_by_.+$/) == 0
|
||||
klass.send(meth, :ordered_contents)
|
||||
|
@ -6,17 +6,17 @@ module Locomotive
|
||||
delegate :seo_title, :meta_keywords, :meta_description, :to => '_source'
|
||||
|
||||
def title
|
||||
self._source.templatized? ? @context['content_instance'].highlighted_field_value : self._source.title
|
||||
self._source.templatized? ? @context['content_entry'].highlighted_field_value : self._source.title
|
||||
end
|
||||
|
||||
def slug
|
||||
self._source.templatized? ? self._source.content_type.slug.singularize : self._source.slug
|
||||
end
|
||||
|
||||
|
||||
def parent
|
||||
@parent ||= self._source.parent.to_liquid
|
||||
end
|
||||
|
||||
|
||||
def breadcrumbs
|
||||
@breadcrumbs ||= liquify(*self._source.self_and_ancestors)
|
||||
end
|
||||
@ -32,11 +32,11 @@ module Locomotive
|
||||
def depth
|
||||
self._source.depth
|
||||
end
|
||||
|
||||
|
||||
def listed?
|
||||
self._source.listed?
|
||||
end
|
||||
|
||||
|
||||
def published?
|
||||
self._source.published?
|
||||
end
|
||||
|
@ -42,7 +42,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
def metadata_object(context)
|
||||
context['content_instance'] || context['page']
|
||||
context['content_entry'] || context['page']
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -45,9 +45,9 @@ module Locomotive
|
||||
page = nil
|
||||
else
|
||||
if page.templatized?
|
||||
@content_instance = page.content_type.contents.where(:_slug => File.basename(path.first)).first
|
||||
@content_entry = page.content_type.entries.where(:_slug => File.basename(path.first)).first
|
||||
|
||||
if @content_instance.nil? || (!@content_instance.visible? && current_locomotive_account.nil?) # content instance not found or not visible
|
||||
if @content_entry.nil? || (!@content_entry.visible? && current_locomotive_account.nil?) # content instance not found or not visible
|
||||
page = nil
|
||||
end
|
||||
end
|
||||
@ -75,8 +75,8 @@ module Locomotive
|
||||
assigns.merge!(flash.to_hash.stringify_keys) # data from api
|
||||
|
||||
if @page.templatized? # add instance from content type
|
||||
assigns['content_instance'] = @content_instance
|
||||
assigns[@page.content_type.slug.singularize] = @content_instance # just here to help to write readable liquid code
|
||||
assigns['content_entry'] = @content_entry
|
||||
assigns[@page.content_type.slug.singularize] = @content_entry # just here to help to write readable liquid code
|
||||
end
|
||||
|
||||
registers = {
|
||||
|
@ -5,10 +5,10 @@ describe Locomotive::ApiContentsController do
|
||||
before(:each) do
|
||||
@site = FactoryGirl.create('existing site')
|
||||
@site.content_types.first.tap do |content_type|
|
||||
content_type.contents_custom_fields.build :label => 'Name', :kind => 'string', :required => true
|
||||
content_type.contents_custom_fields.build :label => 'Description', :kind => 'text'
|
||||
content_type.contents_custom_fields.build :label => 'File', :kind => 'file'
|
||||
content_type.contents_custom_fields.build :label => 'Active', :kind => 'boolean'
|
||||
content_type.entries_custom_fields.build :label => 'Name', :type => 'string', :required => true
|
||||
content_type.entries_custom_fields.build :label => 'Description', :type => 'text'
|
||||
content_type.entries_custom_fields.build :label => 'File', :type => 'file'
|
||||
content_type.entries_custom_fields.build :label => 'Active', :type => 'boolean'
|
||||
end.save
|
||||
|
||||
controller.stubs(:require_site).returns(true)
|
||||
@ -37,38 +37,38 @@ describe Locomotive::ApiContentsController do
|
||||
|
||||
response.should redirect_to('http://www.locomotivecms.com/success')
|
||||
|
||||
@site.reload.content_types.first.contents.size.should == 1
|
||||
@site.reload.content_types.first.entries.size.should == 1
|
||||
end
|
||||
|
||||
it 'does not save a content if required parameters are missing' do
|
||||
post 'create', default_post_params(:content => { :name => '' })
|
||||
post 'create', default_post_params(:content_entry => { :name => '' })
|
||||
|
||||
response.should redirect_to('http://www.locomotivecms.com/failure')
|
||||
|
||||
@site.reload.content_types.first.contents.size.should == 0
|
||||
@site.reload.content_types.first.entries.size.should == 0
|
||||
end
|
||||
|
||||
describe 'XSS vulnerability' do
|
||||
|
||||
it 'sanitizes the params (simple example)' do
|
||||
post 'create', default_post_params(:content => { :name => %(Hacking <script type="text/javascript">alert("You have been hacked")</script>) })
|
||||
post 'create', default_post_params(:content_entry => { :name => %(Hacking <script type="text/javascript">alert("You have been hacked")</script>) })
|
||||
|
||||
content = @site.reload.content_types.first.contents.first
|
||||
entry = @site.reload.content_types.first.entries.first
|
||||
|
||||
content.name.should == "Hacking alert(\"You have been hacked\")"
|
||||
entry.name.should == "Hacking alert(\"You have been hacked\")"
|
||||
end
|
||||
|
||||
it 'sanitizes the params (more complex example)' do
|
||||
post 'create', default_post_params(:content => { :name => %(<img src=javascript:alert('Hello')><table background="javascript:alert('Hello')">Hacked) })
|
||||
post 'create', default_post_params(:content_entry => { :name => %(<img src=javascript:alert('Hello')><table background="javascript:alert('Hello')">Hacked) })
|
||||
|
||||
content = @site.reload.content_types.first.contents.first
|
||||
entry = @site.reload.content_types.first.entries.first
|
||||
|
||||
content.name.should == "Hacked"
|
||||
entry.name.should == "Hacked"
|
||||
end
|
||||
|
||||
it 'does not sanitize non string params' do
|
||||
lambda {
|
||||
post 'create', default_post_params(:content => {
|
||||
post 'create', default_post_params(:content_entry => {
|
||||
:active => true,
|
||||
:file => ActionDispatch::Http::UploadedFile.new(:tempfile => FixturedAsset.open('5k.png'), :filename => '5k.png', :content_type => 'image/png')
|
||||
})
|
||||
@ -82,7 +82,7 @@ describe Locomotive::ApiContentsController do
|
||||
def default_post_params(options = {})
|
||||
{
|
||||
:slug => 'projects',
|
||||
:content => { :name => 'LocomotiveCMS', :description => 'Lorem ipsum' }.merge(options.delete(:content) || {}),
|
||||
:content_entry => { :name => 'LocomotiveCMS', :description => 'Lorem ipsum' }.merge(options.delete(:content_entry) || {}),
|
||||
:success_callback => 'http://www.locomotivecms.com/success',
|
||||
:error_callback => 'http://www.locomotivecms.com/failure'
|
||||
}.merge(options)
|
||||
|
@ -8,18 +8,18 @@ describe Locomotive::Export do
|
||||
site = FactoryGirl.build('another site')
|
||||
Locomotive::Site.stubs(:find).returns(site)
|
||||
project_type = build_project_type(site)
|
||||
project_type.contents.build(:title => 'Project #1', :description => 'Lorem ipsum', :active => true)
|
||||
project_type.contents.build(:title => 'Project #2', :description => 'More Lorem ipsum', :active => false)
|
||||
project_type.entries.build(:title => 'Project #1', :description => 'Lorem ipsum', :active => true)
|
||||
project_type.entries.build(:title => 'Project #2', :description => 'More Lorem ipsum', :active => false)
|
||||
|
||||
team_type = build_team_type(site, project_type)
|
||||
team_type.contents.build(:name => 'Ben', :projects => project_type.contents, :current_project => project_type.contents.first)
|
||||
team_type.contents.build(:name => 'Zach', :current_project => project_type.contents.last)
|
||||
team_type.entries.build(:name => 'Ben', :projects => project_type.entries, :current_project => project_type.entries.first)
|
||||
team_type.entries.build(:name => 'Zach', :current_project => project_type.entries.last)
|
||||
|
||||
@project_data = ::Locomotive::Export.new(site).send(:extract_contents, project_type)
|
||||
@team_data = ::Locomotive::Export.new(site).send(:extract_contents, team_type)
|
||||
end
|
||||
|
||||
it 'includes the exact number of contents' do
|
||||
it 'includes the exact number of entries' do
|
||||
@project_data.size.should == 2
|
||||
@project_data.collect { |n| n.keys.first }.should == ['Project #1', 'Project #2']
|
||||
end
|
||||
@ -41,9 +41,9 @@ describe Locomotive::Export do
|
||||
|
||||
def build_project_type(site)
|
||||
FactoryGirl.build(:content_type, :site => site, :highlighted_field_name => 'custom_field_1').tap do |content_type|
|
||||
content_type.contents_custom_fields.build :label => 'Title', :_alias => 'title', :kind => 'string'
|
||||
content_type.contents_custom_fields.build :label => 'My Description', :_alias => 'description', :kind => 'text'
|
||||
content_type.contents_custom_fields.build :label => 'Active', :kind => 'boolean'
|
||||
content_type.entries_custom_fields.build :label => 'Title', :name => 'title', :type => 'string'
|
||||
content_type.entries_custom_fields.build :label => 'My Description', :name => 'description', :type => 'text'
|
||||
content_type.entries_custom_fields.build :label => 'Active', :type => 'boolean'
|
||||
end
|
||||
end
|
||||
|
||||
@ -51,10 +51,10 @@ describe Locomotive::Export do
|
||||
Object.send(:remove_const, 'TestProject') rescue nil
|
||||
klass = Object.const_set('TestProject', Class.new { def self.embedded?; false; end })
|
||||
content_type = FactoryGirl.build(:content_type, :site => site, :name => 'team', :highlighted_field_name => 'custom_field_1')
|
||||
content_type.contents_custom_fields.build :label => 'Name', :_alias => 'name', :kind => 'string'
|
||||
content_type.contents_custom_fields.build :label => 'Projects', :kind => 'has_many', :_alias => 'projects', :target => 'TestProject'
|
||||
content_type.contents_custom_fields.build :label => 'Bio', :_alias => 'bio', :kind => 'text'
|
||||
content_type.contents_custom_fields.build :label => 'Current Project', :kind => 'has_one', :_alias => 'current_project', :target => 'TestProject'
|
||||
content_type.entries_custom_fields.build :label => 'Name', :name => 'name', :type => 'string'
|
||||
content_type.entries_custom_fields.build :label => 'Projects', :type => 'has_many', :name => 'projects', :target => 'TestProject'
|
||||
content_type.entries_custom_fields.build :label => 'Bio', :name => 'bio', :type => 'text'
|
||||
content_type.entries_custom_fields.build :label => 'Current Project', :type => 'has_one', :name => 'current_project', :target => 'TestProject'
|
||||
content_type
|
||||
end
|
||||
|
||||
|
@ -22,12 +22,12 @@ describe Locomotive::Import::Job do
|
||||
it 'adds content types' do
|
||||
@site.content_types.count.should == 4
|
||||
content_type = @site.content_types.where(:slug => 'projects').first
|
||||
content_type.contents_custom_fields.size.should == 9
|
||||
content_type.entries_custom_fields.size.should == 9
|
||||
end
|
||||
|
||||
it 'replaces the target and the reverse_lookup values by the correct ones in a has_many relationship' do
|
||||
content_type = @site.content_types.where(:slug => 'clients').first
|
||||
field = content_type.contents_custom_fields.last
|
||||
field = content_type.entries_custom_fields.last
|
||||
field.target.should match /^ContentContentType/
|
||||
field.reverse_lookup.should == 'custom_field_8'
|
||||
end
|
||||
@ -44,9 +44,9 @@ describe Locomotive::Import::Job do
|
||||
|
||||
it 'adds samples coming with content types' do
|
||||
content_type = @site.content_types.where(:slug => 'projects').first
|
||||
content_type.contents.size.should == 5
|
||||
content_type.entries.size.should == 5
|
||||
|
||||
content = content_type.contents.first
|
||||
content = content_type.entries.first
|
||||
content._permalink.should == 'locomotivecms'
|
||||
content.seo_title.should == 'My open source CMS'
|
||||
content.meta_description.should == 'bla bla bla'
|
||||
|
@ -5,9 +5,9 @@ describe Locomotive::Liquid::Drops::Content do
|
||||
before(:each) do
|
||||
@site = FactoryGirl.build(:site)
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
content_type.contents_custom_fields.build :label => 'anything', :kind => 'string'
|
||||
content_type.contents_custom_fields.build :label => 'published_at', :kind => 'date'
|
||||
@content = content_type.contents.build({
|
||||
content_type.entries_custom_fields.build :label => 'anything', :type => 'string'
|
||||
content_type.entries_custom_fields.build :label => 'published_at', :type => 'date'
|
||||
@content = content_type.entries.build({
|
||||
:meta_keywords => 'Libidinous, Angsty',
|
||||
:meta_description => "Quite the combination.",
|
||||
:published_at => Date.today })
|
||||
|
@ -14,9 +14,9 @@ describe Locomotive::Liquid::Drops::Contents do
|
||||
|
||||
describe '#group_by' do
|
||||
|
||||
it 'orders contents' do
|
||||
it 'orders entries' do
|
||||
@site.content_types.stubs(:where).returns([@content_type])
|
||||
@content_type.contents.klass.expects(:group_by_category).with(:ordered_contents)
|
||||
@content_type.entries.klass.expects(:group_by_select_option).with(:ordered_entries)
|
||||
render_template '{% for group in contents.projects.group_by_category %} {{ group.name }} {% endfor %}'
|
||||
end
|
||||
|
||||
@ -52,9 +52,9 @@ describe Locomotive::Liquid::Drops::Contents do
|
||||
|
||||
def populate_content_type
|
||||
@content_type.order_by = :_slug
|
||||
@content_type.contents.build(:_slug => 'item1')
|
||||
@content_type.contents.build(:_slug => 'item2')
|
||||
@content_type.contents.build(:_slug => 'item3')
|
||||
@content_type.entries.build(:_slug => 'item1')
|
||||
@content_type.entries.build(:_slug => 'item2')
|
||||
@content_type.entries.build(:_slug => 'item3')
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -73,18 +73,18 @@ describe Locomotive::Liquid::Drops::Page do
|
||||
it 'renders the content instance highlighted field instead for a templatized page' do
|
||||
templatized = FactoryGirl.build(:page, :title => 'Lorem ipsum template', :templatized => true)
|
||||
|
||||
content_instance = Locomotive::Liquid::Drops::Content.new(mock('content_instance', :highlighted_field_value => 'Locomotive rocks !'))
|
||||
content_entry = Locomotive::Liquid::Drops::Content.new(mock('content_entry', :highlighted_field_value => 'Locomotive rocks !'))
|
||||
|
||||
render_template('{{ page.title }}', 'page' => templatized, 'content_instance' => content_instance).should == 'Locomotive rocks !'
|
||||
render_template('{{ page.title }}', 'page' => templatized, 'content_entry' => content_entry).should == 'Locomotive rocks !'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
describe 'published?' do
|
||||
subject { render_template('{{ home.published? }}') }
|
||||
it { should == @home.published?.to_s }
|
||||
end
|
||||
|
||||
|
||||
describe 'listed?' do
|
||||
subject { render_template('{{ home.listed? }}') }
|
||||
it { should == @home.listed?.to_s }
|
||||
|
@ -81,32 +81,32 @@ describe Locomotive::Liquid::Tags::SEO do
|
||||
|
||||
let(:content_type) do
|
||||
FactoryGirl.build(:content_type, :site => site).tap do |ct|
|
||||
ct.contents_custom_fields.build :label => 'anything', :kind => 'String'
|
||||
ct.entries_custom_fields.build :label => 'anything', :type => 'String'
|
||||
end
|
||||
end
|
||||
|
||||
context "has seo title" do
|
||||
let(:content) { content_type.contents.build(:seo_title => 'Content title (SEO)', :meta_keywords => 'Libidinous, Angsty', :meta_description => "Quite the combination.") }
|
||||
subject { render_seo_title('content_instance' => content) }
|
||||
let(:content_entry) { content_type.entries.build(:seo_title => 'Content title (SEO)', :meta_keywords => 'Libidinous, Angsty', :meta_description => "Quite the combination.") }
|
||||
subject { render_seo_title('content_entry' => content_entry) }
|
||||
it { should include(%Q[<title>Content title (SEO)</title>]) }
|
||||
end
|
||||
|
||||
context "does not have seo title" do
|
||||
let(:content) { content_type.contents.build }
|
||||
subject { render_seo_title('content_instance' => content) }
|
||||
let(:content_entry) { content_type.entries.build }
|
||||
subject { render_seo_title('content_entry' => content_entry) }
|
||||
it { should include(%Q[<title>Site title (SEO)</title>]) }
|
||||
end
|
||||
|
||||
context "has metadata" do
|
||||
let(:content) { content_type.contents.build(:meta_keywords => 'Libidinous, Angsty', :meta_description => "Quite the combination.") }
|
||||
subject { render_seo_metadata('content_instance' => content) }
|
||||
it { should include(%Q[<meta name="keywords" content="#{content.meta_keywords}" />]) }
|
||||
it { should include(%Q[<meta name="description" content="#{content.meta_description}" />]) }
|
||||
let(:content_entry) { content_type.entries.build(:meta_keywords => 'Libidinous, Angsty', :meta_description => "Quite the combination.") }
|
||||
subject { render_seo_metadata('content_entry' => content_entry) }
|
||||
it { should include(%Q[<meta name="keywords" content="#{content_entry.meta_keywords}" />]) }
|
||||
it { should include(%Q[<meta name="description" content="#{content_entry.meta_description}" />]) }
|
||||
end
|
||||
|
||||
context "does not have metadata" do
|
||||
let(:content) { content_type.contents.build }
|
||||
subject { render_seo_metadata('content_instance' => content) }
|
||||
let(:content_entry) { content_type.entries.build }
|
||||
subject { render_seo_metadata('content_entry' => content_entry) }
|
||||
it { should include(%Q[<meta name="keywords" content="#{site.meta_keywords}" />]) }
|
||||
it { should include(%Q[<meta name="description" content="#{site.meta_description}" />]) }
|
||||
end
|
||||
|
@ -126,30 +126,30 @@ describe 'Locomotive rendering system' do
|
||||
|
||||
before(:each) do
|
||||
@content_type = FactoryGirl.build(:content_type, :site => nil)
|
||||
@content = @content_type.contents.build(:_visible => true)
|
||||
@content_entry = @content_type.entries.build(:_visible => true)
|
||||
@page.templatized = true
|
||||
@page.content_type = @content_type
|
||||
@controller.request.fullpath = '/projects/edeneo.html'
|
||||
@controller.current_site.pages.expects(:any_in).with({ :fullpath => %w{projects/edeneo projects/content_type_template} }).returns([@page])
|
||||
end
|
||||
|
||||
it 'sets the content_instance variable' do
|
||||
@content_type.contents.stubs(:where).returns([@content])
|
||||
it 'sets the content_entry variable' do
|
||||
@content_type.entries.stubs(:where).returns([@content_entry])
|
||||
@controller.send(:locomotive_page).should_not be_nil
|
||||
@controller.instance_variable_get(:@content_instance).should == @content
|
||||
@controller.instance_variable_get(:@content_entry).should == @content_entry
|
||||
end
|
||||
|
||||
it 'returns the 404 page if the instance does not exist' do
|
||||
@content_type.contents.stubs(:where).returns([])
|
||||
@content_type.entries.stubs(:where).returns([])
|
||||
(klass = Locomotive::Page).expects(:published).returns([true])
|
||||
@controller.current_site.pages.expects(:not_found).returns(klass)
|
||||
@controller.send(:locomotive_page).should be_true
|
||||
@controller.instance_variable_get(:@content_instance).should be_nil
|
||||
@controller.instance_variable_get(:@content_entry).should be_nil
|
||||
end
|
||||
|
||||
it 'returns the 404 page if the instance is not visible' do
|
||||
@content._visible = false
|
||||
@content_type.contents.stubs(:where).returns([@content])
|
||||
@content_entry._visible = false
|
||||
@content_type.entries.stubs(:where).returns([@content_entry])
|
||||
(klass = Locomotive::Page).expects(:published).returns([true])
|
||||
@controller.current_site.pages.expects(:not_found).returns(klass)
|
||||
@controller.send(:locomotive_page).should be_true
|
||||
|
@ -33,7 +33,7 @@ describe Locomotive::Ability do
|
||||
|
||||
context 'content instance' do
|
||||
|
||||
subject { Locomotive::ContentInstance.new }
|
||||
subject { Locomotive::ContentEntry.new }
|
||||
|
||||
context 'management' do
|
||||
it 'should allow management of pages from (admin, designer, author)' do
|
||||
|
209
spec/models/locomotive/content_entry_spec.rb
Normal file
209
spec/models/locomotive/content_entry_spec.rb
Normal file
@ -0,0 +1,209 @@
|
||||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Locomotive::ContentEntry do
|
||||
|
||||
before(:each) do
|
||||
Locomotive::Site.any_instance.stubs(:create_default_pages!).returns(true)
|
||||
@content_type = FactoryGirl.build(:content_type)
|
||||
@content_type.entries_custom_fields.build :label => 'Title', :type => 'String'
|
||||
@content_type.entries_custom_fields.build :label => 'Description', :type => 'Text'
|
||||
@content_type.entries_custom_fields.build :label => 'Visible ?', :type => 'Text', :name => 'visible'
|
||||
@content_type.highlighted_field_name = 'custom_field_1'
|
||||
end
|
||||
|
||||
describe '#validation' do
|
||||
it 'is valid' do
|
||||
build_content_entry.should be_valid
|
||||
end
|
||||
|
||||
## Validations ##
|
||||
|
||||
it 'requires the presence of title' do
|
||||
content_entry = build_content_entry_entry :title => nil
|
||||
content_entry.should_not be_valid
|
||||
content_entry.errors[:title].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
it 'requires the presence of the permalink (_slug)' do
|
||||
content_entry = build_content_entry_entry :title => nil
|
||||
content_entry.should_not be_valid
|
||||
content_entry.errors[:_slug].should == ["can't be blank"]
|
||||
end
|
||||
end
|
||||
|
||||
context 'setting the slug' do
|
||||
before :each do
|
||||
build_content_entry(:_slug => 'dogs').tap(&:save!)._slug.should == 'dogs'
|
||||
end
|
||||
|
||||
it 'uses the given slug if it is unique' do
|
||||
build_content_entry(:_slug => 'monkeys').tap(&:save!)._slug.should == 'monkeys'
|
||||
build_content_entry(:_slug => 'cats-2').tap(&:save!)._slug.should == 'cats-2'
|
||||
end
|
||||
|
||||
it 'appends a number to the end of the slug if it is not unique' do
|
||||
build_content_entry(:_slug => 'dogs').tap(&:save!)._slug.should == 'dogs-1'
|
||||
build_content_entry(:_slug => 'dogs').tap(&:save!)._slug.should == 'dogs-2'
|
||||
build_content_entry(:_slug => 'dogs-2').tap(&:save!)._slug.should == 'dogs-3'
|
||||
build_content_entry(:_slug => 'dogs-2').tap(&:save!)._slug.should == 'dogs-4'
|
||||
end
|
||||
|
||||
it 'ignores the case of a slug' do
|
||||
build_content_entry(:_slug => 'dogs').tap(&:save!)._slug.should == 'dogs-1'
|
||||
build_content_entry(:_slug => 'DOGS').tap(&:save!)._slug.should == 'dogs-2'
|
||||
end
|
||||
|
||||
it 'correctly handles slugs with multiple numbers' do
|
||||
build_content_entry(:_slug => 'fish-1-2').tap(&:save!)._slug.should == 'fish-1-2'
|
||||
build_content_entry(:_slug => 'fish-1-2').tap(&:save!)._slug.should == 'fish-1-3'
|
||||
|
||||
build_content_entry(:_slug => 'fish-1-hi').tap(&:save!)._slug.should == 'fish-1-hi'
|
||||
build_content_entry(:_slug => 'fish-1-hi').tap(&:save!)._slug.should == 'fish-1-hi-1'
|
||||
end
|
||||
end
|
||||
|
||||
describe "#navigation" do
|
||||
before(:each) do
|
||||
%w(first second third).each_with_index do |item,index|
|
||||
content = build_content_entry({:title => item.to_s})
|
||||
content._position_in_list = index
|
||||
instance_variable_set "@#{item}", content
|
||||
end
|
||||
end
|
||||
|
||||
it 'should find previous item when available' do
|
||||
@second.previous.custom_field_1.should == "first"
|
||||
@second.previous._position_in_list.should == 0
|
||||
end
|
||||
|
||||
it 'should find next item when available' do
|
||||
@second.next.custom_field_1.should == "third"
|
||||
@second.next._position_in_list.should == 2
|
||||
end
|
||||
|
||||
it 'should return nil when fetching previous item on first in list' do
|
||||
@first.previous.should == nil
|
||||
end
|
||||
|
||||
it 'should return nil when fetching next item on last in list' do
|
||||
@third.next.should == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#permalink' do
|
||||
|
||||
before(:each) do
|
||||
@content_entry = build_content_entry
|
||||
end
|
||||
|
||||
it 'has a default value based on the highlighted field' do
|
||||
@content_entry.send(:set_slug)
|
||||
@content_entry._permalink.should == 'locomotive'
|
||||
end
|
||||
|
||||
it 'is empty if no value for the highlighted field is provided' do
|
||||
@content_entry.title = nil; @content_entry.send(:set_slug)
|
||||
@content_entry._permalink.should be_nil
|
||||
end
|
||||
|
||||
it 'includes dashes instead of white spaces' do
|
||||
@content_entry.title = 'my content instance'; @content_entry.send(:set_slug)
|
||||
@content_entry._permalink.should == 'my-content-instance'
|
||||
end
|
||||
|
||||
it 'removes accentued characters' do
|
||||
@content_entry.title = "une chèvre dans le pré"; @content_entry.send(:set_slug)
|
||||
@content_entry._permalink.should == 'une-chevre-dans-le-pre'
|
||||
end
|
||||
|
||||
it 'removes dots' do
|
||||
@content_entry.title = "my.test"; @content_entry.send(:set_slug)
|
||||
@content_entry._permalink.should == 'my-test'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#visibility' do
|
||||
|
||||
before(:each) do
|
||||
@content_entry = build_content_entry
|
||||
end
|
||||
|
||||
it 'is visible by default' do
|
||||
@content_entry._visible?.should be_true
|
||||
@content_entry.visible?.should be_true
|
||||
end
|
||||
|
||||
it 'can be visible even if it is nil' do
|
||||
@content_entry.visible = nil
|
||||
@content_entry.send(:set_visibility)
|
||||
@content_entry.visible?.should be_true
|
||||
end
|
||||
|
||||
it 'can not be visible' do
|
||||
@content_entry.visible = false
|
||||
@content_entry.send(:set_visibility)
|
||||
@content_entry.visible?.should be_false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#requirements' do
|
||||
|
||||
it 'has public access to the highlighted field value' do
|
||||
build_content_entry.highlighted_field_value.should == 'Locomotive'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#api' do
|
||||
|
||||
before(:each) do
|
||||
@account_1 = FactoryGirl.build('admin user', :id => fake_bson_id('1'))
|
||||
@account_2 = FactoryGirl.build('frenchy user', :id => fake_bson_id('2'))
|
||||
|
||||
@content_type.api_enabled = true
|
||||
@content_type.api_accounts = ['', @account_1.id, @account_2.id]
|
||||
|
||||
Locomotive::Site.any_instance.stubs(:accounts).returns([@account_1, @account_2])
|
||||
|
||||
@content_entry = build_content_entry
|
||||
end
|
||||
|
||||
it 'does not send email notifications if the api is disabled' do
|
||||
@content_type.api_enabled = false
|
||||
Locomotive::Notifications.expects(:new_content_entry).never
|
||||
@content_entry.save
|
||||
end
|
||||
|
||||
it 'does not send email notifications if no api accounts' do
|
||||
@content_type.api_accounts = nil
|
||||
Locomotive::Notifications.expects(:new_content_entry).never
|
||||
@content_entry.save
|
||||
end
|
||||
|
||||
it 'sends email notifications when a new instance is created' do
|
||||
Locomotive::Notifications.expects(:new_content_entry).with(@account_1, @content).returns(mock('mailer', :deliver => true))
|
||||
Locomotive::Notifications.expects(:new_content_entry).with(@account_2, @content).returns(mock('mailer', :deliver => true))
|
||||
@content_entry.save
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#site' do
|
||||
it 'delegates to the content type' do
|
||||
@content_type.expects(:site)
|
||||
build_content_entry.site
|
||||
end
|
||||
end
|
||||
|
||||
def build_content_entry(options = {})
|
||||
@content_type.entries.build({ :title => 'Locomotive', :description => 'Lorem ipsum....' }.merge(options))
|
||||
end
|
||||
|
||||
def fake_bson_id(id)
|
||||
BSON::ObjectId(id.to_s.rjust(24, '0'))
|
||||
end
|
||||
end
|
@ -1,209 +0,0 @@
|
||||
# encoding: utf-8
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Locomotive::ContentInstance do
|
||||
|
||||
before(:each) do
|
||||
Locomotive::Site.any_instance.stubs(:create_default_pages!).returns(true)
|
||||
@content_type = FactoryGirl.build(:content_type)
|
||||
@content_type.contents_custom_fields.build :label => 'Title', :kind => 'String'
|
||||
@content_type.contents_custom_fields.build :label => 'Description', :kind => 'Text'
|
||||
@content_type.contents_custom_fields.build :label => 'Visible ?', :kind => 'Text', :_alias => 'visible'
|
||||
@content_type.highlighted_field_name = 'custom_field_1'
|
||||
end
|
||||
|
||||
describe '#validation' do
|
||||
it 'is valid' do
|
||||
build_content.should be_valid
|
||||
end
|
||||
|
||||
## Validations ##
|
||||
|
||||
it 'requires the presence of title' do
|
||||
content = build_content :title => nil
|
||||
content.should_not be_valid
|
||||
content.errors[:title].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
it 'requires the presence of the permalink (_slug)' do
|
||||
content = build_content :title => nil
|
||||
content.should_not be_valid
|
||||
content.errors[:_slug].should == ["can't be blank"]
|
||||
end
|
||||
end
|
||||
|
||||
context 'setting the slug' do
|
||||
before :each do
|
||||
build_content(:_slug => 'dogs').tap(&:save!)._slug.should == 'dogs'
|
||||
end
|
||||
|
||||
it 'uses the given slug if it is unique' do
|
||||
build_content(:_slug => 'monkeys').tap(&:save!)._slug.should == 'monkeys'
|
||||
build_content(:_slug => 'cats-2').tap(&:save!)._slug.should == 'cats-2'
|
||||
end
|
||||
|
||||
it 'appends a number to the end of the slug if it is not unique' do
|
||||
build_content(:_slug => 'dogs').tap(&:save!)._slug.should == 'dogs-1'
|
||||
build_content(:_slug => 'dogs').tap(&:save!)._slug.should == 'dogs-2'
|
||||
build_content(:_slug => 'dogs-2').tap(&:save!)._slug.should == 'dogs-3'
|
||||
build_content(:_slug => 'dogs-2').tap(&:save!)._slug.should == 'dogs-4'
|
||||
end
|
||||
|
||||
it 'ignores the case of a slug' do
|
||||
build_content(:_slug => 'dogs').tap(&:save!)._slug.should == 'dogs-1'
|
||||
build_content(:_slug => 'DOGS').tap(&:save!)._slug.should == 'dogs-2'
|
||||
end
|
||||
|
||||
it 'correctly handles slugs with multiple numbers' do
|
||||
build_content(:_slug => 'fish-1-2').tap(&:save!)._slug.should == 'fish-1-2'
|
||||
build_content(:_slug => 'fish-1-2').tap(&:save!)._slug.should == 'fish-1-3'
|
||||
|
||||
build_content(:_slug => 'fish-1-hi').tap(&:save!)._slug.should == 'fish-1-hi'
|
||||
build_content(:_slug => 'fish-1-hi').tap(&:save!)._slug.should == 'fish-1-hi-1'
|
||||
end
|
||||
end
|
||||
|
||||
describe "#navigation" do
|
||||
before(:each) do
|
||||
%w(first second third).each_with_index do |item,index|
|
||||
content = build_content({:title => item.to_s})
|
||||
content._position_in_list = index
|
||||
instance_variable_set "@#{item}", content
|
||||
end
|
||||
end
|
||||
|
||||
it 'should find previous item when available' do
|
||||
@second.previous.custom_field_1.should == "first"
|
||||
@second.previous._position_in_list.should == 0
|
||||
end
|
||||
|
||||
it 'should find next item when available' do
|
||||
@second.next.custom_field_1.should == "third"
|
||||
@second.next._position_in_list.should == 2
|
||||
end
|
||||
|
||||
it 'should return nil when fetching previous item on first in list' do
|
||||
@first.previous.should == nil
|
||||
end
|
||||
|
||||
it 'should return nil when fetching next item on last in list' do
|
||||
@third.next.should == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#permalink' do
|
||||
|
||||
before(:each) do
|
||||
@content = build_content
|
||||
end
|
||||
|
||||
it 'has a default value based on the highlighted field' do
|
||||
@content.send(:set_slug)
|
||||
@content._permalink.should == 'locomotive'
|
||||
end
|
||||
|
||||
it 'is empty if no value for the highlighted field is provided' do
|
||||
@content.title = nil; @content.send(:set_slug)
|
||||
@content._permalink.should be_nil
|
||||
end
|
||||
|
||||
it 'includes dashes instead of white spaces' do
|
||||
@content.title = 'my content instance'; @content.send(:set_slug)
|
||||
@content._permalink.should == 'my-content-instance'
|
||||
end
|
||||
|
||||
it 'removes accentued characters' do
|
||||
@content.title = "une chèvre dans le pré"; @content.send(:set_slug)
|
||||
@content._permalink.should == 'une-chevre-dans-le-pre'
|
||||
end
|
||||
|
||||
it 'removes dots' do
|
||||
@content.title = "my.test"; @content.send(:set_slug)
|
||||
@content._permalink.should == 'my-test'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#visibility' do
|
||||
|
||||
before(:each) do
|
||||
@content = build_content
|
||||
end
|
||||
|
||||
it 'is visible by default' do
|
||||
@content._visible?.should be_true
|
||||
@content.visible?.should be_true
|
||||
end
|
||||
|
||||
it 'can be visible even if it is nil' do
|
||||
@content.visible = nil
|
||||
@content.send(:set_visibility)
|
||||
@content.visible?.should be_true
|
||||
end
|
||||
|
||||
it 'can not be visible' do
|
||||
@content.visible = false
|
||||
@content.send(:set_visibility)
|
||||
@content.visible?.should be_false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#requirements' do
|
||||
|
||||
it 'has public access to the highlighted field value' do
|
||||
build_content.highlighted_field_value.should == 'Locomotive'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#api' do
|
||||
|
||||
before(:each) do
|
||||
@account_1 = FactoryGirl.build('admin user', :id => fake_bson_id('1'))
|
||||
@account_2 = FactoryGirl.build('frenchy user', :id => fake_bson_id('2'))
|
||||
|
||||
@content_type.api_enabled = true
|
||||
@content_type.api_accounts = ['', @account_1.id, @account_2.id]
|
||||
|
||||
Locomotive::Site.any_instance.stubs(:accounts).returns([@account_1, @account_2])
|
||||
|
||||
@content = build_content
|
||||
end
|
||||
|
||||
it 'does not send email notifications if the api is disabled' do
|
||||
@content_type.api_enabled = false
|
||||
Locomotive::Notifications.expects(:new_content_instance).never
|
||||
@content.save
|
||||
end
|
||||
|
||||
it 'does not send email notifications if no api accounts' do
|
||||
@content_type.api_accounts = nil
|
||||
Locomotive::Notifications.expects(:new_content_instance).never
|
||||
@content.save
|
||||
end
|
||||
|
||||
it 'sends email notifications when a new instance is created' do
|
||||
Locomotive::Notifications.expects(:new_content_instance).with(@account_1, @content).returns(mock('mailer', :deliver => true))
|
||||
Locomotive::Notifications.expects(:new_content_instance).with(@account_2, @content).returns(mock('mailer', :deliver => true))
|
||||
@content.save
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '#site' do
|
||||
it 'delegates to the content type' do
|
||||
@content_type.expects(:site)
|
||||
build_content.site
|
||||
end
|
||||
end
|
||||
|
||||
def build_content(options = {})
|
||||
@content_type.contents.build({ :title => 'Locomotive', :description => 'Lorem ipsum....' }.merge(options))
|
||||
end
|
||||
|
||||
def fake_bson_id(id)
|
||||
BSON::ObjectId(id.to_s.rjust(24, '0'))
|
||||
end
|
||||
end
|
@ -10,7 +10,7 @@ describe Locomotive::ContentType do
|
||||
|
||||
it 'should have a valid factory' do
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
content_type.contents_custom_fields.build :label => 'anything', :kind => 'String'
|
||||
content_type.entries_custom_fields.build :label => 'anything', :type => 'String'
|
||||
content_type.should be_valid
|
||||
end
|
||||
|
||||
@ -32,7 +32,7 @@ describe Locomotive::ContentType do
|
||||
|
||||
it 'is not valid if slug is not unique' do
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
content_type.contents_custom_fields.build :label => 'anything', :kind => 'String'
|
||||
content_type.entries_custom_fields.build :label => 'anything', :type => 'String'
|
||||
content_type.save
|
||||
(content_type = FactoryGirl.build(:content_type, :site => content_type.site)).should_not be_valid
|
||||
content_type.errors[:slug].should == ["is already taken"]
|
||||
@ -41,27 +41,27 @@ describe Locomotive::ContentType do
|
||||
it 'is not valid if there is not at least one field' do
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
content_type.should_not be_valid
|
||||
content_type.errors[:contents_custom_fields].should == ["is too small (minimum element number is 1)"]
|
||||
content_type.errors[:entries_custom_fields].should == ["is too small (minimum element number is 1)"]
|
||||
end
|
||||
|
||||
%w(created_at updated_at).each do |_alias|
|
||||
it "does not allow #{_alias} as alias" do
|
||||
%w(created_at updated_at).each do |name|
|
||||
it "does not allow #{name} as name" do
|
||||
content_type = FactoryGirl.build(:content_type)
|
||||
field = content_type.contents_custom_fields.build :label => 'anything', :kind => 'String', :_alias => _alias
|
||||
field = content_type.entries_custom_fields.build :label => 'anything', :type => 'String', :name => name
|
||||
field.valid?.should be_false
|
||||
field.errors[:_alias].should == ['is reserved']
|
||||
field.errors[:name].should == ['is reserved']
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context '#ordered_contents' do
|
||||
context '#ordered_entries' do
|
||||
|
||||
before(:each) do
|
||||
@content_type = FactoryGirl.build(:content_type, :order_by => 'created_at')
|
||||
@content_1 = stub('content_1', :name => 'Did', :_position_in_list => 2)
|
||||
@content_2 = stub('content_2', :name => 'Sacha', :_position_in_list => 1)
|
||||
@content_type.stubs(:contents).returns([@content_1, @content_2])
|
||||
@content_type.stubs(:entries).returns([@content_1, @content_2])
|
||||
end
|
||||
|
||||
it 'orders with the ASC direction by default' do
|
||||
@ -74,34 +74,34 @@ describe Locomotive::ContentType do
|
||||
@content_type.order_manually?.should == true
|
||||
end
|
||||
|
||||
it 'returns a list of contents ordered manually' do
|
||||
it 'returns a list of entries ordered manually' do
|
||||
@content_type.order_by = '_position_in_list'
|
||||
@content_type.ordered_contents.collect(&:name).should == %w(Sacha Did)
|
||||
@content_type.ordered_entries.collect(&:name).should == %w(Sacha Did)
|
||||
end
|
||||
|
||||
it 'returns a list of contents ordered by a column specified by order_by (ASC)' do
|
||||
it 'returns a list of entries ordered by a column specified by order_by (ASC)' do
|
||||
@content_type.order_by = 'name'
|
||||
@content_type.ordered_contents.collect(&:name).should == %w(Did Sacha)
|
||||
@content_type.ordered_entries.collect(&:name).should == %w(Did Sacha)
|
||||
end
|
||||
|
||||
it 'returns a list of contents ordered by a column specified by order_by (DESC)' do
|
||||
it 'returns a list of entries ordered by a column specified by order_by (DESC)' do
|
||||
@content_type.order_by = 'name'
|
||||
@content_type.order_direction = 'desc'
|
||||
@content_type.ordered_contents.collect(&:name).should == %w(Sacha Did)
|
||||
@content_type.ordered_entries.collect(&:name).should == %w(Sacha Did)
|
||||
end
|
||||
|
||||
it 'returns a list of contents ordered by a Date column when first instance is missing the value' do
|
||||
|
||||
it 'returns a list of entries ordered by a Date column when first instance is missing the value' do
|
||||
@content_type = FactoryGirl.build(:content_type, :order_by => 'created_at')
|
||||
@content_type.content_custom_fields.build :label => 'Active at', :name => 'active_at', :kind => 'Date'
|
||||
@content_type.content_custom_fields.build :label => 'Active at', :name => 'active_at', :type => 'Date'
|
||||
e = Date.parse('01/01/2001')
|
||||
l = Date.parse('02/02/2002')
|
||||
[nil,e,l].each { |d| @content_type.contents << @content_type.content_klass.new(:active_at => d) }
|
||||
[nil,e,l].each { |d| @content_type.entries << @content_type.content_klass.new(:active_at => d) }
|
||||
@content_type.order_by = 'active_at'
|
||||
@content_type.order_direction = 'asc'
|
||||
lambda { @content_type.ordered_contents }.should_not raise_error(ArgumentError)
|
||||
@content_type.ordered_contents.map(&:active_at).should == [nil,e,l]
|
||||
lambda { @content_type.ordered_entries }.should_not raise_error(ArgumentError)
|
||||
@content_type.ordered_entries.map(&:active_at).should == [nil,e,l]
|
||||
@content_type.order_direction = 'desc'
|
||||
@content_type.ordered_contents.map(&:active_at).should == [l,e,nil]
|
||||
@content_type.ordered_entries.map(&:active_at).should == [l,e,nil]
|
||||
end
|
||||
|
||||
end
|
||||
@ -112,8 +112,8 @@ describe Locomotive::ContentType do
|
||||
site = FactoryGirl.build(:site)
|
||||
Locomotive::Site.stubs(:find).returns(site)
|
||||
@content_type = FactoryGirl.build(:content_type, :site => site, :highlighted_field_name => 'custom_field_1')
|
||||
@content_type.contents_custom_fields.build :label => 'My Description', :_alias => 'description', :kind => 'text'
|
||||
@content_type.contents_custom_fields.build :label => 'Active', :kind => 'boolean'
|
||||
@content_type.entries_custom_fields.build :label => 'My Description', :name => 'description', :type => 'text'
|
||||
@content_type.entries_custom_fields.build :label => 'Active', :type => 'boolean'
|
||||
# Locomotive::ContentType.logger = Logger.new($stdout)
|
||||
# Locomotive::ContentType.db.connection.instance_variable_set(:@logger, Logger.new($stdout))
|
||||
end
|
||||
@ -121,7 +121,7 @@ describe Locomotive::ContentType do
|
||||
context 'unit' do
|
||||
|
||||
before(:each) do
|
||||
@field = CustomFields::Field.new(:kind => 'String')
|
||||
@field = CustomFields::Field.new(:type => 'String')
|
||||
end
|
||||
|
||||
it 'should tell if it is a String' do
|
||||
@ -129,7 +129,7 @@ describe Locomotive::ContentType do
|
||||
end
|
||||
|
||||
it 'should tell if it is a Text' do
|
||||
@field.kind = 'Text'
|
||||
@field.type = 'Text'
|
||||
@field.text?.should be_true
|
||||
end
|
||||
|
||||
@ -137,24 +137,24 @@ describe Locomotive::ContentType do
|
||||
|
||||
context 'validation' do
|
||||
|
||||
%w{label kind}.each do |key|
|
||||
%w{label type}.each do |key|
|
||||
it "should validate presence of #{key}" do
|
||||
field = @content_type.contents_custom_fields.build({ :label => 'Shortcut', :kind => 'String' }.merge(key.to_sym => nil))
|
||||
field = @content_type.entries_custom_fields.build({ :label => 'Shortcut', :type => 'String' }.merge(key.to_sym => nil))
|
||||
field.should_not be_valid
|
||||
field.errors[key.to_sym].should == ["can't be blank"]
|
||||
end
|
||||
end
|
||||
|
||||
it 'should not have unique label' do
|
||||
field = @content_type.contents_custom_fields.build :label => 'Active', :kind => 'Boolean'
|
||||
field = @content_type.entries_custom_fields.build :label => 'Active', :type => 'Boolean'
|
||||
field.should_not be_valid
|
||||
field.errors[:label].should == ["is already taken"]
|
||||
end
|
||||
|
||||
it 'should invalidate parent if custom field is not valid' do
|
||||
field = @content_type.contents_custom_fields.build
|
||||
field = @content_type.entries_custom_fields.build
|
||||
@content_type.should_not be_valid
|
||||
@content_type.contents_custom_fields.last.errors[:label].should == ["can't be blank"]
|
||||
@content_type.entries_custom_fields.last.errors[:label].should == ["can't be blank"]
|
||||
end
|
||||
|
||||
end
|
||||
@ -162,13 +162,13 @@ describe Locomotive::ContentType do
|
||||
context 'define core attributes' do
|
||||
|
||||
it 'should have an unique name' do
|
||||
@content_type.contents_custom_fields.first._name.should == "custom_field_1"
|
||||
@content_type.contents_custom_fields.last._name.should == "custom_field_2"
|
||||
@content_type.entries_custom_fields.first._name.should == "custom_field_1"
|
||||
@content_type.entries_custom_fields.last._name.should == "custom_field_2"
|
||||
end
|
||||
|
||||
it 'should have an unique alias' do
|
||||
@content_type.contents_custom_fields.first.safe_alias.should == "description"
|
||||
@content_type.contents_custom_fields.last.safe_alias.should == "active"
|
||||
@content_type.entries_custom_fields.first.name.should == "description"
|
||||
@content_type.entries_custom_fields.last.name.should == "active"
|
||||
end
|
||||
|
||||
end
|
||||
@ -176,7 +176,7 @@ describe Locomotive::ContentType do
|
||||
context 'build and save' do
|
||||
|
||||
it 'should build asset' do
|
||||
asset = @content_type.contents.build
|
||||
asset = @content_type.entries.build
|
||||
lambda {
|
||||
asset.description
|
||||
asset.active
|
||||
@ -185,24 +185,24 @@ describe Locomotive::ContentType do
|
||||
end
|
||||
|
||||
it 'should assign values to newly built asset' do
|
||||
asset = build_content(@content_type)
|
||||
asset = build_content_entry(@content_type)
|
||||
asset.description.should == 'Lorem ipsum'
|
||||
asset.active.should == true
|
||||
end
|
||||
|
||||
it 'should save asset' do
|
||||
asset = build_content(@content_type)
|
||||
asset = build_content_entry(@content_type)
|
||||
asset.save and @content_type.reload
|
||||
asset = @content_type.contents.first
|
||||
asset = @content_type.entries.first
|
||||
asset.description.should == 'Lorem ipsum'
|
||||
asset.active.should == true
|
||||
end
|
||||
|
||||
it 'should not modify contents from another collection' do
|
||||
asset = build_content(@content_type)
|
||||
it 'should not modify entries from another collection' do
|
||||
asset = build_content_entry(@content_type)
|
||||
asset.save and @content_type.reload
|
||||
new_collection = Locomotive::ContentType.new
|
||||
lambda { new_collection.contents.build.description }.should raise_error
|
||||
lambda { new_collection.entries.build.description }.should raise_error
|
||||
end
|
||||
|
||||
end
|
||||
@ -210,36 +210,36 @@ describe Locomotive::ContentType do
|
||||
context 'modifying fields' do
|
||||
|
||||
before(:each) do
|
||||
@asset = build_content(@content_type).save
|
||||
@asset = build_content_entry(@content_type).save
|
||||
end
|
||||
|
||||
it 'should add new field' do
|
||||
@content_type.contents_custom_fields.build :label => 'Active at', :name => 'active_at', :kind => 'Date'
|
||||
@content_type.entries_custom_fields.build :label => 'Active at', :name => 'active_at', :type => 'Date'
|
||||
@content_type.upsert(:validate => false)
|
||||
@content_type.invalidate_content_klass
|
||||
@content_type.reload
|
||||
asset = @content_type.contents.first
|
||||
asset = @content_type.entries.first
|
||||
lambda { asset.active_at }.should_not raise_error
|
||||
end
|
||||
|
||||
it 'should remove field' do
|
||||
@content_type.contents_custom_fields.clear
|
||||
@content_type.entries_custom_fields.clear
|
||||
@content_type.upsert(:validate => false)
|
||||
@content_type.invalidate_content_klass
|
||||
@content_type.reload
|
||||
asset = @content_type.contents.first
|
||||
asset = @content_type.entries.first
|
||||
lambda { asset.active_at }.should raise_error
|
||||
end
|
||||
|
||||
it 'should rename field label' do
|
||||
@content_type.contents_custom_fields.first.label = 'Simple description'
|
||||
@content_type.contents_custom_fields.first._alias = nil
|
||||
@content_type.entries_custom_fields.first.label = 'Simple description'
|
||||
@content_type.entries_custom_fields.first.name = nil
|
||||
@content_type.upsert(:validate => false)
|
||||
|
||||
@content_type.invalidate_content_klass
|
||||
@content_type.reload
|
||||
|
||||
asset = @content_type.contents.first
|
||||
asset = @content_type.entries.first
|
||||
asset.simple_description.should == 'Lorem ipsum'
|
||||
end
|
||||
|
||||
@ -248,38 +248,38 @@ describe Locomotive::ContentType do
|
||||
context 'managing from hash' do
|
||||
|
||||
it 'adds new field' do
|
||||
@content_type.contents_custom_fields.clear
|
||||
field = @content_type.contents_custom_fields.build :label => 'Title'
|
||||
@content_type.contents_custom_fields_attributes = { 0 => { :id => field.id.to_s, 'label' => 'A title', 'kind' => 'String' }, 1 => { 'label' => 'Tagline', 'kind' => 'String' } }
|
||||
@content_type.contents_custom_fields.size.should == 2
|
||||
@content_type.contents_custom_fields.first.label.should == 'A title'
|
||||
@content_type.contents_custom_fields.last.label.should == 'Tagline'
|
||||
@content_type.entries_custom_fields.clear
|
||||
field = @content_type.entries_custom_fields.build :label => 'Title'
|
||||
@content_type.entries_custom_fields_attributes = { 0 => { :id => field.id.to_s, 'label' => 'A title', 'type' => 'String' }, 1 => { 'label' => 'Tagline', 'type' => 'String' } }
|
||||
@content_type.entries_custom_fields.size.should == 2
|
||||
@content_type.entries_custom_fields.first.label.should == 'A title'
|
||||
@content_type.entries_custom_fields.last.label.should == 'Tagline'
|
||||
end
|
||||
|
||||
it 'updates/removes fields' do
|
||||
field = @content_type.contents_custom_fields.build :label => 'Title', :kind => 'String'
|
||||
field = @content_type.entries_custom_fields.build :label => 'Title', :type => 'String'
|
||||
@content_type.save; @content_type = Locomotive::ContentType.find(@content_type.id)
|
||||
@content_type.update_attributes(:contents_custom_fields_attributes => {
|
||||
'0' => { 'id' => lookup_field_id(0), 'label' => 'My Description', 'kind' => 'Text', '_destroy' => '1' },
|
||||
'1' => { 'id' => lookup_field_id(1), 'label' => 'Active', 'kind' => 'Boolean', '_destroy' => '1' },
|
||||
'2' => { 'id' => lookup_field_id(2), 'label' => 'My Title !', 'kind' => 'String' },
|
||||
'new_record' => { 'label' => 'Published at', 'kind' => 'String' }
|
||||
@content_type.update_attributes(:entries_custom_fields_attributes => {
|
||||
'0' => { 'id' => lookup_field_id(0), 'label' => 'My Description', 'type' => 'Text', '_destroy' => '1' },
|
||||
'1' => { 'id' => lookup_field_id(1), 'label' => 'Active', 'type' => 'Boolean', '_destroy' => '1' },
|
||||
'2' => { 'id' => lookup_field_id(2), 'label' => 'My Title !', 'type' => 'String' },
|
||||
'new_record' => { 'label' => 'Published at', 'type' => 'String' }
|
||||
})
|
||||
@content_type = Locomotive::ContentType.find(@content_type.id)
|
||||
@content_type.contents_custom_fields.size.should == 2
|
||||
@content_type.contents_custom_fields.first.label.should == 'My Title !'
|
||||
@content_type.entries_custom_fields.size.should == 2
|
||||
@content_type.entries_custom_fields.first.label.should == 'My Title !'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def build_content(content_type)
|
||||
content_type.contents.build(:name => 'Asset on steroids', :description => 'Lorem ipsum', :active => true)
|
||||
def build_content_entry(content_type)
|
||||
content_type.entries.build(:name => 'Asset on steroids', :description => 'Lorem ipsum', :active => true)
|
||||
end
|
||||
|
||||
def lookup_field_id(index)
|
||||
@content_type.contents_custom_fields.all[index].id.to_s
|
||||
@content_type.entries_custom_fields.all[index].id.to_s
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -138,7 +138,7 @@ FactoryGirl.define do
|
||||
site { Locomotive::Site.where(:subdomain => "acme").first || Factory(:site) }
|
||||
end
|
||||
|
||||
factory :content_instance, :class => Locomotive::ContentInstance do
|
||||
factory :content_entry, :class => Locomotive::ContentEntry do
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user