fixed editable elements (wip)
This commit is contained in:
parent
1ef1e3fbf4
commit
cfbe68564d
@ -6,13 +6,12 @@ module Locomotive
|
|||||||
## fields ##
|
## fields ##
|
||||||
field :slug
|
field :slug
|
||||||
field :block
|
field :block
|
||||||
field :default_content, :localize => true
|
|
||||||
field :default_attribute
|
|
||||||
field :hint
|
field :hint
|
||||||
field :priority, :type => Integer, :default => 0
|
field :priority, :type => Integer, :default => 0
|
||||||
|
field :fixed, :type => Boolean, :default => false
|
||||||
field :disabled, :type => Boolean, :default => false
|
field :disabled, :type => Boolean, :default => false
|
||||||
field :assignable, :type => Boolean, :default => true
|
|
||||||
field :from_parent, :type => Boolean, :default => false
|
field :from_parent, :type => Boolean, :default => false
|
||||||
|
# field :locales, :type => Array TODO
|
||||||
|
|
||||||
## associations ##
|
## associations ##
|
||||||
embedded_in :page, :class_name => 'Locomotive::Page', :inverse_of => :editable_elements
|
embedded_in :page, :class_name => 'Locomotive::Page', :inverse_of => :editable_elements
|
||||||
@ -20,10 +19,60 @@ module Locomotive
|
|||||||
## validations ##
|
## validations ##
|
||||||
validates_presence_of :slug
|
validates_presence_of :slug
|
||||||
|
|
||||||
|
## callbacks ##
|
||||||
|
after_save :propagate_content, :if => :fixed?
|
||||||
|
|
||||||
## scopes ##
|
## scopes ##
|
||||||
scope :by_priority, :order_by => [[:priority, :desc]]
|
scope :by_priority, :order_by => [[:priority, :desc]]
|
||||||
|
|
||||||
## methods ##
|
## methods ##
|
||||||
|
|
||||||
|
def _run_rearrange_callbacks
|
||||||
|
# callback from page/tree. not needed in the editable elements
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_content?
|
||||||
|
# needs to be overridden for each kind of elements
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Copy attributes extracted from the corresponding Liquid tag
|
||||||
|
# Each editable element overrides this method.
|
||||||
|
#
|
||||||
|
# @param [ Hash ] attributes The up-to-date attributes
|
||||||
|
#
|
||||||
|
def copy_attributes(attributes)
|
||||||
|
self.attributes = attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
# Copy attributes from an existing editable element coming
|
||||||
|
# from the parent page. Each editable element may or not
|
||||||
|
# override this method. The source element is a new record.
|
||||||
|
#
|
||||||
|
# @param [ EditableElement] el The source element
|
||||||
|
#
|
||||||
|
def copy_attributes_from(el)
|
||||||
|
self.attributes = el.attributes.reject { |attr| !%w(slug block hint priority fixed disabled from_parent).include?(attr) }
|
||||||
|
self.from_parent = true
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def _selector
|
||||||
|
locale = ::Mongoid::Fields::I18n.locale
|
||||||
|
{
|
||||||
|
'site_id' => self.page.site_id,
|
||||||
|
"template_dependencies.#{locale}" => { '$in' => [self.page._id] },
|
||||||
|
'editable_elements.fixed' => true,
|
||||||
|
'editable_elements.block' => self.block,
|
||||||
|
'editable_elements.slug' => self.slug
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def propagate_content
|
||||||
|
# needs to be overridden for each kind of elements (file, short text, ...etc)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -5,13 +5,72 @@ module Locomotive
|
|||||||
|
|
||||||
replace_field 'source', ::String, true
|
replace_field 'source', ::String, true
|
||||||
|
|
||||||
|
field :default_source_url, :localize => true
|
||||||
|
|
||||||
|
after_save :propagate_content
|
||||||
|
|
||||||
|
## methods ##
|
||||||
|
|
||||||
|
# Returns the url or the path to the uploaded file
|
||||||
|
# if it exists. Otherwise returns the default url.
|
||||||
|
#
|
||||||
|
# @note This method is not used for the rendering, only for the back-office
|
||||||
|
#
|
||||||
|
# @return [String] The url or path of the file
|
||||||
|
#
|
||||||
def content
|
def content
|
||||||
self.source? ? self.source.url : self.default_content
|
self.source? ? self.source.url : self.default_source_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_content?
|
||||||
|
!self.source? && self.default_source_url.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def copy_attributes(attributes)
|
||||||
|
unless self.default_content?
|
||||||
|
attributes.delete(:default_source_url)
|
||||||
|
end
|
||||||
|
|
||||||
|
super(attributes)
|
||||||
|
end
|
||||||
|
|
||||||
|
def copy_attributes_from(el)
|
||||||
|
super(el)
|
||||||
|
|
||||||
|
if el.source_translations.nil?
|
||||||
|
self.attributes['default_source_url'] = el.attributes['default_source_url'] || {}
|
||||||
|
else
|
||||||
|
el.source_translations.keys.each do |locale|
|
||||||
|
::Mongoid::Fields::I18n.with_locale(locale) do
|
||||||
|
self.default_source_url = el.source? ? el.source.url : el.default_source_url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_source=(value)
|
||||||
|
self.source_will_change! # notify the page to run the callbacks for that element
|
||||||
|
self.default_source_url = nil
|
||||||
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
def as_json(options = {})
|
def as_json(options = {})
|
||||||
Locomotive::EditableFilePresenter.new(self).as_json
|
Locomotive::EditableFilePresenter.new(self).as_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def propagate_content
|
||||||
|
if self.source_changed?
|
||||||
|
operations = {
|
||||||
|
'$set' => {
|
||||||
|
"editable_elements.$.default_source_url.#{::Mongoid::Fields::I18n.locale}" => self.source.url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.page.collection.update self._selector, operations, :multi => true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -2,20 +2,46 @@ module Locomotive
|
|||||||
class EditableShortText < EditableElement
|
class EditableShortText < EditableElement
|
||||||
|
|
||||||
## fields ##
|
## fields ##
|
||||||
field :content, :localize => true
|
field :content, :localize => true
|
||||||
|
field :default_content, :type => Boolean, :localize => true, :default => true
|
||||||
|
|
||||||
## methods ##
|
## methods ##
|
||||||
|
|
||||||
def content_with_localization
|
def content=(value)
|
||||||
value = self.content_without_localization
|
self.default_content = false unless self.new_record?
|
||||||
value.blank? ? self.default_content : value
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method_chain :content, :localization
|
def default_content?
|
||||||
|
!!self.default_content
|
||||||
|
end
|
||||||
|
|
||||||
|
def copy_attributes_from(el)
|
||||||
|
super(el)
|
||||||
|
|
||||||
|
self.attributes['content'] = el.content_translations || {}
|
||||||
|
self.attributes['default_content'] = el.default_content_translations
|
||||||
|
end
|
||||||
|
|
||||||
def as_json(options = {})
|
def as_json(options = {})
|
||||||
Locomotive::EditableShortTextPresenter.new(self).as_json
|
Locomotive::EditableShortTextPresenter.new(self).as_json
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def propagate_content
|
||||||
|
if self.content_changed?
|
||||||
|
operations = {
|
||||||
|
'$set' => {
|
||||||
|
"editable_elements.$.content.#{::Mongoid::Fields::I18n.locale}" => self.content,
|
||||||
|
"editable_elements.$.default_content.#{::Mongoid::Fields::I18n.locale}" => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.page.collection.update self._selector, operations, :multi => true
|
||||||
|
end
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -6,15 +6,10 @@ module Locomotive
|
|||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
included do
|
included do
|
||||||
embeds_many :editable_elements, :class_name => 'Locomotive::EditableElement'
|
embeds_many :editable_elements, :class_name => 'Locomotive::EditableElement', :cascade_callbacks => true
|
||||||
|
|
||||||
after_save :remove_disabled_editable_elements
|
after_save :remove_disabled_editable_elements
|
||||||
|
|
||||||
# editable file callbacks
|
|
||||||
after_save :store_file_sources!
|
|
||||||
before_save :write_file_source_identifiers
|
|
||||||
after_destroy :remove_file_sources!
|
|
||||||
|
|
||||||
accepts_nested_attributes_for :editable_elements
|
accepts_nested_attributes_for :editable_elements
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -31,7 +26,7 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
def enabled_editable_elements
|
def enabled_editable_elements
|
||||||
self.editable_elements.by_priority.reject { |el| el.disabled? }
|
self.editable_elements.by_priority.reject { |el| el.disabled? || (el.fixed? && el.from_parent?) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def editable_elements_grouped_by_blocks
|
def editable_elements_grouped_by_blocks
|
||||||
@ -48,10 +43,12 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_or_update_editable_element(attributes, type)
|
def add_or_update_editable_element(attributes, type)
|
||||||
|
# locale = attributes.delete(:locale) # TODO
|
||||||
|
|
||||||
element = self.find_editable_element(attributes[:block], attributes[:slug])
|
element = self.find_editable_element(attributes[:block], attributes[:slug])
|
||||||
|
|
||||||
if element
|
if element
|
||||||
element.attributes = attributes
|
element.copy_attributes(attributes)
|
||||||
else
|
else
|
||||||
self.editable_elements.build(attributes, type)
|
self.editable_elements.build(attributes, type)
|
||||||
end
|
end
|
||||||
@ -63,24 +60,13 @@ module Locomotive
|
|||||||
|
|
||||||
def merge_editable_elements_from_page(source)
|
def merge_editable_elements_from_page(source)
|
||||||
source.editable_elements.each do |el|
|
source.editable_elements.each do |el|
|
||||||
next if el.disabled? or !el.assignable?
|
next if el.disabled?
|
||||||
|
|
||||||
existing_el = self.find_editable_element(el.block, el.slug)
|
existing_el = self.find_editable_element(el.block, el.slug)
|
||||||
|
|
||||||
if existing_el.nil? # new one from parents
|
if existing_el.nil? # new one from parents
|
||||||
new_attributes = el.attributes.merge(:from_parent => true)
|
new_el = self.editable_elements.build({}, el.class)
|
||||||
|
new_el.copy_attributes_from(el)
|
||||||
if new_attributes['default_attribute'].present?
|
|
||||||
new_attributes['default_content'] = self.send(new_attributes['default_attribute']) || el.content
|
|
||||||
else
|
|
||||||
if el.respond_to?(:content) # only for text
|
|
||||||
new_attributes['default_content'] = el.content
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
self.editable_elements.build(new_attributes, el.class)
|
|
||||||
elsif existing_el.default_attribute.nil?
|
|
||||||
existing_el.attributes = { :disabled => false, :default_content => el.content }
|
|
||||||
else
|
else
|
||||||
existing_el.attributes = { :disabled => false }
|
existing_el.attributes = { :disabled => false }
|
||||||
end
|
end
|
||||||
@ -90,29 +76,10 @@ module Locomotive
|
|||||||
def remove_disabled_editable_elements
|
def remove_disabled_editable_elements
|
||||||
return unless self.editable_elements.any? { |el| el.disabled? }
|
return unless self.editable_elements.any? { |el| el.disabled? }
|
||||||
|
|
||||||
# super fast way to remove useless elements all in once (TODO callbacks)
|
# super fast way to remove useless elements all in once
|
||||||
self.collection.update(self.atomic_selector, '$pull' => { 'editable_elements' => { 'disabled' => true } })
|
self.collection.update(self.atomic_selector, '$pull' => { 'editable_elements' => { 'disabled' => true } })
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
|
||||||
|
|
||||||
## callbacks for editable files
|
|
||||||
|
|
||||||
# equivalent to "after_save :store_source!" in EditableFile
|
|
||||||
def store_file_sources!
|
|
||||||
self.find_editable_files.collect(&:store_source!)
|
|
||||||
end
|
|
||||||
|
|
||||||
# equivalent to "before_save :write_source_identifier" in EditableFile
|
|
||||||
def write_file_source_identifiers
|
|
||||||
self.find_editable_files.collect(&:write_source_identifier)
|
|
||||||
end
|
|
||||||
|
|
||||||
# equivalent to "after_destroy :remove_source!" in EditableFile
|
|
||||||
def remove_file_sources!
|
|
||||||
self.find_editable_files.collect(&:remove_source!)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,6 +52,7 @@ module Locomotive
|
|||||||
scope :fullpath, lambda { |fullpath| { :where => { :fullpath => fullpath } } }
|
scope :fullpath, lambda { |fullpath| { :where => { :fullpath => fullpath } } }
|
||||||
scope :handle, lambda { |handle| { :where => { :handle => handle } } }
|
scope :handle, lambda { |handle| { :where => { :handle => handle } } }
|
||||||
scope :minimal_attributes, lambda { |attrs = []| { :only => (attrs || []) + %w(title slug fullpath position depth published templatized redirect listed parent_id site_id created_at updated_at) } }
|
scope :minimal_attributes, lambda { |attrs = []| { :only => (attrs || []) + %w(title slug fullpath position depth published templatized redirect listed parent_id site_id created_at updated_at) } }
|
||||||
|
scope :dependent_from, lambda { |id| { :where => { :template_dependencies.in => [id] } } }
|
||||||
|
|
||||||
## methods ##
|
## methods ##
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
.inner
|
.inner
|
||||||
%h2!= t('locomotive.pages.index.latest_entries')
|
%h2!= t('locomotive.pages.index.latest_entries')
|
||||||
%ul
|
%ul
|
||||||
- current_site.pages.latest_updated.minimal_attributes.each do |page|
|
- current_site.pages.unscoped.latest_updated.minimal_attributes.each do |page|
|
||||||
%li
|
%li
|
||||||
= link_to truncate(page.title, :length => 25), edit_page_url(page)
|
= link_to truncate(page.title, :length => 25), edit_page_url(page)
|
||||||
%span= time_ago_in_words(page.updated_at)
|
%span= time_ago_in_words(page.updated_at)
|
||||||
|
@ -102,7 +102,7 @@ en:
|
|||||||
slug: "It will be used as the name of the collection in the liquid templates. Ex: <span class='code'>{{ contents.my_projects }}</span>"
|
slug: "It will be used as the name of the collection in the liquid templates. Ex: <span class='code'>{{ contents.my_projects }}</span>"
|
||||||
raw_item_template: "You can customize the text displayed for each item in the list. Simply use Liquid. Ex: <span class='code'>{{ entry.name }})</span>"
|
raw_item_template: "You can customize the text displayed for each item in the list. Simply use Liquid. Ex: <span class='code'>{{ entry.name }})</span>"
|
||||||
public_submission_enabled: "It is used to let people from outside to create new entries (example: messages in a contact form)"
|
public_submission_enabled: "It is used to let people from outside to create new entries (example: messages in a contact form)"
|
||||||
public_submission_accounts: "If the public submission option is enabled and for each entry created, sends a notification email tothe accounts listed above."
|
public_submission_accounts: "If the public submission option is enabled and for each entry created, sends a notification email to the accounts listed above."
|
||||||
"custom_fields/field":
|
"custom_fields/field":
|
||||||
name: "Name of the property for liquid templates. Ex: <span class='code'>{{ your_object.<name_of_your_field> }}</span>"
|
name: "Name of the property for liquid templates. Ex: <span class='code'>{{ your_object.<name_of_your_field> }}</span>"
|
||||||
hint: "Text displayed in the model form just below the field"
|
hint: "Text displayed in the model form just below the field"
|
||||||
|
@ -6,7 +6,7 @@ module Locomotive
|
|||||||
delegate :seo_title, :meta_keywords, :meta_description, :to => '_source'
|
delegate :seo_title, :meta_keywords, :meta_description, :to => '_source'
|
||||||
|
|
||||||
def title
|
def title
|
||||||
self._source.templatized? ? @context['content_entry']._label : self._source.title
|
self._source.templatized? ? @context['entry']._label : self._source.title
|
||||||
end
|
end
|
||||||
|
|
||||||
def slug
|
def slug
|
||||||
|
@ -9,7 +9,7 @@ module Locomotive
|
|||||||
def initialize(tag_name, markup, tokens, context)
|
def initialize(tag_name, markup, tokens, context)
|
||||||
if markup =~ Syntax
|
if markup =~ Syntax
|
||||||
@slug = $1.gsub('\'', '')
|
@slug = $1.gsub('\'', '')
|
||||||
@options = { :assignable => true }
|
@options = { :fixed => false }
|
||||||
markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/^'/, '').gsub(/'$/, '') }
|
markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/^'/, '').gsub(/'$/, '') }
|
||||||
else
|
else
|
||||||
raise ::Liquid::SyntaxError.new("Syntax Error in 'editable_xxx' - Valid syntax: editable_xxx <slug>(, <options>)")
|
raise ::Liquid::SyntaxError.new("Syntax Error in 'editable_xxx' - Valid syntax: editable_xxx <slug>(, <options>)")
|
||||||
@ -22,18 +22,7 @@ module Locomotive
|
|||||||
super
|
super
|
||||||
|
|
||||||
if @context[:page].present?
|
if @context[:page].present?
|
||||||
@context[:page].add_or_update_editable_element({
|
@context[:page].add_or_update_editable_element(default_element_attributes, document_type)
|
||||||
:block => @context[:current_block].try(:name),
|
|
||||||
:slug => @slug,
|
|
||||||
:hint => @options[:hint],
|
|
||||||
:priority => @options[:priority] || 0,
|
|
||||||
:default_attribute => @options[:default],
|
|
||||||
:default_content => default_content_option,
|
|
||||||
:assignable => @options[:assignable],
|
|
||||||
:disabled => false,
|
|
||||||
:from_parent => false,
|
|
||||||
:_type => self.document_type.to_s
|
|
||||||
}, document_type)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -43,9 +32,6 @@ module Locomotive
|
|||||||
element = current_page.find_editable_element(context['block'].try(:name), @slug)
|
element = current_page.find_editable_element(context['block'].try(:name), @slug)
|
||||||
|
|
||||||
if element.present?
|
if element.present?
|
||||||
unless element.default_content.present?
|
|
||||||
element.default_content = render_default_content(context)
|
|
||||||
end
|
|
||||||
render_element(context, element)
|
render_element(context, element)
|
||||||
else
|
else
|
||||||
Locomotive.log :error, "[editable element] missing element `#{context['block'].try(:name)}` / #{@slug} on #{current_page.fullpath}"
|
Locomotive.log :error, "[editable element] missing element `#{context['block'].try(:name)}` / #{@slug} on #{current_page.fullpath}"
|
||||||
@ -55,6 +41,19 @@ module Locomotive
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def default_element_attributes
|
||||||
|
{
|
||||||
|
:block => @options[:block] || @context[:current_block].try(:name),
|
||||||
|
:slug => @slug,
|
||||||
|
:hint => @options[:hint],
|
||||||
|
:priority => @options[:priority] || 0,
|
||||||
|
:fixed => !!@options[:fixed],
|
||||||
|
:disabled => false,
|
||||||
|
:from_parent => false,
|
||||||
|
:_type => self.document_type.to_s
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def render_element(element)
|
def render_element(element)
|
||||||
raise 'FIXME: has to be overidden'
|
raise 'FIXME: has to be overidden'
|
||||||
end
|
end
|
||||||
@ -63,14 +62,6 @@ module Locomotive
|
|||||||
raise 'FIXME: has to be overidden'
|
raise 'FIXME: has to be overidden'
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_content_option
|
|
||||||
result = nil
|
|
||||||
if @options[:default].present?
|
|
||||||
result = @context[:page].send(@options[:default])
|
|
||||||
end
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
def render_default_content(context)
|
def render_default_content(context)
|
||||||
render_all(@nodelist, context).join(' ')
|
render_all(@nodelist, context).join(' ')
|
||||||
end
|
end
|
||||||
|
@ -6,8 +6,26 @@ module Locomotive
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def default_element_attributes
|
||||||
|
if @nodelist.first.is_a?(String)
|
||||||
|
super.merge(:default_source_url => @nodelist.first.try(:to_s))
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def render_element(context, element)
|
def render_element(context, element)
|
||||||
element.source? ? element.source.url : element.default_content
|
if element.source?
|
||||||
|
element.source.url
|
||||||
|
else
|
||||||
|
if element.default_source_url.present?
|
||||||
|
element.default_source_url
|
||||||
|
else
|
||||||
|
render_default_content(context)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def document_type
|
def document_type
|
||||||
|
@ -7,14 +7,16 @@ module Locomotive
|
|||||||
protected
|
protected
|
||||||
|
|
||||||
def render_element(context, element)
|
def render_element(context, element)
|
||||||
if context.registers[:inline_editor]
|
content = element.default_content? ? render_default_content(context) : element.content
|
||||||
|
|
||||||
|
if editable?(context, element)
|
||||||
%{
|
%{
|
||||||
<div class='editable-long-text' data-element-id='#{element.id}' data-element-index='#{element._index}'>
|
<div class='editable-long-text' data-element-id='#{element.id}' data-element-index='#{element._index}'>
|
||||||
#{element.content}
|
#{content}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
element.content
|
content
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -7,14 +7,16 @@ module Locomotive
|
|||||||
protected
|
protected
|
||||||
|
|
||||||
def render_element(context, element)
|
def render_element(context, element)
|
||||||
if context.registers[:inline_editor]
|
content = element.default_content? ? render_default_content(context) : element.content
|
||||||
|
|
||||||
|
if editable?(context, element)
|
||||||
%{
|
%{
|
||||||
<span class='editable-short-text' data-element-id='#{element.id}' data-element-index='#{element._index}'>
|
<span class='editable-short-text' data-element-id='#{element.id}' data-element-index='#{element._index}'>
|
||||||
#{element.content}
|
#{content}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
element.content
|
content
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -22,6 +24,10 @@ module Locomotive
|
|||||||
EditableShortText
|
EditableShortText
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def editable?(context, element)
|
||||||
|
context.registers[:inline_editor] && (!element.fixed? || (element.fixed? && !element.from_parent?))
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
::Liquid::Template.register_tag('editable_short_text', ShortText)
|
::Liquid::Template.register_tag('editable_short_text', ShortText)
|
||||||
|
@ -74,9 +74,9 @@ describe Locomotive::Liquid::Drops::Page do
|
|||||||
it 'renders the content instance highlighted field instead for a templatized 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)
|
templatized = FactoryGirl.build(:page, :title => 'Lorem ipsum template', :templatized => true)
|
||||||
|
|
||||||
content_entry = Locomotive::Liquid::Drops::ContentEntry.new(mock('content_entry', :_label => 'Locomotive rocks !'))
|
entry = Locomotive::Liquid::Drops::ContentEntry.new(mock('entry', :_label => 'Locomotive rocks !'))
|
||||||
|
|
||||||
render_template('{{ page.title }}', 'page' => templatized, 'content_entry' => content_entry).should == 'Locomotive rocks !'
|
render_template('{{ page.title }}', 'page' => templatized, 'entry' => entry).should == 'Locomotive rocks !'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Locomotive::EditableElement do
|
|
||||||
|
|
||||||
before(:each) do
|
|
||||||
@site = FactoryGirl.create(:site)
|
|
||||||
@home = @site.pages.root.first
|
|
||||||
|
|
||||||
@home.update_attributes :raw_template => "{% block body %}{% editable_short_text 'body' %}Lorem ipsum{% endeditable_short_text %}{% endblock %}"
|
|
||||||
|
|
||||||
@sub_page_1 = FactoryGirl.create(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
|
||||||
@sub_page_2 = FactoryGirl.create(:page, :slug => 'sub_page_2', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
|
||||||
|
|
||||||
@sub_page_1_1 = FactoryGirl.create(:page, :slug => 'sub_page_1_1', :parent => @sub_page_1, :raw_template => "{% extends 'parent' %}")
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'in sub pages level #1' do
|
|
||||||
|
|
||||||
before(:each) do
|
|
||||||
@sub_page_1.reload
|
|
||||||
@sub_page_2.reload
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'exists' do
|
|
||||||
@sub_page_1.editable_elements.size.should == 1
|
|
||||||
@sub_page_2.editable_elements.size.should == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'has a non-nil slug' do
|
|
||||||
@sub_page_1.editable_elements.first.slug.should == 'body'
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'in sub pages level #2' do
|
|
||||||
|
|
||||||
before(:each) do
|
|
||||||
@sub_page_1_1.reload
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'exists' do
|
|
||||||
@sub_page_1_1.editable_elements.size.should == 1
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'has a non-nil slug' do
|
|
||||||
@sub_page_1_1.editable_elements.first.slug.should == 'body'
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'removes editable elements' do
|
|
||||||
@sub_page_1_1.editable_elements.destroy_all
|
|
||||||
@sub_page_1_1.reload
|
|
||||||
@sub_page_1_1.editable_elements.size.should == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
@ -16,13 +16,25 @@ describe Locomotive::EditableFile do
|
|||||||
@home.editable_elements.first.slug.should == 'image'
|
@home.editable_elements.first.slug.should == 'image'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'disables the default content flag if the remove_source method is called' do
|
||||||
|
@home.editable_elements.first.remove_source = true
|
||||||
|
@home.save; @home.reload
|
||||||
|
@home.editable_elements.first.default_content?.should be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'disables the default content when a new file is uploaded' do
|
||||||
|
@home.editable_elements.first.source = FixturedAsset.open('5k.png')
|
||||||
|
@home.save
|
||||||
|
@home.editable_elements.first.default_content?.should be_false
|
||||||
|
end
|
||||||
|
|
||||||
it 'does not have 2 image fields' do
|
it 'does not have 2 image fields' do
|
||||||
editable_file = @home.editable_elements.first
|
editable_file = @home.editable_elements.first
|
||||||
fields = editable_file.class.fields.keys
|
fields = editable_file.class.fields.keys
|
||||||
(fields.include?('source') && fields.include?(:source)).should be_false
|
(fields.include?('source') && fields.include?(:source)).should be_false
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with an attached file' do
|
describe 'with an attached file' do
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@editable_file = @home.editable_elements.first
|
@editable_file = @home.editable_elements.first
|
||||||
@ -41,4 +53,43 @@ describe Locomotive::EditableFile do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '"sticky" files' do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@home.update_attributes :raw_template => "{% block body %}{% editable_file 'image', fixed: true %}/foo.png{% endeditable_file %}{% endblock %}"
|
||||||
|
|
||||||
|
@sub_page_1 = FactoryGirl.create(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'index' %}")
|
||||||
|
@sub_page_2 = FactoryGirl.create(:page, :slug => 'sub_page_2', :parent => @home, :raw_template => "{% extends 'index' %}")
|
||||||
|
|
||||||
|
@sub_page_1_el = @sub_page_1.editable_elements.first
|
||||||
|
@sub_page_2_el = @sub_page_2.editable_elements.first
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'exists in sub pages' do
|
||||||
|
@sub_page_1.editable_elements.size.should == 1
|
||||||
|
@sub_page_2.editable_elements.size.should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is marked as fixed' do
|
||||||
|
@sub_page_1_el.fixed?.should be_true
|
||||||
|
@sub_page_2_el.fixed?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'enables the default content when it just got created' do
|
||||||
|
@sub_page_1_el.source?.should be_false
|
||||||
|
@sub_page_1_el.default_source_url.should == '/foo.png'
|
||||||
|
@sub_page_1_el.default_content?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'gets also updated when updating the very first element' do
|
||||||
|
@home.editable_elements.first.source = FixturedAsset.open('5k.png')
|
||||||
|
@home.save; @sub_page_1.reload; @sub_page_2.reload
|
||||||
|
@sub_page_1.editable_elements.first.default_source_url.should be_true
|
||||||
|
@sub_page_1.editable_elements.first.default_source_url.should =~ /files\/5k.png$/
|
||||||
|
@sub_page_2.editable_elements.first.default_source_url.should be_true
|
||||||
|
@sub_page_2.editable_elements.first.default_source_url.should =~ /files\/5k.png$/
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
27
spec/models/locomotive/editable_long_text_spec.rb
Normal file
27
spec/models/locomotive/editable_long_text_spec.rb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Locomotive::EditableLongText do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@site = FactoryGirl.create(:site)
|
||||||
|
@home = @site.pages.root.first
|
||||||
|
|
||||||
|
@home.update_attributes :raw_template => "{% block body %}{% editable_long_text 'body' %}Lorem ipsum{% endeditable_long_text %}{% endblock %}"
|
||||||
|
|
||||||
|
@sub_page_1 = FactoryGirl.create(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'exists' do
|
||||||
|
@sub_page_1.editable_elements.size.should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has a non-nil slug' do
|
||||||
|
@sub_page_1.editable_elements.first.slug.should == 'body'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not have a content at first' do
|
||||||
|
@sub_page_1.editable_elements.first.content.should be_nil
|
||||||
|
@sub_page_1.editable_elements.first.default_content.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
114
spec/models/locomotive/editable_short_text_spec.rb
Normal file
114
spec/models/locomotive/editable_short_text_spec.rb
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Locomotive::EditableShortText do
|
||||||
|
|
||||||
|
describe 'a simple case' do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@site = FactoryGirl.create(:site)
|
||||||
|
@home = @site.pages.root.first
|
||||||
|
|
||||||
|
@home.update_attributes :raw_template => "{% block body %}{% editable_short_text 'body' %}Lorem ipsum{% endeditable_short_text %}{% endblock %}"
|
||||||
|
|
||||||
|
@sub_page_1 = FactoryGirl.create(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||||
|
@sub_page_2 = FactoryGirl.create(:page, :slug => 'sub_page_2', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||||
|
|
||||||
|
@sub_page_1_el = @sub_page_1.editable_elements.first
|
||||||
|
|
||||||
|
@sub_page_1_1 = FactoryGirl.create(:page, :slug => 'sub_page_1_1', :parent => @sub_page_1, :raw_template => "{% extends 'parent' %}")
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'in sub pages level #1' do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@sub_page_1.reload
|
||||||
|
@sub_page_2.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'exists' do
|
||||||
|
@sub_page_1.editable_elements.size.should == 1
|
||||||
|
@sub_page_2.editable_elements.size.should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has a non-nil slug' do
|
||||||
|
@sub_page_1.editable_elements.first.slug.should == 'body'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not have a content at first' do
|
||||||
|
@sub_page_1_el.content.should be_nil
|
||||||
|
@sub_page_1_el.default_content.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'in sub pages level #2' do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@sub_page_1_1.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'exists' do
|
||||||
|
@sub_page_1_1.editable_elements.size.should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has a non-nil slug' do
|
||||||
|
@sub_page_1_1.editable_elements.first.slug.should == 'body'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'removes editable elements' do
|
||||||
|
@sub_page_1_1.editable_elements.destroy_all
|
||||||
|
@sub_page_1_1.reload
|
||||||
|
@sub_page_1_1.editable_elements.size.should == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '"sticky" elements' do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@site = FactoryGirl.create(:site)
|
||||||
|
@home = @site.pages.root.first
|
||||||
|
|
||||||
|
@home.update_attributes :raw_template => "{% block body %}{% editable_short_text 'body', fixed: true %}Lorem ipsum{% endeditable_short_text %}{% endblock %}"
|
||||||
|
@home_el = @home.editable_elements.first
|
||||||
|
|
||||||
|
@sub_page_1 = FactoryGirl.create(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||||
|
@sub_page_2 = FactoryGirl.create(:page, :slug => 'sub_page_2', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||||
|
|
||||||
|
@sub_page_1_el = @sub_page_1.editable_elements.first
|
||||||
|
@sub_page_2_el = @sub_page_2.editable_elements.first
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'exists in sub pages' do
|
||||||
|
@sub_page_1.editable_elements.size.should == 1
|
||||||
|
@sub_page_2.editable_elements.size.should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is marked as fixed' do
|
||||||
|
@sub_page_1_el.fixed?.should be_true
|
||||||
|
@sub_page_2_el.fixed?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'enables the default content when it just got created' do
|
||||||
|
@sub_page_1_el.default_content?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'disables the default content if the content changed' do
|
||||||
|
@sub_page_1_el.content = 'Bla bla'
|
||||||
|
@sub_page_1_el.default_content?.should be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'gets also updated when updating the very first element' do
|
||||||
|
@home_el.content = 'Hello world'
|
||||||
|
@home.save
|
||||||
|
@sub_page_1.reload; @sub_page_1_el = @sub_page_1.editable_elements.first
|
||||||
|
@sub_page_2.reload; @sub_page_2_el = @sub_page_2.editable_elements.first
|
||||||
|
@sub_page_1_el.content.should == 'Hello world'
|
||||||
|
@sub_page_2_el.content.should == 'Hello world'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user