Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
Didier Lafforgue | bf480a6df5 | |
Didier Lafforgue | e5cb5d1f9a | |
Didier Lafforgue | 62e2a5029d | |
Didier Lafforgue | 63fd77f950 | |
Didier Lafforgue | 14596a5443 | |
did | 4d1b986f1b | |
Didier Lafforgue | e26febdaf6 | |
Didier Lafforgue | 260f9ae4ef | |
Didier Lafforgue | 64ea41cbcd | |
Didier Lafforgue | 64168cad37 |
1
Gemfile
1
Gemfile
|
@ -8,6 +8,7 @@ gemspec # Include gemspec dependencies
|
||||||
# The rest of the dependencies are for use when in the locomotive development environment
|
# The rest of the dependencies are for use when in the locomotive development environment
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
# gem 'locomotive-mongoid-tree', :path => '../gems/custom_fields' # for Developers
|
||||||
# gem 'custom_fields', :path => '../gems/custom_fields' # for Developers
|
# gem 'custom_fields', :path => '../gems/custom_fields' # for Developers
|
||||||
# gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git', :branch => '2.0.0.rc' # Branch on Github
|
# gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git', :branch => '2.0.0.rc' # Branch on Github
|
||||||
|
|
||||||
|
|
|
@ -103,9 +103,7 @@ GEM
|
||||||
rack-test (>= 0.5.4)
|
rack-test (>= 0.5.4)
|
||||||
selenium-webdriver (~> 2.0)
|
selenium-webdriver (~> 2.0)
|
||||||
xpath (~> 0.1.4)
|
xpath (~> 0.1.4)
|
||||||
carrierwave (0.6.2)
|
carrierwave (0.6.1)
|
||||||
activemodel (>= 3.2.0)
|
|
||||||
activesupport (>= 3.2.0)
|
|
||||||
carrierwave-mongoid (0.1.3)
|
carrierwave-mongoid (0.1.3)
|
||||||
carrierwave (>= 0.5.6)
|
carrierwave (>= 0.5.6)
|
||||||
mongoid (~> 2.1)
|
mongoid (~> 2.1)
|
||||||
|
@ -148,7 +146,7 @@ GEM
|
||||||
rack
|
rack
|
||||||
ejs (1.0.0)
|
ejs (1.0.0)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
excon (0.13.4)
|
excon (0.13.3)
|
||||||
execjs (1.3.0)
|
execjs (1.3.0)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
factory_girl (2.5.2)
|
factory_girl (2.5.2)
|
||||||
|
|
|
@ -21,7 +21,4 @@ class Locomotive.Models.Page extends Backbone.Model
|
||||||
delete hash['editable_elements']
|
delete hash['editable_elements']
|
||||||
hash.editable_elements = @get('editable_elements').toJSONForSave() if @get('editable_elements')? && @get('editable_elements').length > 0
|
hash.editable_elements = @get('editable_elements').toJSONForSave() if @get('editable_elements')? && @get('editable_elements').length > 0
|
||||||
|
|
||||||
delete hash['target_klass_name']
|
|
||||||
hash.target_klass_name = @get('target_klass_name') if @get('templatized') == true
|
|
||||||
|
|
||||||
class Locomotive.Models.PagesCollection extends Backbone.Collection
|
class Locomotive.Models.PagesCollection extends Backbone.Collection
|
|
@ -41,7 +41,7 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||||
@enable_response_type_select()
|
@enable_response_type_select()
|
||||||
|
|
||||||
# enable check boxes
|
# enable check boxes
|
||||||
@enable_templatized_checkbox()
|
@enable_wildcard_checkbox()
|
||||||
|
|
||||||
@enable_redirect_checkbox()
|
@enable_redirect_checkbox()
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||||
@editor = CodeMirror.fromTextArea input.get()[0],
|
@editor = CodeMirror.fromTextArea input.get()[0],
|
||||||
mode: 'liquid'
|
mode: 'liquid'
|
||||||
autoMatchParens: false
|
autoMatchParens: false
|
||||||
lineNumbers: false
|
lineNumbers: true
|
||||||
passDelay: 50
|
passDelay: 50
|
||||||
tabMode: 'shift'
|
tabMode: 'shift'
|
||||||
theme: 'default'
|
theme: 'default'
|
||||||
|
@ -109,14 +109,9 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||||
url: @$('#page_slug').attr('data-url')
|
url: @$('#page_slug').attr('data-url')
|
||||||
type: 'get'
|
type: 'get'
|
||||||
dataType: 'json'
|
dataType: 'json'
|
||||||
data: { parent_id: @$('#page_parent_id').val(), slug: @$('#page_slug').val() }
|
data: { parent_id: @$('#page_parent_id').val(), slug: @$('#page_slug').val(), wildcard: @model.get('wildcard') }
|
||||||
success: (data) =>
|
success: (data) =>
|
||||||
@$('#page_slug_input .inline-hints').html(data.url).effect('highlight')
|
@$('#page_slug_input .inline-hints').html(data.url).effect('highlight')
|
||||||
if data.templatized_parent
|
|
||||||
@$('li#page_slug_input').show()
|
|
||||||
@$('li#page_templatized_input, li#page_target_klass_name_input').hide()
|
|
||||||
else
|
|
||||||
@$('li#page_templatized_input').show() unless @model.get('redirect')
|
|
||||||
|
|
||||||
enable_response_type_select: ->
|
enable_response_type_select: ->
|
||||||
@$('li#page_response_type_input').change (event) =>
|
@$('li#page_response_type_input').change (event) =>
|
||||||
|
@ -126,19 +121,13 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||||
@model.set redirect: false
|
@model.set redirect: false
|
||||||
@$('li#page_redirect_input, li#page_redirect_url_input').hide()
|
@$('li#page_redirect_input, li#page_redirect_url_input').hide()
|
||||||
|
|
||||||
enable_templatized_checkbox: ->
|
enable_wildcard_checkbox: ->
|
||||||
@_enable_checkbox 'templatized',
|
@_enable_checkbox 'wildcard',
|
||||||
features: ['slug', 'redirect', 'listed']
|
features: ['redirect', 'listed']
|
||||||
on_callback: =>
|
|
||||||
@$('li#page_target_klass_name_input').show()
|
|
||||||
off_callback: =>
|
|
||||||
@$('li#page_target_klass_name_input').hide()
|
|
||||||
|
|
||||||
@$('li#page_templatized_input').hide() if @model.get('templatized_from_parent') == true
|
|
||||||
|
|
||||||
enable_redirect_checkbox: ->
|
enable_redirect_checkbox: ->
|
||||||
@_enable_checkbox 'redirect',
|
@_enable_checkbox 'redirect',
|
||||||
features: ['templatized', 'cache_strategy']
|
features: ['wildcard', 'cache_strategy']
|
||||||
on_callback: =>
|
on_callback: =>
|
||||||
@$('li#page_redirect_url_input').show()
|
@$('li#page_redirect_url_input').show()
|
||||||
off_callback: =>
|
off_callback: =>
|
||||||
|
|
|
@ -271,7 +271,7 @@ ul.list {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.templatized > .inner > a {
|
&.wildcard > .inner > a {
|
||||||
padding-right: 24px;
|
padding-right: 24px;
|
||||||
background: transparent image-url("locomotive/list/icons/template.png") no-repeat right 2px;
|
background: transparent image-url("locomotive/list/icons/template.png") no-repeat right 2px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,10 +53,10 @@ module Locomotive
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_path
|
def get_path
|
||||||
page = current_site.pages.build(:parent => current_site.pages.find(params[:parent_id]), :slug => params[:slug].permalink).tap do |p|
|
page = current_site.pages.build(:parent => current_site.pages.find(params[:parent_id]), :slug => params[:slug].permalink, :wildcard => params[:wildcard]).tap do |p|
|
||||||
p.valid?; p.send(:build_fullpath)
|
p.valid?; p.send(:build_fullpath)
|
||||||
end
|
end
|
||||||
render :json => { :url => public_page_url(page), :slug => page.slug, :templatized_parent => page.templatized_from_parent? }
|
render :json => { :url => public_page_url(page), :slug => page.slug }
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -99,13 +99,13 @@ module Locomotive
|
||||||
Locomotive.config.multi_sites?
|
Locomotive.config.multi_sites?
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_page_url(page, options = {})
|
# def public_page_url(page, options = {})
|
||||||
if content = options.delete(:content)
|
# if content = options.delete(:content)
|
||||||
File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug)
|
# File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug)
|
||||||
else
|
# else
|
||||||
File.join(current_site_public_url, page.fullpath)
|
# File.join(current_site_public_url, page.fullpath)
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
||||||
# memberships
|
# memberships
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ module Locomotive
|
||||||
module PagesHelper
|
module PagesHelper
|
||||||
|
|
||||||
def css_for_page(page)
|
def css_for_page(page)
|
||||||
%w(index not_found templatized redirect).inject([]) do |memo, state|
|
%w(index not_found wildcard redirect).inject([]) do |memo, state|
|
||||||
memo << state.dasherize if page.send(:"#{state}?")
|
memo << state.dasherize if page.send(:"#{state}?")
|
||||||
memo
|
memo
|
||||||
end.join(' ')
|
end.join(' ')
|
||||||
|
@ -32,13 +32,6 @@ module Locomotive
|
||||||
list
|
list
|
||||||
end
|
end
|
||||||
|
|
||||||
def options_for_target_klass_name
|
|
||||||
base_models = current_site.content_types.map do |type|
|
|
||||||
[type.name.humanize, type.klass_with_custom_fields(:entries)]
|
|
||||||
end
|
|
||||||
base_models + Locomotive.config.models_for_templatization.map { |name| [name.underscore.humanize, name] }
|
|
||||||
end
|
|
||||||
|
|
||||||
def options_for_page_cache_strategy
|
def options_for_page_cache_strategy
|
||||||
[
|
[
|
||||||
[t('.cache_strategy.none'), 'none'],
|
[t('.cache_strategy.none'), 'none'],
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
module Locomotive
|
||||||
|
module Extensions
|
||||||
|
module Page
|
||||||
|
module Fullpath
|
||||||
|
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
|
||||||
|
## fields ##
|
||||||
|
field :fullpath, :localize => true
|
||||||
|
field :wildcard, :type => Boolean, :default => false
|
||||||
|
field :wildcards, :type => Array
|
||||||
|
|
||||||
|
## callbacks ##
|
||||||
|
before_validation :get_wildcards_from_parent
|
||||||
|
before_validation :add_slug_to_wildcards
|
||||||
|
before_save :build_fullpath
|
||||||
|
after_update :propagate_fullpath_changes
|
||||||
|
|
||||||
|
# before_save :set_children_autosave
|
||||||
|
# before_rearrange :foo #propagate_fullpath_changes
|
||||||
|
# after_save :propagate_fullpath_changes
|
||||||
|
|
||||||
|
# after_save { |p| puts "[after_save] #{p.fullpath} / #{p.wildcards.inspect} / #{p.wildcard?}" }
|
||||||
|
|
||||||
|
## scopes ##
|
||||||
|
# scope :fullpath, lambda { |fullpath| { :where => { :fullpath => fullpath } } } # used ?
|
||||||
|
|
||||||
|
## virtual attributes ##
|
||||||
|
attr_accessor :wildcards_hash
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
# def foo
|
||||||
|
# Rails.logger.debug "----> rearranging #{self.slug}.......\n\n"
|
||||||
|
# puts "[rearranging]"
|
||||||
|
# end
|
||||||
|
|
||||||
|
# This method returns true if the fullpath is enhanced
|
||||||
|
# by wildcards. It is different from the wildcard? method
|
||||||
|
# because it includes the ancestors when determining if
|
||||||
|
# the current page has wildcards or not.
|
||||||
|
#
|
||||||
|
def has_wildcards?
|
||||||
|
self.wildcard? || !self.fullpath.try(:index, '*').nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
# It returns a pretty output of the fullpath. The "*" characters
|
||||||
|
# are replaced by the following pattern ":<slug>" like the ones you can find
|
||||||
|
# in the Ruby on Rails routes.
|
||||||
|
#
|
||||||
|
def pretty_fullpath
|
||||||
|
return self.fullpath unless self.has_wildcards?
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
self.fullpath.split('/').map do |segment|
|
||||||
|
if segment == '*'
|
||||||
|
":#{self.wildcards[index]}".tap { index += 1 }
|
||||||
|
else
|
||||||
|
segment
|
||||||
|
end
|
||||||
|
end.join('/')
|
||||||
|
end
|
||||||
|
|
||||||
|
# It returns the fullpath with wildcard segments replaced by the values
|
||||||
|
# specified in the first argument.
|
||||||
|
#
|
||||||
|
# @param [ Hash ] values The map assigning to a wildcard name its value
|
||||||
|
# @return [ String ] The compiled fullpath
|
||||||
|
#
|
||||||
|
def compiled_fullpath(values)
|
||||||
|
return self.fullpath unless self.has_wildcards?
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
self.fullpath.split('/').map do |segment|
|
||||||
|
if segment == '*'
|
||||||
|
"#{values[self.wildcards[index]]}".tap { index += 1 }
|
||||||
|
else
|
||||||
|
segment
|
||||||
|
end
|
||||||
|
end.join('/')
|
||||||
|
end
|
||||||
|
|
||||||
|
# It builds the map associating the name of a wildcard
|
||||||
|
# with its value within the path.
|
||||||
|
# The map is also stored in the wildcards_hash attribute
|
||||||
|
# of the page.
|
||||||
|
#
|
||||||
|
# @param [ String ] path the path from the HTTP request
|
||||||
|
# @return [ Hash ] The map
|
||||||
|
#
|
||||||
|
def match_wildcards(path)
|
||||||
|
self.wildcards_hash, wildcard_index, segments = {}, 0, self.fullpath.split('/')
|
||||||
|
|
||||||
|
path.split('/').each_with_index do |segment, index|
|
||||||
|
if segments[index] == '*'
|
||||||
|
self.wildcards_hash[self.wildcards[wildcard_index].underscore] = segment
|
||||||
|
wildcard_index += 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.wildcards_hash
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
# def set_children_autosave
|
||||||
|
# @autosave_for_children = !must_propagate_fullpath_changes?
|
||||||
|
# true
|
||||||
|
# end
|
||||||
|
|
||||||
|
def get_wildcards_from_parent
|
||||||
|
return true if self.parent.nil?
|
||||||
|
|
||||||
|
if self.parent.has_wildcards?
|
||||||
|
# puts "[get_wildcards_from_parent] #{self.slug} - #{self.parent.wildcards.inspect}"
|
||||||
|
self.wildcards = self.parent.wildcards.clone
|
||||||
|
else
|
||||||
|
# puts "[get_wildcards_from_parent] #{self.slug} - reset wildcards"
|
||||||
|
self.wildcards = []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_slug_to_wildcards
|
||||||
|
# puts "[add_slug_to_wildcards] #{self.slug} / #{self.wildcard?}"
|
||||||
|
(self.wildcards ||= []) << self.slug if self.wildcard?
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_fullpath
|
||||||
|
if self.index? || self.not_found?
|
||||||
|
self.fullpath = self.slug
|
||||||
|
else
|
||||||
|
segments = (self.parent.fullpath.try(:split, '/') || [nil]) + [self.wildcard? ? '*' : self.slug]
|
||||||
|
segments.shift if segments.first == 'index'
|
||||||
|
self.fullpath = File.join segments.compact
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def propagate_fullpath_changes
|
||||||
|
if self.fullpath_changed? || self.wildcards_changed?
|
||||||
|
self.rearrange_children!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# def must_propagate_fullpath_changes?
|
||||||
|
# self.wildcard_changed? || self.slug_changed?
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# def propagate_fullpath_changes
|
||||||
|
# return true unless must_propagate_fullpath_changes?
|
||||||
|
#
|
||||||
|
# parent_identities = { self._id => self }
|
||||||
|
#
|
||||||
|
# Rails.logger.debug "[propagate_fullpath_changes] BEGIN page #{self.slug} #{self.fullpath} / #{self.wildcards.inspect} / #{self._parent.try(:has_wildcards?).inspect}"
|
||||||
|
# puts "[propagate_fullpath_changes] BEGIN page #{self.slug} #{self.fullpath} / #{self.wildcards.inspect} / #{self._parent.try(:has_wildcards?).inspect}"
|
||||||
|
#
|
||||||
|
# self.descendants.order_by([[:depth, :asc]]).each do |page|
|
||||||
|
# _parent = parent_identities[page.parent_id]
|
||||||
|
# _fullpath = {}
|
||||||
|
# _wildcards = nil
|
||||||
|
#
|
||||||
|
# puts "[propagate_fullpath_changes] #{page.fullpath} / #{page.wildcards.inspect} / #{page._parent.try(:has_wildcards?).inspect}"
|
||||||
|
#
|
||||||
|
# if _parent.has_wildcards?
|
||||||
|
# _wildcards = _parent.wildcards + (page.wildcard? ? [page.slug] : [])
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# self.site.locales.each do |locale|
|
||||||
|
# base_fullpath = _parent.fullpath_translations[locale]
|
||||||
|
# slug = page.wildcard? ? '*' : page.slug_translations[locale]
|
||||||
|
#
|
||||||
|
# next if base_fullpath.blank?
|
||||||
|
#
|
||||||
|
# _fullpath[locale] = File.join(base_fullpath, slug)
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# selector = { 'id' => page._id }
|
||||||
|
# operations = {
|
||||||
|
# '$set' => {
|
||||||
|
# 'wildcards' => _wildcards,
|
||||||
|
# 'fullpath' => _fullpath
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# self.collection.update selector, operations
|
||||||
|
#
|
||||||
|
# parent_identities[page._id] = page
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -22,7 +22,8 @@ module Locomotive
|
||||||
validate :template_must_be_valid
|
validate :template_must_be_valid
|
||||||
|
|
||||||
## scopes ##
|
## scopes ##
|
||||||
scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
|
scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
|
||||||
|
scope :dependent_from, lambda { |id| { :where => { :template_dependencies.in => [id] } } }
|
||||||
end
|
end
|
||||||
|
|
||||||
def template
|
def template
|
||||||
|
|
|
@ -11,11 +11,10 @@ module Locomotive
|
||||||
|
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
|
|
||||||
# Given both a site and a path, this method tries
|
# Given both a site and a path, this method retrieves
|
||||||
# to get the matching page.
|
# the matching page if it exists.
|
||||||
# If the page is templatized, the related content entry is
|
# If the found page owns wildcards in its fullpath, then
|
||||||
# associated to the page (page.content_entry stores the entry).
|
# assigns the value for each wildcard and store the result within the page.
|
||||||
# If no page is found, then it returns the 404 one instead.
|
|
||||||
#
|
#
|
||||||
# @param [ Site ] site The site where to find the page
|
# @param [ Site ] site The site where to find the page
|
||||||
# @param [ String ] path The fullpath got from the request
|
# @param [ String ] path The fullpath got from the request
|
||||||
|
@ -33,17 +32,7 @@ module Locomotive
|
||||||
if !_page.published? && !logged_in
|
if !_page.published? && !logged_in
|
||||||
next
|
next
|
||||||
else
|
else
|
||||||
if _page.templatized?
|
_page.match_wildcards(path)
|
||||||
%r(^#{_page.fullpath.gsub('content_type_template', '([^\/]+)')}$) =~ path
|
|
||||||
|
|
||||||
permalink = $1
|
|
||||||
|
|
||||||
_page.content_entry = _page.fetch_target_entry(permalink)
|
|
||||||
|
|
||||||
if _page.content_entry.nil? || (!_page.content_entry.visible? && !logged_in) # content instance not found or not visible
|
|
||||||
next
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
page = _page
|
page = _page
|
||||||
|
@ -56,9 +45,7 @@ module Locomotive
|
||||||
|
|
||||||
# Calculate all the combinations possible based on the
|
# Calculate all the combinations possible based on the
|
||||||
# fact that one of the segment of the path could be
|
# fact that one of the segment of the path could be
|
||||||
# a content type from a templatized page.
|
# a wildcard.
|
||||||
# We postulate that there is only one templatized page in a path
|
|
||||||
# (ie: no nested templatized pages)
|
|
||||||
#
|
#
|
||||||
# @param [ String ] path The path to the page
|
# @param [ String ] path The path to the page
|
||||||
#
|
#
|
||||||
|
@ -69,13 +56,13 @@ module Locomotive
|
||||||
end
|
end
|
||||||
|
|
||||||
#:nodoc:
|
#:nodoc:
|
||||||
def _path_combinations(segments, can_include_template = true)
|
def _path_combinations(segments)
|
||||||
return nil if segments.empty?
|
return nil if segments.empty?
|
||||||
|
|
||||||
segment = segments.shift
|
segment = segments.shift
|
||||||
|
|
||||||
(can_include_template ? [segment, 'content_type_template'] : [segment]).map do |_segment|
|
[segment, '*'].map do |_segment|
|
||||||
if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != 'content_type_template'))
|
if (_combinations = _path_combinations(segments.clone))
|
||||||
[*_combinations].map do |_combination|
|
[*_combinations].map do |_combination|
|
||||||
File.join(_segment, _combination)
|
File.join(_segment, _combination)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,136 +1,136 @@
|
||||||
module Locomotive
|
# module Locomotive
|
||||||
module Extensions
|
# module Extensions
|
||||||
module Page
|
# module Page
|
||||||
module Templatized
|
# module Templatized
|
||||||
|
#
|
||||||
extend ActiveSupport::Concern
|
# extend ActiveSupport::Concern
|
||||||
|
#
|
||||||
included do
|
# included do
|
||||||
|
#
|
||||||
## fields ##
|
# ## fields ##
|
||||||
field :templatized, :type => Boolean, :default => false
|
# field :templatized, :type => Boolean, :default => false
|
||||||
field :templatized_from_parent, :type => Boolean, :default => false
|
# field :templatized_from_parent, :type => Boolean, :default => false
|
||||||
field :target_klass_name
|
# field :target_klass_name
|
||||||
|
#
|
||||||
## validations ##
|
# ## validations ##
|
||||||
validates_presence_of :target_klass_name, :if => :templatized?
|
# validates_presence_of :target_klass_name, :if => :templatized?
|
||||||
validate :ensure_target_klass_name_security
|
# validate :ensure_target_klass_name_security
|
||||||
|
#
|
||||||
## callbacks ##
|
# ## callbacks ##
|
||||||
before_validation :get_templatized_from_parent
|
# before_validation :get_templatized_from_parent
|
||||||
before_validation :set_slug_if_templatized
|
# before_validation :set_slug_if_templatized
|
||||||
before_validation :ensure_target_klass_name_security
|
# before_validation :ensure_target_klass_name_security
|
||||||
after_save :propagate_templatized
|
# after_save :propagate_templatized
|
||||||
|
#
|
||||||
## scopes ##
|
# ## scopes ##
|
||||||
scope :templatized, :where => { :templatized => true }
|
# scope :templatized, :where => { :templatized => true }
|
||||||
|
#
|
||||||
## virtual attributes ##
|
# ## virtual attributes ##
|
||||||
attr_accessor :content_entry
|
# attr_accessor :content_entry
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
# Returns the class specified by the target_klass_name property
|
# # Returns the class specified by the target_klass_name property
|
||||||
#
|
# #
|
||||||
# @example
|
# # @example
|
||||||
#
|
# #
|
||||||
# page.target_klass_name = 'Locomotive::Entry12345'
|
# # page.target_klass_name = 'Locomotive::Entry12345'
|
||||||
# page.target_klass = Locomotive::Entry12345
|
# # page.target_klass = Locomotive::Entry12345
|
||||||
#
|
# #
|
||||||
# @return [ Class ] The target class
|
# # @return [ Class ] The target class
|
||||||
#
|
# #
|
||||||
def target_klass
|
# def target_klass
|
||||||
target_klass_name.constantize
|
# target_klass_name.constantize
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
# Gives the name which can be used in a liquid template in order
|
# # Gives the name which can be used in a liquid template in order
|
||||||
# to reference an entry. It uses the slug property if the target klass
|
# # to reference an entry. It uses the slug property if the target klass
|
||||||
# is a Locomotive content type or the class name itself for the other classes.
|
# # is a Locomotive content type or the class name itself for the other classes.
|
||||||
#
|
# #
|
||||||
# @example
|
# # @example
|
||||||
#
|
# #
|
||||||
# page.target_klass_name = 'Locomotive::Entry12345' # related to the content type Articles
|
# # page.target_klass_name = 'Locomotive::Entry12345' # related to the content type Articles
|
||||||
# page.target_entry_name = 'article'
|
# # page.target_entry_name = 'article'
|
||||||
#
|
# #
|
||||||
# page.target_klass_name = 'OurProduct'
|
# # page.target_klass_name = 'OurProduct'
|
||||||
# page.target_entry_name = 'our_product'
|
# # page.target_entry_name = 'our_product'
|
||||||
#
|
# #
|
||||||
# @return [ String ] The name in lowercase and underscored
|
# # @return [ String ] The name in lowercase and underscored
|
||||||
#
|
# #
|
||||||
def target_entry_name
|
# def target_entry_name
|
||||||
if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
# if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
||||||
@content_type ||= self.site.content_types.find($1)
|
# @content_type ||= self.site.content_types.find($1)
|
||||||
@content_type.slug.singularize
|
# @content_type.slug.singularize
|
||||||
else
|
# else
|
||||||
self.target_klass_name.underscore
|
# self.target_klass_name.underscore
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
# Finds the entry both specified by the target klass and identified by the permalink
|
# # Finds the entry both specified by the target klass and identified by the permalink
|
||||||
#
|
# #
|
||||||
# @param [ String ] permalink The permalink of the entry
|
# # @param [ String ] permalink The permalink of the entry
|
||||||
#
|
# #
|
||||||
# @return [ Object ] The document
|
# # @return [ Object ] The document
|
||||||
#
|
# #
|
||||||
def fetch_target_entry(permalink)
|
# def fetch_target_entry(permalink)
|
||||||
target_klass.find_by_permalink(permalink)
|
# target_klass.find_by_permalink(permalink)
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
protected
|
# protected
|
||||||
|
#
|
||||||
def get_templatized_from_parent
|
# def get_templatized_from_parent
|
||||||
return if self.parent.nil?
|
# return if self.parent.nil?
|
||||||
|
#
|
||||||
if self.parent.templatized?
|
# if self.parent.templatized?
|
||||||
self.templatized = self.templatized_from_parent = true
|
# self.templatized = self.templatized_from_parent = true
|
||||||
self.target_klass_name = self.parent.target_klass_name
|
# self.target_klass_name = self.parent.target_klass_name
|
||||||
elsif !self.templatized?
|
# elsif !self.templatized?
|
||||||
self.templatized = self.templatized_from_parent = false
|
# self.templatized = self.templatized_from_parent = false
|
||||||
self.target_klass_name = nil
|
# self.target_klass_name = nil
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
def set_slug_if_templatized
|
# def set_slug_if_templatized
|
||||||
self.slug = 'content_type_template' if self.templatized? && !self.templatized_from_parent?
|
# self.slug = 'content_type_template' if self.templatized? && !self.templatized_from_parent?
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
# Makes sure the target_klass is owned by the site OR
|
# # Makes sure the target_klass is owned by the site OR
|
||||||
# if it belongs to the models allowed by the application
|
# # if it belongs to the models allowed by the application
|
||||||
# thanks to the models_for_templatization option.
|
# # thanks to the models_for_templatization option.
|
||||||
#
|
# #
|
||||||
def ensure_target_klass_name_security
|
# def ensure_target_klass_name_security
|
||||||
return if !self.templatized? || self.target_klass_name.blank?
|
# return if !self.templatized? || self.target_klass_name.blank?
|
||||||
|
#
|
||||||
if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
# if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
||||||
content_type = Locomotive::ContentType.find($1)
|
# content_type = Locomotive::ContentType.find($1)
|
||||||
|
#
|
||||||
if content_type.site_id != self.site_id
|
# if content_type.site_id != self.site_id
|
||||||
self.errors.add :target_klass_name, :security
|
# self.errors.add :target_klass_name, :security
|
||||||
end
|
# end
|
||||||
elsif !Locomotive.config.models_for_templatization.include?(self.target_klass_name)
|
# elsif !Locomotive.config.models_for_templatization.include?(self.target_klass_name)
|
||||||
self.errors.add :target_klass_name, :security
|
# self.errors.add :target_klass_name, :security
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
# Sets the templatized, templatized_from_parent properties of
|
# # Sets the templatized, templatized_from_parent properties of
|
||||||
# the children of the current page ONLY IF the templatized
|
# # the children of the current page ONLY IF the templatized
|
||||||
# attribute got changed.
|
# # attribute got changed.
|
||||||
#
|
# #
|
||||||
def propagate_templatized
|
# def propagate_templatized
|
||||||
return unless self.templatized_changed?
|
# return unless self.templatized_changed?
|
||||||
|
#
|
||||||
selector = { 'parent_ids' => { '$in' => [self._id] } }
|
# selector = { 'parent_ids' => { '$in' => [self._id] } }
|
||||||
operations = {
|
# operations = {
|
||||||
'$set' => {
|
# '$set' => {
|
||||||
'templatized' => self.templatized,
|
# 'templatized' => self.templatized,
|
||||||
'templatized_from_parent' => self.templatized,
|
# 'templatized_from_parent' => self.templatized,
|
||||||
'target_klass_name' => self.target_klass_name
|
# 'target_klass_name' => self.target_klass_name
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
|
#
|
||||||
self.collection.update selector, operations, :multi => true
|
# self.collection.update selector, operations, :multi => true
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
end
|
# end
|
||||||
|
|
|
@ -77,6 +77,10 @@ module Locomotive
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# def autosave_for_children?
|
||||||
|
# @autosave_for_children != false
|
||||||
|
# end
|
||||||
|
|
||||||
# Returns the children of this node but with the minimal set of required attributes
|
# Returns the children of this node but with the minimal set of required attributes
|
||||||
#
|
#
|
||||||
# @return [ Array ] The children pages ordered by their position
|
# @return [ Array ] The children pages ordered by their position
|
||||||
|
|
|
@ -56,6 +56,10 @@ module Locomotive
|
||||||
self.locales_was.first || Locomotive.config.site_locales.first
|
self.locales_was.first || Locomotive.config.site_locales.first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_locale_changed?
|
||||||
|
self.default_locale != self.default_locale_was
|
||||||
|
end
|
||||||
|
|
||||||
def locale_fallbacks(locale)
|
def locale_fallbacks(locale)
|
||||||
[locale.to_s] + (locales - [locale.to_s])
|
[locale.to_s] + (locales - [locale.to_s])
|
||||||
end
|
end
|
||||||
|
@ -93,4 +97,22 @@ module Locomotive
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# %w(index 404).each do |slug|
|
||||||
|
# page = self.pages.where("slug.#{self.default_locale}" => slug).first
|
||||||
|
#
|
||||||
|
# self.locales.each do |locale|
|
||||||
|
# if .blank?
|
||||||
|
# page.collection.update({ :_id => page._id }, { '$set' => { "slug.#{locale}" => slug } })
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# if page.attributes['title'][locale.to_s].blank?
|
||||||
|
# page.collection.update({ :_id => page._id }, {
|
||||||
|
# '$set' => { "title.#{locale}" => }
|
||||||
|
# })
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
|
@ -8,7 +8,7 @@ module Locomotive
|
||||||
include Extensions::Page::EditableElements
|
include Extensions::Page::EditableElements
|
||||||
include Extensions::Page::Parse
|
include Extensions::Page::Parse
|
||||||
include Extensions::Page::Render
|
include Extensions::Page::Render
|
||||||
include Extensions::Page::Templatized
|
include Extensions::Page::Fullpath
|
||||||
include Extensions::Page::Redirect
|
include Extensions::Page::Redirect
|
||||||
include Extensions::Page::Listed
|
include Extensions::Page::Listed
|
||||||
include Extensions::Shared::Seo
|
include Extensions::Shared::Seo
|
||||||
|
@ -16,7 +16,6 @@ module Locomotive
|
||||||
## fields ##
|
## fields ##
|
||||||
field :title, :localize => true
|
field :title, :localize => true
|
||||||
field :slug, :localize => true
|
field :slug, :localize => true
|
||||||
field :fullpath, :localize => true
|
|
||||||
field :handle
|
field :handle
|
||||||
field :raw_template, :localize => true
|
field :raw_template, :localize => true
|
||||||
field :locales, :type => Array
|
field :locales, :type => Array
|
||||||
|
@ -35,14 +34,13 @@ module Locomotive
|
||||||
## callbacks ##
|
## callbacks ##
|
||||||
after_initialize :set_default_raw_template
|
after_initialize :set_default_raw_template
|
||||||
before_validation :normalize_slug
|
before_validation :normalize_slug
|
||||||
before_save :build_fullpath
|
|
||||||
before_save :record_current_locale
|
before_save :record_current_locale
|
||||||
before_destroy :do_not_remove_index_and_404_pages
|
before_destroy :do_not_remove_index_and_404_pages
|
||||||
|
|
||||||
## validations ##
|
## validations ##
|
||||||
validates_presence_of :site, :title, :slug
|
validates_presence_of :site, :title, :slug
|
||||||
validates_uniqueness_of :slug, :scope => [:site_id, :parent_id]
|
validates_uniqueness_of :slug, :scope => [:site_id, :parent_id]
|
||||||
validates_uniqueness_of :handle, :allow_blank => true
|
validates_uniqueness_of :handle, :allow_blank => true, :scope => [:site_id]
|
||||||
validates_exclusion_of :slug, :in => Locomotive.config.reserved_slugs, :if => Proc.new { |p| p.depth <= 1 }
|
validates_exclusion_of :slug, :in => Locomotive.config.reserved_slugs, :if => Proc.new { |p| p.depth <= 1 }
|
||||||
|
|
||||||
## named scopes ##
|
## named scopes ##
|
||||||
|
@ -50,10 +48,8 @@ module Locomotive
|
||||||
scope :root, :where => { :slug => 'index', :depth => 0 }
|
scope :root, :where => { :slug => 'index', :depth => 0 }
|
||||||
scope :not_found, :where => { :slug => '404', :depth => 0 }
|
scope :not_found, :where => { :slug => '404', :depth => 0 }
|
||||||
scope :published, :where => { :published => true }
|
scope :published, :where => { :published => true }
|
||||||
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 response_type parent_id parent_ids site_id created_at updated_at) } }
|
scope :minimal_attributes, lambda { |attrs = []| { :only => (attrs || []) + %w(title slug fullpath position depth published with_wildcards redirect listed wildcard response_type parent_id parent_ids site_id created_at updated_at) } }
|
||||||
scope :dependent_from, lambda { |id| { :where => { :template_dependencies.in => [id] } } }
|
|
||||||
|
|
||||||
## methods ##
|
## methods ##
|
||||||
|
|
||||||
|
@ -114,16 +110,6 @@ module Locomotive
|
||||||
self.raw_template ||= ::I18n.t('attributes.defaults.pages.other.body')
|
self.raw_template ||= ::I18n.t('attributes.defaults.pages.other.body')
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_fullpath
|
|
||||||
if self.index? || self.not_found?
|
|
||||||
self.fullpath = self.slug
|
|
||||||
else
|
|
||||||
slugs = self.ancestors_and_self.map(&:slug)
|
|
||||||
slugs.shift unless slugs.size == 1
|
|
||||||
self.fullpath = File.join slugs.compact
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def record_current_locale
|
def record_current_locale
|
||||||
self.locales ||= []
|
self.locales ||= []
|
||||||
self.locales << ::Mongoid::Fields::I18n.locale
|
self.locales << ::Mongoid::Fields::I18n.locale
|
||||||
|
|
|
@ -64,20 +64,21 @@ module Locomotive
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
# FIXME: Currently there is no t/translate method on the I18n module
|
# FIXME: Currently there is no t/translate method on the
|
||||||
# Extensions::Site::I18n which is breaking the testing. The
|
# Extensions::Site::I18n module which is breaking the testing. The
|
||||||
# namespaced ::I18n should be changed to just I18n when the t()
|
# namespaced ::I18n should be replaced by simply I18n when the t()
|
||||||
# method is available
|
# method will be available.
|
||||||
def create_default_pages!
|
def create_default_pages!
|
||||||
::Mongoid::Fields::I18n.with_locale(self.default_locale) do
|
%w(index 404).each do |slug|
|
||||||
%w{index 404}.each do |slug|
|
page = self.pages.build(:title => '', :slug => '', :raw_template => '', :published => true)
|
||||||
self.pages.create({
|
|
||||||
:slug => slug,
|
self.locales.each do |locale|
|
||||||
:title => ::I18n.t("attributes.defaults.pages.#{slug}.title"),
|
page.attributes['slug'][locale] = slug
|
||||||
:raw_template => ::I18n.t("attributes.defaults.pages.#{slug}.body"),
|
page.attributes['title'][locale] = ::I18n.t("attributes.defaults.pages.#{slug}.title", :locale => locale)
|
||||||
:published => true
|
page.attributes['raw_template'][locale] = ::I18n.t("attributes.defaults.pages.#{slug}.body", :locale => locale)
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
page.save
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module Locomotive
|
module Locomotive
|
||||||
class PagePresenter < BasePresenter
|
class PagePresenter < BasePresenter
|
||||||
|
|
||||||
delegate :title, :slug, :fullpath, :handle, :raw_template, :published, :listed, :templatized, :templatized_from_parent, :redirect, :redirect_url, :template_changed, :cache_strategy, :response_type, :to => :source
|
delegate :title, :slug, :fullpath, :handle, :raw_template, :published, :listed, :wildcard, :wildcards, :redirect, :redirect_url, :template_changed, :cache_strategy, :response_type, :to => :source
|
||||||
|
|
||||||
def escaped_raw_template
|
def escaped_raw_template
|
||||||
h(self.source.raw_template)
|
h(self.source.raw_template)
|
||||||
|
@ -12,7 +12,7 @@ module Locomotive
|
||||||
end
|
end
|
||||||
|
|
||||||
def included_methods
|
def included_methods
|
||||||
super + %w(title slug fullpath handle raw_template published listed templatized templatized_from_parent redirect redirect_url cache_strategy response_type template_changed editable_elements localized_fullpaths)
|
super + %w(title slug fullpath handle raw_template published listed wildcard wildcards redirect redirect_url cache_strategy response_type template_changed editable_elements localized_fullpaths)
|
||||||
end
|
end
|
||||||
|
|
||||||
def localized_fullpaths
|
def localized_fullpaths
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
- if not @page.index? and not @page.not_found?
|
- if not @page.index? and not @page.not_found?
|
||||||
= f.input :parent_id, :as => :select, :collection => parent_pages_options, :include_blank => false
|
= f.input :parent_id, :as => :select, :collection => parent_pages_options, :include_blank => false
|
||||||
|
|
||||||
= f.input :slug, :required => false, :hint => @page.slug.blank? ? t('.empty_slug') : public_page_url(@page), :input_html => { :'data-url' => get_path_pages_url, :disabled => @page.index? || @page.not_found? }, :wrapper_html => { :style => "#{'display: none' if @page.templatized? && !@page.templatized_from_parent?};", :class => 'em-inline-hints' }
|
= f.input :slug, :required => false, :hint => @page.slug.blank? ? t('.empty_slug') : public_page_url(@page), :input_html => { :'data-url' => get_path_pages_url, :disabled => @page.index? || @page.not_found? }, :class => 'em-inline-hints'
|
||||||
|
|
||||||
= f.inputs :name => :seo, :class => "inputs foldable #{'folded' if inputs_folded?(@page)}" do
|
= f.inputs :name => :seo, :class => "inputs foldable #{'folded' if inputs_folded?(@page)}" do
|
||||||
|
|
||||||
|
@ -34,15 +34,13 @@
|
||||||
|
|
||||||
= f.input :response_type, :as => :select, :collection => options_for_page_response_type, :include_blank => false
|
= f.input :response_type, :as => :select, :collection => options_for_page_response_type, :include_blank => false
|
||||||
|
|
||||||
= f.input :templatized, :as => :'Locomotive::Toggle', :style => "#{'display: none' if @page.redirect? || @page.templatized_from_parent?}"
|
= f.input :wildcard, :as => :'Locomotive::Toggle', :style => "#{'display: none' if @page.redirect?}"
|
||||||
|
|
||||||
= f.input :target_klass_name, :as => :select, :collection => options_for_target_klass_name, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if !@page.templatized? || @page.templatized_from_parent?}" }
|
|
||||||
|
|
||||||
= f.input :published, :as => :'Locomotive::Toggle'
|
= f.input :published, :as => :'Locomotive::Toggle'
|
||||||
|
|
||||||
= f.input :listed, :as => :'Locomotive::Toggle'
|
= f.input :listed, :as => :'Locomotive::Toggle', :wrapper_html => { :style => "#{'display: none' if @page.has_wildcards?}" }
|
||||||
|
|
||||||
= f.input :redirect, :as => :'Locomotive::Toggle', :wrapper_html => { :style => "#{'display: none' if @page.templatized? || !@page.default_response_type?}" }
|
= f.input :redirect, :as => :'Locomotive::Toggle', :wrapper_html => { :style => "#{'display: none' if !@page.default_response_type? || @page.has_wildcards?}" }
|
||||||
|
|
||||||
= f.input :cache_strategy, :as => :select, :collection => options_for_page_cache_strategy, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if @page.redirect?}" }
|
= f.input :cache_strategy, :as => :select, :collection => options_for_page_cache_strategy, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if @page.redirect?}" }
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
%li{ :id => "item-#{page.id}", :class => "page #{css_for_page(page)}" }
|
%li{ :id => "item-#{page.id}", :class => "page #{css_for_page(page)}" }
|
||||||
|
|
||||||
- children = can?(:manage, page) ? page.children : page.children.find_all { |p| !p.templatized? }
|
- children = page.children
|
||||||
|
|
||||||
- with_children = !children.empty?
|
- with_children = !children.empty?
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,8 @@ xml.urlset "xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9" do
|
||||||
|
|
||||||
@pages.each do |page|
|
@pages.each do |page|
|
||||||
if not page.index_or_not_found?
|
if not page.index_or_not_found?
|
||||||
if page.templatized?
|
if page.wildcard?
|
||||||
page.content_type.entries.visible.each do |c|
|
# FIXME (Didier L.) unable for now to generate all the pages
|
||||||
xml.url do
|
|
||||||
xml.loc page_url(page, { :content => c, :host => true })
|
|
||||||
xml.lastmod c.updated_at.to_date.to_s('%Y-%m-%d')
|
|
||||||
xml.priority 0.9
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
xml.url do
|
xml.url do
|
||||||
xml.loc page_url(page, { :host => true })
|
xml.loc page_url(page, { :host => true })
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
Haml::Template.options[:format] = :html5
|
Haml::Template.options[:format] = :html5
|
||||||
Haml::Template.options[:ugly] = true # improve performance in dev
|
Haml::Template.options[:ugly] = true # improve performance in dev
|
||||||
|
|
|
@ -57,7 +57,7 @@ de:
|
||||||
title: Titel
|
title: Titel
|
||||||
parent: Parent
|
parent: Parent
|
||||||
slug: Slug
|
slug: Slug
|
||||||
templatized: Templatized
|
wildcard: Wildcard
|
||||||
published: Veröffentlicht
|
published: Veröffentlicht
|
||||||
listed: Im Menü
|
listed: Im Menü
|
||||||
redirect: Umleitung
|
redirect: Umleitung
|
||||||
|
|
|
@ -58,7 +58,7 @@ es:
|
||||||
parent_id: Padre
|
parent_id: Padre
|
||||||
slug: Enlace
|
slug: Enlace
|
||||||
listed: Menu
|
listed: Menu
|
||||||
templatized: Templatizada
|
wildcard: Wildcard
|
||||||
published: Publicada
|
published: Publicada
|
||||||
redirect: Redirección
|
redirect: Redirección
|
||||||
redirect_url: Url de redirección
|
redirect_url: Url de redirección
|
||||||
|
|
|
@ -60,7 +60,7 @@ fr:
|
||||||
parent_id: Dossier parent
|
parent_id: Dossier parent
|
||||||
slug: Raccourci
|
slug: Raccourci
|
||||||
listed: Menu
|
listed: Menu
|
||||||
templatized: Templatisée
|
wildcard: Wildcard
|
||||||
published: Publiée
|
published: Publiée
|
||||||
redirect: Redirection
|
redirect: Redirection
|
||||||
redirect_url: Url de redirection
|
redirect_url: Url de redirection
|
||||||
|
|
|
@ -64,7 +64,7 @@ it:
|
||||||
parent_id: Pagina superiore
|
parent_id: Pagina superiore
|
||||||
slug: Slug
|
slug: Slug
|
||||||
listed: In menù
|
listed: In menù
|
||||||
templatized: Templatized
|
wildcard: Wildcard
|
||||||
published: Pubblicata
|
published: Pubblicata
|
||||||
redirect: Redirezione
|
redirect: Redirezione
|
||||||
redirect_url: Url di redirezione
|
redirect_url: Url di redirezione
|
||||||
|
|
|
@ -221,7 +221,7 @@
|
||||||
parent: Tilhører
|
parent: Tilhører
|
||||||
parent_id: Tilhører
|
parent_id: Tilhører
|
||||||
slug: Slug
|
slug: Slug
|
||||||
templatized: Templatized
|
wildcard: Wildcard
|
||||||
published: Publisert
|
published: Publisert
|
||||||
listed: I meny
|
listed: I meny
|
||||||
redirect: Videresending
|
redirect: Videresending
|
||||||
|
|
|
@ -60,7 +60,7 @@ pt-BR:
|
||||||
title: Título
|
title: Título
|
||||||
parent: Pai
|
parent: Pai
|
||||||
slug: Slug
|
slug: Slug
|
||||||
templatized: Template
|
wildcard: Wildcard
|
||||||
published: Publicado
|
published: Publicado
|
||||||
cache_strategy: Cache
|
cache_strategy: Cache
|
||||||
content_type:
|
content_type:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
ru:
|
ru:
|
||||||
errors:
|
errors:
|
||||||
messages:
|
messages:
|
||||||
domain_taken: "%{value} уже занято"
|
domain_taken: "%{value} уже занято"
|
||||||
|
@ -15,7 +15,7 @@ ru:
|
||||||
liquid_extend: "Страница '%{fullpath}' наследует (расширяет) несуществующий шаблон"
|
liquid_extend: "Страница '%{fullpath}' наследует (расширяет) несуществующий шаблон"
|
||||||
liquid_translation: "Страница '%{fullpath}' наследует (расширяет) непереведенный шаблон"
|
liquid_translation: "Страница '%{fullpath}' наследует (расширяет) непереведенный шаблон"
|
||||||
too_few_custom_fields: "По крайней мере одно поле является обязательным"
|
too_few_custom_fields: "По крайней мере одно поле является обязательным"
|
||||||
security: "проблема безопасности"
|
security: "проблема безопасности"
|
||||||
|
|
||||||
attributes:
|
attributes:
|
||||||
defaults:
|
defaults:
|
||||||
|
@ -35,7 +35,7 @@ ru:
|
||||||
title: Имя
|
title: Имя
|
||||||
parent: Родитель
|
parent: Родитель
|
||||||
slug: Ссылка
|
slug: Ссылка
|
||||||
templatized: Шаблонизирована
|
wildcard: Wildcard
|
||||||
published: Опубликована
|
published: Опубликована
|
||||||
listed: Меню
|
listed: Меню
|
||||||
redirect: Перенаправлена
|
redirect: Перенаправлена
|
||||||
|
@ -89,7 +89,7 @@ ru:
|
||||||
default: "%d.%m.%Y"
|
default: "%d.%m.%Y"
|
||||||
short: "%d %b"
|
short: "%d %b"
|
||||||
long: "%d %B %Y"
|
long: "%d %B %Y"
|
||||||
|
|
||||||
# Названия дней недели -- контекстные и отдельностоящие
|
# Названия дней недели -- контекстные и отдельностоящие
|
||||||
day_names: [воскресенье, понедельник, вторник, среда, четверг, пятница, суббота]
|
day_names: [воскресенье, понедельник, вторник, среда, четверг, пятница, суббота]
|
||||||
standalone_day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
|
standalone_day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
|
||||||
|
@ -97,19 +97,19 @@ ru:
|
||||||
|
|
||||||
# Названия месяцев -- сокращенные и полные, плюс отдельностоящие.
|
# Названия месяцев -- сокращенные и полные, плюс отдельностоящие.
|
||||||
# Не забудьте nil в начале массиве (~)
|
# Не забудьте nil в начале массиве (~)
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Don't forget the nil at the beginning; there's no such thing as a 0th month
|
# Don't forget the nil at the beginning; there's no such thing as a 0th month
|
||||||
month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря]
|
month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря]
|
||||||
standalone_month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
|
standalone_month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
|
||||||
abbr_month_names: [~, янв., февр., марта, апр., мая, июня, июля, авг., сент., окт., нояб., дек.]
|
abbr_month_names: [~, янв., февр., марта, апр., мая, июня, июля, авг., сент., окт., нояб., дек.]
|
||||||
standalone_abbr_month_names: [~, янв., февр., март, апр., май, июнь, июль, авг., сент., окт., нояб., дек.]
|
standalone_abbr_month_names: [~, янв., февр., март, апр., май, июнь, июль, авг., сент., окт., нояб., дек.]
|
||||||
|
|
||||||
# Порядок компонентов даты для хелперов
|
# Порядок компонентов даты для хелперов
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Used in date_select and datime_select.
|
# Used in date_select and datime_select.
|
||||||
order:
|
order:
|
||||||
- :day
|
- :day
|
||||||
- :month
|
- :month
|
||||||
- :year
|
- :year
|
||||||
|
@ -120,7 +120,7 @@ ru:
|
||||||
default: "%a, %d %b %Y, %H:%M:%S %z"
|
default: "%a, %d %b %Y, %H:%M:%S %z"
|
||||||
short: "%d %b, %H:%M"
|
short: "%d %b, %H:%M"
|
||||||
long: "%d %B %Y, %H:%M"
|
long: "%d %B %Y, %H:%M"
|
||||||
|
|
||||||
# am/pm решено перевести как "утра/вечера" :)
|
# am/pm решено перевести как "утра/вечера" :)
|
||||||
am: "утра"
|
am: "утра"
|
||||||
pm: "вечера"
|
pm: "вечера"
|
||||||
|
@ -138,7 +138,7 @@ ru:
|
||||||
delimiter: " "
|
delimiter: " "
|
||||||
# Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
|
# Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
|
||||||
precision: 3
|
precision: 3
|
||||||
|
|
||||||
# Used in number_to_currency()
|
# Used in number_to_currency()
|
||||||
currency:
|
currency:
|
||||||
format:
|
format:
|
||||||
|
@ -152,14 +152,14 @@ ru:
|
||||||
separator: "."
|
separator: "."
|
||||||
delimiter: " "
|
delimiter: " "
|
||||||
precision: 2
|
precision: 2
|
||||||
|
|
||||||
# Used in number_to_percentage()
|
# Used in number_to_percentage()
|
||||||
percentage:
|
percentage:
|
||||||
format:
|
format:
|
||||||
# These three are to override number.format and are optional
|
# These three are to override number.format and are optional
|
||||||
# separator:
|
# separator:
|
||||||
delimiter: ""
|
delimiter: ""
|
||||||
|
|
||||||
# Used in number_to_precision()
|
# Used in number_to_precision()
|
||||||
precision:
|
precision:
|
||||||
format:
|
format:
|
||||||
|
@ -167,18 +167,18 @@ ru:
|
||||||
# separator:
|
# separator:
|
||||||
delimiter: ""
|
delimiter: ""
|
||||||
# precision:
|
# precision:
|
||||||
|
|
||||||
# Used in number_to_human_size()
|
# Used in number_to_human_size()
|
||||||
human:
|
human:
|
||||||
format:
|
format:
|
||||||
# These three are to override number.format and are optional
|
# These three are to override number.format and are optional
|
||||||
# separator:
|
# separator:
|
||||||
delimiter: ""
|
delimiter: ""
|
||||||
precision: 1
|
precision: 1
|
||||||
|
|
||||||
# Rails 2.2
|
# Rails 2.2
|
||||||
# storage_units: [байт, КБ, МБ, ГБ, ТБ]
|
# storage_units: [байт, КБ, МБ, ГБ, ТБ]
|
||||||
|
|
||||||
# Rails 2.3
|
# Rails 2.3
|
||||||
storage_units:
|
storage_units:
|
||||||
# Storage units output formatting.
|
# Storage units output formatting.
|
||||||
|
@ -272,7 +272,7 @@ ru:
|
||||||
# Rails 2.2
|
# Rails 2.2
|
||||||
sentence_connector: "и"
|
sentence_connector: "и"
|
||||||
skip_last_comma: true
|
skip_last_comma: true
|
||||||
|
|
||||||
# Rails 2.3
|
# Rails 2.3
|
||||||
words_connector: ", "
|
words_connector: ", "
|
||||||
two_words_connector: " и "
|
two_words_connector: " и "
|
||||||
|
|
|
@ -55,9 +55,7 @@ de:
|
||||||
page:
|
page:
|
||||||
published: "Nur authentifizierte Accounts können nicht publizierte Seiten ansehen."
|
published: "Nur authentifizierte Accounts können nicht publizierte Seiten ansehen."
|
||||||
cache_strategy: "Cache die Seiten, um eine bessere Geschwindigkeit zu erzielen. Die 'Einfach' Option ist ein guter Kompromiss."
|
cache_strategy: "Cache die Seiten, um eine bessere Geschwindigkeit zu erzielen. Die 'Einfach' Option ist ein guter Kompromiss."
|
||||||
templatized: "Nutze diese Seite als Vorlage für einen Baustein, den du erstellt hast."
|
|
||||||
listed: "Regele, ob die Seite in den generierten Menüs angezeigt werden soll."
|
listed: "Regele, ob die Seite in den generierten Menüs angezeigt werden soll."
|
||||||
content_type_id: "Der Baustein für den diese Seite als Vorlage dienen soll."
|
|
||||||
seo_title: "Wähle einen Titel für den 'title' Tag im Seiten Header. Lass es leer, wenn der Seitentitel verwendet werden soll."
|
seo_title: "Wähle einen Titel für den 'title' Tag im Seiten Header. Lass es leer, wenn der Seitentitel verwendet werden soll."
|
||||||
meta_keywords: "Meta-Schlagworte, die im HEAD-Bereich der Webseite genutzt werden. Die einzelnen Wörter werden durch eine Leertaste getrennt. Diese werden für die Suchmaschinen benötigt."
|
meta_keywords: "Meta-Schlagworte, die im HEAD-Bereich der Webseite genutzt werden. Die einzelnen Wörter werden durch eine Leertaste getrennt. Diese werden für die Suchmaschinen benötigt."
|
||||||
meta_description: "Meta-Beschreibung, die im HEAD-Bereich der Webseite genutzt wird. Diese wird für die Suchmaschinen benötigt."
|
meta_description: "Meta-Beschreibung, die im HEAD-Bereich der Webseite genutzt wird. Diese wird für die Suchmaschinen benötigt."
|
||||||
|
|
|
@ -57,9 +57,8 @@ en:
|
||||||
handle: "Unique identifier to retrieve this page within an external controller instance"
|
handle: "Unique identifier to retrieve this page within an external controller instance"
|
||||||
published: "Only authenticated accounts can view unpublished pages."
|
published: "Only authenticated accounts can view unpublished pages."
|
||||||
cache_strategy: "Cache the page for better performance. The 'Simple' choice is a good compromise."
|
cache_strategy: "Cache the page for better performance. The 'Simple' choice is a good compromise."
|
||||||
templatized: "Use the page as a template for a model you defined."
|
wildcard: "Make the page have a wildcard segment in its path. Then the slug will be used as the name of the wildcard in the template"
|
||||||
listed: "Control whether to show the page from generated menus."
|
listed: "Control whether to show the page from generated menus."
|
||||||
target_klass_name: "The type of content this page will be a template for."
|
|
||||||
seo_title: "Define a page title which should be used as the value for the title tag in the head section. Leave it empty if you want to use the default value from the site settings."
|
seo_title: "Define a page title which should be used as the value for the title tag in the head section. Leave it empty if you want to use the default value from the site settings."
|
||||||
meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma."
|
meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma."
|
||||||
meta_description: "Overrides the site's meta description used within the head tag of the page."
|
meta_description: "Overrides the site's meta description used within the head tag of the page."
|
||||||
|
@ -84,7 +83,7 @@ en:
|
||||||
source: "The current file is available here %{url}"
|
source: "The current file is available here %{url}"
|
||||||
content_entry:
|
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 }})\"."
|
_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."
|
seo_title: "The value you fill in can be used to replace the SEO title in any pages."
|
||||||
meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma."
|
meta_keywords: "Overrides the site's meta keywords used within the head tag of the page. They are separated by a comma."
|
||||||
meta_description: "Overrides the site's meta description used within the head tag of the page."
|
meta_description: "Overrides the site's meta description used within the head tag of the page."
|
||||||
import:
|
import:
|
||||||
|
|
|
@ -49,9 +49,7 @@ es:
|
||||||
page:
|
page:
|
||||||
published: "Las páginas no publicadas son únicamente visibles tras iniciar sesión."
|
published: "Las páginas no publicadas son únicamente visibles tras iniciar sesión."
|
||||||
cache_strategy: "Utilizar una caché de página para un mejor rendimiento. La opción 'Simple' es un buen compromiso."
|
cache_strategy: "Utilizar una caché de página para un mejor rendimiento. La opción 'Simple' es un buen compromiso."
|
||||||
templatized: "Usar la página como plantilla de un modelo."
|
|
||||||
listed: "Controla si la página se enseña o no en los menús."
|
listed: "Controla si la página se enseña o no en los menús."
|
||||||
content_type_id: "El modelo del cual será una plantilla esta página."
|
|
||||||
meta_keywords: "Reescribir las palabras clave SEO utilizadas en la cabecera de la página. Deben estar separadas por comas."
|
meta_keywords: "Reescribir las palabras clave SEO utilizadas en la cabecera de la página. Deben estar separadas por comas."
|
||||||
meta_description: "Reescribir la metadescripción que se utiliza en la cabecera de la página."
|
meta_description: "Reescribir la metadescripción que se utiliza en la cabecera de la página."
|
||||||
snippet:
|
snippet:
|
||||||
|
|
|
@ -53,9 +53,8 @@ fr:
|
||||||
page:
|
page:
|
||||||
published: "Seuls les administrateurs authentifiés peuvent voir une page non publiée."
|
published: "Seuls les administrateurs authentifiés peuvent voir une page non publiée."
|
||||||
cache_strategy: "Cache la page pour de meilleure performance. L'option 'Simple' est le meilleur compromis."
|
cache_strategy: "Cache la page pour de meilleure performance. L'option 'Simple' est le meilleur compromis."
|
||||||
templatized: "Utilise la page comme un template pour un modèle défini."
|
wildcard: "Détermine si la page aura la dernière partie de son URL dynamique. Si oui, le slug sera utilisé comme nom du segment dans le template."
|
||||||
listed: "Controle si la page doit être visible depuis les menus automatiquement générés."
|
listed: "Controle si la page doit être visible depuis les menus automatiquement générés."
|
||||||
target_klass_name: "Le type du contenu pour lequel cette page est un template."
|
|
||||||
seo_title: "Définit un titre de page à mettre dans la balise TITLE de la page. Laissez le blanc pour utiliser la valeur par défaut (voir configuration du site)."
|
seo_title: "Définit un titre de page à mettre dans la balise TITLE de la page. Laissez le blanc pour utiliser la valeur par défaut (voir configuration du site)."
|
||||||
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."
|
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."
|
||||||
meta_description: "Redéfinit la description du site. Utilisée à l'intérieur de la balise HEAD."
|
meta_description: "Redéfinit la description du site. Utilisée à l'intérieur de la balise HEAD."
|
||||||
|
|
|
@ -55,9 +55,7 @@ it:
|
||||||
page:
|
page:
|
||||||
published: "Solo gli account autenticati possono visualizzare le pagine non pubblicate."
|
published: "Solo gli account autenticati possono visualizzare le pagine non pubblicate."
|
||||||
cache_strategy: "Attiva il cache della pagina per miglirare le prestazioni. L'opzione 'Semplice' è un buon compromesso."
|
cache_strategy: "Attiva il cache della pagina per miglirare le prestazioni. L'opzione 'Semplice' è un buon compromesso."
|
||||||
templatized: "Utilizzare la pagina come template per un modello che hai definito."
|
|
||||||
listed: "Determina se la pagina deve essere mostrata nei menù generati."
|
listed: "Determina se la pagina deve essere mostrata nei menù generati."
|
||||||
content_type_id: "Il tipo di contenuto di cui questa pagina sarà il template."
|
|
||||||
seo_title: "Definisce il titolo della pagina inserito nel tag title della sezione head. Lascia vuoto se vuoi che venga utilizzato il titolo definito per il sito."
|
seo_title: "Definisce il titolo della pagina inserito nel tag title della sezione head. Lascia vuoto se vuoi che venga utilizzato il titolo definito per il sito."
|
||||||
meta_keywords: "Sovrascrive per questa pagina le meta keywords definite per il sito all'interno del tag head della pagina. Sono separate da virgola."
|
meta_keywords: "Sovrascrive per questa pagina le meta keywords definite per il sito all'interno del tag head della pagina. Sono separate da virgola."
|
||||||
meta_description: "Sovrascrive per questa pagina la meta description definita per il sito."
|
meta_description: "Sovrascrive per questa pagina la meta description definita per il sito."
|
||||||
|
|
|
@ -49,9 +49,7 @@ nl:
|
||||||
page:
|
page:
|
||||||
published: "Alleen geauthenticeerde accounts kunnen niet gepubliceerde pagina's zien."
|
published: "Alleen geauthenticeerde accounts kunnen niet gepubliceerde pagina's zien."
|
||||||
cache_strategy: "Cache de pagina voor betere prestaties. De 'Simpele' keus is een goed compromis."
|
cache_strategy: "Cache de pagina voor betere prestaties. De 'Simpele' keus is een goed compromis."
|
||||||
templatized: "Gebruik de pagina als template voor een door u gedefinieerd model."
|
|
||||||
listed: "Controleer of de pagina getoond wordt van de gegenereerde menu's."
|
listed: "Controleer of de pagina getoond wordt van de gegenereerde menu's."
|
||||||
content_type_id: "Het type inhoud waar deze pagina als template voor dient"
|
|
||||||
meta_keywords: "Overschrijft de meta keywords van de website in de head tag van deze pagina. Gescheiden door een komma"
|
meta_keywords: "Overschrijft de meta keywords van de website in de head tag van deze pagina. Gescheiden door een komma"
|
||||||
meta_description: "Overschrijft de meta description van de website in de head tag van deze pagina."
|
meta_description: "Overschrijft de meta description van de website in de head tag van deze pagina."
|
||||||
snippet:
|
snippet:
|
||||||
|
|
|
@ -55,9 +55,7 @@
|
||||||
page:
|
page:
|
||||||
published: "Kun autoriserte kontoer kan se ikke-publiserte sider"
|
published: "Kun autoriserte kontoer kan se ikke-publiserte sider"
|
||||||
cache_strategy: "Buffre siden for å bedre ytelsen. \"Enkel\" er et bra kompromiss."
|
cache_strategy: "Buffre siden for å bedre ytelsen. \"Enkel\" er et bra kompromiss."
|
||||||
templatized: "Bruk denne siden som mal for en modell."
|
|
||||||
listed: "Styr om siden skal vises i de genererte menyene."
|
listed: "Styr om siden skal vises i de genererte menyene."
|
||||||
content_type_id: "Innholdstypen denne siden skal være mal for."
|
|
||||||
seo_title: "Definer en egen tittel for siden. Denne blir benyttet av nettleseren. Hvis denne står tom blir standardverdien fra sideinnstillingene benyttet."
|
seo_title: "Definer en egen tittel for siden. Denne blir benyttet av nettleseren. Hvis denne står tom blir standardverdien fra sideinnstillingene benyttet."
|
||||||
meta_keywords: "Overstyr søkemotor-metadata for denne siden. Separer med komma."
|
meta_keywords: "Overstyr søkemotor-metadata for denne siden. Separer med komma."
|
||||||
meta_description: "Overstyr søkemotorbeskrivelsen for denne siden."
|
meta_description: "Overstyr søkemotorbeskrivelsen for denne siden."
|
||||||
|
|
|
@ -46,7 +46,6 @@ pt-BR:
|
||||||
page:
|
page:
|
||||||
published: "Apenas contas autenticadas podem ver páginas não publicadas."
|
published: "Apenas contas autenticadas podem ver páginas não publicadas."
|
||||||
cache_strategy: 'Faça o Cache da página para obter melhor desempenho. A escolha do "Simples" é um bom compromisso'
|
cache_strategy: 'Faça o Cache da página para obter melhor desempenho. A escolha do "Simples" é um bom compromisso'
|
||||||
templatized: "Utilize a página como template para o modelo definido."
|
|
||||||
snippet:
|
snippet:
|
||||||
slug: "Você precisa saber a ordem para inserir fragmentos dentro da página."
|
slug: "Você precisa saber a ordem para inserir fragmentos dentro da página."
|
||||||
site:
|
site:
|
||||||
|
|
|
@ -57,9 +57,7 @@ ru:
|
||||||
handle: "Уникальный идентификатор для поиска этой страницы из экземпляра внешнего rails-контроллера"
|
handle: "Уникальный идентификатор для поиска этой страницы из экземпляра внешнего rails-контроллера"
|
||||||
published: "Только аутентифицированным пользователям разрешается просматривать неопубликованные страницы."
|
published: "Только аутентифицированным пользователям разрешается просматривать неопубликованные страницы."
|
||||||
cache_strategy: "Кэшировать страницу для лучшей производительности. Вариант 'Простое' является хорошим компромиссом."
|
cache_strategy: "Кэшировать страницу для лучшей производительности. Вариант 'Простое' является хорошим компромиссом."
|
||||||
templatized: "Используйте страницу в качестве шаблона для определенной вами модели."
|
|
||||||
listed: "Контролируйте возможность показа страницы из сгенерированных меню."
|
listed: "Контролируйте возможность показа страницы из сгенерированных меню."
|
||||||
target_klass_name: "Тип контента (модели), для которого эта страница будет выступать в качестве шаблона."
|
|
||||||
seo_title: "Определите заголовок страницы, который будет использоваться как значение тэга title в секции head. Оставьте пустым, если вы хотите использовать значение по умолчанию из настроек сайта."
|
seo_title: "Определите заголовок страницы, который будет использоваться как значение тэга title в секции head. Оставьте пустым, если вы хотите использовать значение по умолчанию из настроек сайта."
|
||||||
meta_keywords: "Переопределяет meta keywords сайта, используемые внутри тэга head страницы. Они разделены запятыми."
|
meta_keywords: "Переопределяет meta keywords сайта, используемые внутри тэга head страницы. Они разделены запятыми."
|
||||||
meta_description: "Переопределяет meta description сайта, используемые внутри тэга head страницы."
|
meta_description: "Переопределяет meta description сайта, используемые внутри тэга head страницы."
|
||||||
|
|
401
doc/TODO
401
doc/TODO
|
@ -1,136 +1,14 @@
|
||||||
BOARD:
|
BOARD:
|
||||||
|
|
||||||
x namespace assets
|
x page with regexp url => wildcards
|
||||||
x bugs:
|
- with_scope allowed for the find tag
|
||||||
x toggler
|
- nested relationships (find tag)
|
||||||
x advanced options (redirect url missing)
|
- script to migrate from templatized to wildcard
|
||||||
x locomotive_media (not animating on open)
|
- seo title (content_entry should be available)
|
||||||
x undefined method `_selector' for #<Locomotive::Page:0x00000107434768>
|
- write more tests
|
||||||
x editable_elements => view + handlebar template
|
- find_spec
|
||||||
x editable_short_text => tinymce
|
- features
|
||||||
x editable_file =>
|
- clean code
|
||||||
x backbone / handlebar
|
|
||||||
x new formtastic inputs
|
|
||||||
x menu / submenu in full css3 (no images)
|
|
||||||
x fix css in firefox
|
|
||||||
x update page in ajax
|
|
||||||
x edit my site
|
|
||||||
x css
|
|
||||||
x robots.txt
|
|
||||||
x domains
|
|
||||||
x roles
|
|
||||||
x save
|
|
||||||
x fix other sections
|
|
||||||
x edit my account
|
|
||||||
x create a new site
|
|
||||||
x create a new accounts
|
|
||||||
x theme assets
|
|
||||||
x polish the page
|
|
||||||
x snippets
|
|
||||||
x delete in ajax
|
|
||||||
x upload many files at once
|
|
||||||
x import/export
|
|
||||||
x export
|
|
||||||
x site picker
|
|
||||||
x content types
|
|
||||||
x move content instances into their own collection
|
|
||||||
x manage custom_fields
|
|
||||||
x automatic name
|
|
||||||
x required
|
|
||||||
x editable plugin: add class depending on the type => surrounding span instead
|
|
||||||
x position
|
|
||||||
x open the nested form
|
|
||||||
x remove an entry
|
|
||||||
x look n feel
|
|
||||||
x display errors
|
|
||||||
x slugify
|
|
||||||
x refactor highlighted_field (field id instead of name)
|
|
||||||
x other content type options
|
|
||||||
x show / hide options of a field based on its type
|
|
||||||
x select: add/edit/remove options
|
|
||||||
x text: formatting
|
|
||||||
x change in main menu
|
|
||||||
x manage contents
|
|
||||||
x list (highlighted field)
|
|
||||||
x slugify
|
|
||||||
x crud
|
|
||||||
x new
|
|
||||||
x date
|
|
||||||
x checkbox
|
|
||||||
x html
|
|
||||||
x file
|
|
||||||
x edit
|
|
||||||
x destroy
|
|
||||||
x public_form (previously api something)
|
|
||||||
x bug text formatting
|
|
||||||
x custom_fields: use the appropriate icon to drag select options
|
|
||||||
x bug ui with contents popup
|
|
||||||
x use list_or_group_entries instead of ordered_entries
|
|
||||||
x i18n
|
|
||||||
x add locales a site responds to
|
|
||||||
x locale switcher
|
|
||||||
x constraint: one locale at least
|
|
||||||
x front
|
|
||||||
x pages
|
|
||||||
x inline-editor
|
|
||||||
x back to default locale (if changed in settings) and when creating new pages / entries
|
|
||||||
- inline editor
|
|
||||||
x rack
|
|
||||||
x iframe
|
|
||||||
(- remove inline-editor tag)
|
|
||||||
x save editable elements
|
|
||||||
x notification (growl)
|
|
||||||
x change page
|
|
||||||
x i18n
|
|
||||||
- style the "ADMIN" button
|
|
||||||
- aloha:
|
|
||||||
x remove sidebar
|
|
||||||
- i18n
|
|
||||||
- insert image
|
|
||||||
x deployment
|
|
||||||
x fix integration problems
|
|
||||||
x pre-compile assets
|
|
||||||
x API
|
|
||||||
x authentication from a token + controller to deliver a token
|
|
||||||
x api routes
|
|
||||||
x change api location
|
|
||||||
(- add a way to custom the as_json method within the presenters (by default as_json ?) + custom responder ?)
|
|
||||||
x REST actions:
|
|
||||||
x CRUD theme assets
|
|
||||||
x CRUD snippets
|
|
||||||
x CRUD content assets
|
|
||||||
x CRUD pages
|
|
||||||
x CRUD content types
|
|
||||||
x data ?
|
|
||||||
x script to migrate existing site
|
|
||||||
x i18n
|
|
||||||
x upgrade to rails 3.2 (https://github.com/locomotivecms/engine/pull/281/files)
|
|
||||||
x missing custom_fields
|
|
||||||
x belongs_to
|
|
||||||
x has_many
|
|
||||||
x many_to_many
|
|
||||||
x simplify cells integration when modifying a menu from the main app
|
|
||||||
x heroku module for locomotive
|
|
||||||
x refactoring
|
|
||||||
x remove the import / export scripts
|
|
||||||
x remove the cross domain authentication (use auth_token instead)
|
|
||||||
x where to put Locomotive::InlineEditorMiddleware ?
|
|
||||||
x global regions: keyword in editable element (http://www.mongodb.org/display/DOCS/Updating)
|
|
||||||
x override sort for contents
|
|
||||||
|
|
||||||
- bugs / ui tweaks
|
|
||||||
x unable to toggle the "required" check_boxes for content types
|
|
||||||
x unable to sign out
|
|
||||||
x unable to remove a field
|
|
||||||
x "back to admin" link does not work if inline editor disabled
|
|
||||||
x unable to delete memberships
|
|
||||||
x disallow to click twice on the submit form button (spinner ?)
|
|
||||||
x weird behaviour when changing the default locale of a site
|
|
||||||
- editable_elements does not display the first time they get created (and if there are no existing ones)
|
|
||||||
- display by categories does not work when localized
|
|
||||||
- message to notify people if their browser is too old
|
|
||||||
|
|
||||||
? install a site by default at the first installation (without asking)
|
|
||||||
|
|
||||||
BACKLOG:
|
BACKLOG:
|
||||||
|
|
||||||
|
@ -141,9 +19,6 @@ BACKLOG:
|
||||||
- html view in the aloha popup
|
- html view in the aloha popup
|
||||||
- editable elements should wrap a tag: div, h1, ...etc (default span)
|
- editable elements should wrap a tag: div, h1, ...etc (default span)
|
||||||
- edit images (upload new ones, ...etc) => wait for aloha or send them an email ?
|
- edit images (upload new ones, ...etc) => wait for aloha or send them an email ?
|
||||||
- cucumber features for admin pages (in progress)
|
|
||||||
(- duostack/doutcloud version)
|
|
||||||
- write my first tutorial about locomotive
|
|
||||||
- upgrade warning if new version of locomotive (maybe based on the commit id)
|
- upgrade warning if new version of locomotive (maybe based on the commit id)
|
||||||
- deploying workflow:
|
- deploying workflow:
|
||||||
- roll back a bad update
|
- roll back a bad update
|
||||||
|
@ -156,16 +31,6 @@ BACKLOG:
|
||||||
- tooltip to explain the difference between 1.) Admin 2.) Author 3.) Designer?
|
- tooltip to explain the difference between 1.) Admin 2.) Author 3.) Designer?
|
||||||
- [bushido] guiders / welcome page / devise cas authentication (SSO)
|
- [bushido] guiders / welcome page / devise cas authentication (SSO)
|
||||||
|
|
||||||
REFACTORING:
|
|
||||||
|
|
||||||
- move content_type and content_instances in the CustomFields plugin (much more appropriate)
|
|
||||||
|
|
||||||
BUGS:
|
|
||||||
x mode author: settings KO + editable elements non visibles
|
|
||||||
x locales pour le locomotive editor => KO
|
|
||||||
! impossible de sauvegarder une page
|
|
||||||
|
|
||||||
|
|
||||||
NICE TO HAVE:
|
NICE TO HAVE:
|
||||||
- export site
|
- export site
|
||||||
- super_finder
|
- super_finder
|
||||||
|
@ -175,250 +40,4 @@ NICE TO HAVE:
|
||||||
- automatic update !
|
- automatic update !
|
||||||
- page not found (front) => if logged in, link to create the page
|
- page not found (front) => if logged in, link to create the page
|
||||||
- switch to list (theme assets / assets ?). delete all in once (with checkbox) or see details (updated_at, size, ...etc)
|
- switch to list (theme assets / assets ?). delete all in once (with checkbox) or see details (updated_at, size, ...etc)
|
||||||
- code completion ? http://blog.quplo.com/2010/06/common-sense-code-completion/
|
- code completion ? http://blog.quplo.com/2010/06/common-sense-code-completion/
|
||||||
|
|
||||||
DONE:
|
|
||||||
|
|
||||||
x tiny mce or similar for custom field text type.
|
|
||||||
x refactor custom field types
|
|
||||||
x new custom field types
|
|
||||||
x boolean
|
|
||||||
x enable/disable text formatting
|
|
||||||
x custom fields for asset collections
|
|
||||||
x [BUG] impossible to remove many assets in an asset collection
|
|
||||||
x new custom field type: date
|
|
||||||
x missing key: en, admin, theme_assets, images, no_items
|
|
||||||
x new custom field type: file
|
|
||||||
x update custom_fields plugin
|
|
||||||
x locomotive ui
|
|
||||||
x liquid templates
|
|
||||||
x rss parser
|
|
||||||
x localize application in French
|
|
||||||
x default
|
|
||||||
x devise
|
|
||||||
x carrierwave
|
|
||||||
x localize devise emails
|
|
||||||
x admin
|
|
||||||
x change credits in the admin footer
|
|
||||||
x license
|
|
||||||
x textile filter
|
|
||||||
x [bug] varnish can not be refreshed in heroku so "max-age" has to be disabled => modify cache strategy
|
|
||||||
x "remember me" should always be enabled
|
|
||||||
x sitemap
|
|
||||||
x refactoring admin crud (pages + layouts + snippets)
|
|
||||||
x flash messages in French
|
|
||||||
x save layout / snippet / page / stylesheet / javascript with CMD + S (ajax)
|
|
||||||
x change action icons according to the right action [Sacha]
|
|
||||||
x publish event when saving form in ajax (for instance, in order to update account name or site name)
|
|
||||||
x page templatized (bound to a model)
|
|
||||||
x theme asset picker when editing layout / snippet
|
|
||||||
x templatized: do not display content with visible / active set to false
|
|
||||||
x theme assets: disable version if not image (handled by the new version of Carrierwave)
|
|
||||||
x rack app to map pretty asset url to S3 => shortcut urls instead
|
|
||||||
x site selector (cross domain authentication)
|
|
||||||
x nice error page
|
|
||||||
x nice 404 page (admin section)
|
|
||||||
x liquid inheritance
|
|
||||||
x bug editable_xxx disabled for nil block
|
|
||||||
! duplicated block name
|
|
||||||
x display liquid errors
|
|
||||||
x theme assets selector in page editor
|
|
||||||
x saving page in ajax
|
|
||||||
x editable_long_text tag
|
|
||||||
x blocking issue when modifying the parent of 2 templates => one of the 2 children has reference of the first child
|
|
||||||
x editable_file tag
|
|
||||||
x stylish file field
|
|
||||||
x remove not used editable element all in once
|
|
||||||
x default content from parent editable element
|
|
||||||
x unable to upload/remove editable file
|
|
||||||
x customize tinyMCE: no html popup => div popup, nice icons
|
|
||||||
x add images / files inside long text element (back-office side at first ?)
|
|
||||||
x create a repo for a tool "a la" vision
|
|
||||||
x asset collections => liquid
|
|
||||||
x images tag to write
|
|
||||||
! apply http://github.com/flori/json/commit/2c0f8d2c9b15a33b8d10ffcb1959aef54d320b57
|
|
||||||
x snippet dependencies => do not work correctly
|
|
||||||
? google analytics tag
|
|
||||||
x mask internal asset_collections
|
|
||||||
x refactor ui for the theme assets page
|
|
||||||
x fix assets liquid tags / filters
|
|
||||||
x upload and insert new images in a css or js from the ui is broken
|
|
||||||
x proxy for fonts (http://markevans.github.com/dragonfly/file.Rails3.html)
|
|
||||||
x order yaml file (http://www.ruby-forum.com/topic/120295)
|
|
||||||
x fix tests
|
|
||||||
x inline editing (http://www.aloha-editor.com/wiki/index.php/Aloha_PHP_Example)
|
|
||||||
x spinner
|
|
||||||
x save automatically (callback) => store modifications
|
|
||||||
x admin buttons
|
|
||||||
x edit page
|
|
||||||
x save / cancel
|
|
||||||
x back to back-office => admin settings of the page
|
|
||||||
(- duplicate page ?)
|
|
||||||
(- super bonus statistics)
|
|
||||||
x locale
|
|
||||||
x store page toolbar status in cookie
|
|
||||||
x trim short text content
|
|
||||||
x namespace js functions
|
|
||||||
x import tool:
|
|
||||||
x select field (see custom fields and nocoffee theme) ?
|
|
||||||
x disable sub tasks by passing options
|
|
||||||
x exceptions
|
|
||||||
x page to import theme
|
|
||||||
x contents: group_by, oder_by, api_enabled
|
|
||||||
x folders for theme assets
|
|
||||||
x theme assets whitelist
|
|
||||||
x fonts
|
|
||||||
x asset collections
|
|
||||||
x rewrite the unzip process (for the import)
|
|
||||||
x bug with asset collections (assets disappear if we save the collection ?!)
|
|
||||||
x import tool:
|
|
||||||
x asset whitelist
|
|
||||||
x do not override existing site name
|
|
||||||
x add samples option
|
|
||||||
x content types
|
|
||||||
x asset collections
|
|
||||||
x page templatized (tied to content type)
|
|
||||||
x remove existing pages / contents option => reset
|
|
||||||
x give choice to reset site / add samples
|
|
||||||
x french translatations
|
|
||||||
x cosmetic / ui bugs / bugs:
|
|
||||||
x segmentation fault with with_scope
|
|
||||||
x paginate is not working
|
|
||||||
x redirection in dev does not work correctly for cross domain
|
|
||||||
x drag&drop for assets ('last' class issue)
|
|
||||||
x increase the input field width for domain names
|
|
||||||
x assets within custom contents are not deleted when the whole content type gets destroyed (after_destroy callback ?)
|
|
||||||
x api
|
|
||||||
x handle html request (for now, it's just json)
|
|
||||||
x installation guide
|
|
||||||
x detect if new installation
|
|
||||||
x no-site error redirects to the first step
|
|
||||||
x steps:
|
|
||||||
x welcome: domains, ...etc
|
|
||||||
x Create account
|
|
||||||
x Create new site (name, subdomain) / Import theme (worker or list of sites from fs)
|
|
||||||
x import:
|
|
||||||
x ordered pages ?
|
|
||||||
x order_by for content_types ? created_at, updated_at
|
|
||||||
x liquid:
|
|
||||||
x nav
|
|
||||||
x no_wrapper option
|
|
||||||
x regexp to get rid of some pages
|
|
||||||
x filters
|
|
||||||
x default_pagination: labels
|
|
||||||
x [content types] the "display column" selector should not include file types
|
|
||||||
x Worker => Heroku / S3 (not so sure finally)
|
|
||||||
x jammit-s3: assets
|
|
||||||
x copy assets.yml config file when using it as gem (http://asciicasts.com/episodes/218-making-generators-in-rails-3)
|
|
||||||
x import theme without delayed_job
|
|
||||||
x rspec 2.3
|
|
||||||
x ruby 1.9.2:
|
|
||||||
x DelayedJob not working
|
|
||||||
x new version of Aloha-Editor
|
|
||||||
x locomotive gem: test with staging
|
|
||||||
x nav tag:
|
|
||||||
x site | page | parent
|
|
||||||
x retrieve only important page information from mongodb
|
|
||||||
x published by default when importing pages
|
|
||||||
x page redirection
|
|
||||||
x notify accounts when new instance of models (opt): none, one or many accounts. Used for contact form.
|
|
||||||
x implementation
|
|
||||||
x emails
|
|
||||||
x tests
|
|
||||||
x fix bug issue about (custom fields)
|
|
||||||
x moving to mongoid 2.0.0 rc.6
|
|
||||||
x accepts_nested_attributes (javascript part)
|
|
||||||
x check the theme uploader
|
|
||||||
x release new version of CustomFields, ActsAsTree gems
|
|
||||||
x add metadata to sites
|
|
||||||
x pull requests #31 et #32
|
|
||||||
x password / new_password
|
|
||||||
x bugs
|
|
||||||
x custom_fields not deleted (doesn't use index anymore)
|
|
||||||
? editable_elements slug becomes nil
|
|
||||||
x editable_elements not updated (doesn't use index anymore)
|
|
||||||
x uploading videos http://groups.google.com/group/carrierwave/browse_thread/thread/6e211d98f1ff4bc0/51717c2167695ca2?lnk=gst&q=version#51717c2167695ca2
|
|
||||||
x custom fields: accepts_nested_attributes weird behaviour when creating new content type + adding random fields
|
|
||||||
x better icons for mime type (css3)
|
|
||||||
x validation for custom fields: required done
|
|
||||||
x pull request #44
|
|
||||||
x bug on dates (https://github.com/locomotivecms/engine/issues#issue/48)
|
|
||||||
x generated sitemaps are invalid (url + date)
|
|
||||||
x integrate new locomotivecms home
|
|
||||||
x seo section for the page form: seo title, seo keywords, seo description
|
|
||||||
x bugs: #50, #51
|
|
||||||
x 2 different sites on the same main domain (one in www, the other one in something else) (Raphael Costa)
|
|
||||||
! asset collections: custom resizing if image
|
|
||||||
x bushido version
|
|
||||||
x default template
|
|
||||||
~ editable_elements: inheritable: false (Mattias) => seems to be fixed by Dirk's last pull request (#44) => content tag
|
|
||||||
x resizing images on the fly
|
|
||||||
x locomedia tinyMCE plugin (Bernd)
|
|
||||||
x remove asset_collections
|
|
||||||
x site templates
|
|
||||||
x tinyMCE plugin
|
|
||||||
x vignette.rb
|
|
||||||
x code
|
|
||||||
x helpers
|
|
||||||
x ui
|
|
||||||
x rake task
|
|
||||||
x internal collection
|
|
||||||
x assign same _id
|
|
||||||
x pick up a theme_asset
|
|
||||||
x pull request locomedia
|
|
||||||
x refactor slugify method (use parameterize + create a module)
|
|
||||||
x contents permalink (UI)
|
|
||||||
x BUG: has_one / has_many. Delete an author
|
|
||||||
x bushido changes in the master
|
|
||||||
? edit sidebar (inline editor). Unable to reset it
|
|
||||||
x SEO: support and support/ should be 2 different pages. Remove trailing slash
|
|
||||||
x issue #91: httparty
|
|
||||||
x issue #90: seo metadata
|
|
||||||
x issue #57: seo page title
|
|
||||||
x issue #56
|
|
||||||
x tweak ui: form, quick link to edit a model in the popup menu
|
|
||||||
x Has_one => group by in the select
|
|
||||||
x better hints:
|
|
||||||
x notify the user that after changing the page title, they still have to click "update" for the change to be saved
|
|
||||||
x created_by ASC => "Creation date ascending"
|
|
||||||
x cancan: (authors / designers / admin)
|
|
||||||
x model
|
|
||||||
x ui
|
|
||||||
x controllers / views:
|
|
||||||
x page
|
|
||||||
x content / content type
|
|
||||||
x asset
|
|
||||||
x site
|
|
||||||
x account
|
|
||||||
x snippet
|
|
||||||
x theme asset
|
|
||||||
x features / specs
|
|
||||||
x enable rack-cache only for a specific url
|
|
||||||
x more cucumber tests for the content types
|
|
||||||
x check hosting:
|
|
||||||
x heroku
|
|
||||||
x bushi.do
|
|
||||||
x unable to reach the console
|
|
||||||
x deploy => okay
|
|
||||||
x unable to set a new subdomain
|
|
||||||
x liquid tag: Date.today (now), add a test to compare 2 dates
|
|
||||||
? better ui: increase text field length (auto sizable ?) + refactor error message
|
|
||||||
- trigger refresh at startup
|
|
||||||
x bugs
|
|
||||||
x heroku: unable to upload a new file => okay
|
|
||||||
x import => okay
|
|
||||||
x delete an item => okay
|
|
||||||
x bug: duplicate fields (new entry) when errors in the content type form
|
|
||||||
x tinyMCE => fullscreen
|
|
||||||
x export site
|
|
||||||
x rake task to import a remote template
|
|
||||||
x MERGE
|
|
||||||
x remove withelist for assets since we've got now roles
|
|
||||||
x admin role is not correctly set when creating a new website
|
|
||||||
x the required star for file field is not shown
|
|
||||||
x Rights to set roles (ticket #104)
|
|
||||||
x export: problems with templatized pages (source => multi levels pages)
|
|
||||||
x do not rename files for fonts
|
|
||||||
x icon for redirection page in the pages section (back-office)
|
|
||||||
x installed on heroku with source
|
|
||||||
x test and/or convert existing templates (the 2 of the themes section)
|
|
|
@ -45,9 +45,6 @@ Locomotive.configure do |config|
|
||||||
# follow the Dependency Injection pattern
|
# follow the Dependency Injection pattern
|
||||||
# config.context_assign_extensions = {}
|
# config.context_assign_extensions = {}
|
||||||
|
|
||||||
# add extra classes other than the defined content types among a site which will potentially used by the templatized pages.
|
|
||||||
# config.models_for_templatization = %w(Product)
|
|
||||||
|
|
||||||
# Rack-cache settings, mainly used for the inline resizing image module. Default options:
|
# Rack-cache settings, mainly used for the inline resizing image module. Default options:
|
||||||
# config.rack_cache = {
|
# config.rack_cache = {
|
||||||
# :verbose => true,
|
# :verbose => true,
|
||||||
|
|
|
@ -24,10 +24,10 @@ module Locomotive
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_page_url(page, options = {})
|
def public_page_url(page, options = {})
|
||||||
if content = options.delete(:content)
|
if contents = options.delete(:contents)
|
||||||
File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug)
|
File.join(current_site_public_url, page.compiled_fullpath(contents))
|
||||||
else
|
else
|
||||||
File.join(current_site_public_url, page.fullpath)
|
File.join(current_site_public_url, page.pretty_fullpath)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,4 +10,4 @@ module Formtastic
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -3,14 +3,18 @@ module Locomotive
|
||||||
module Drops
|
module Drops
|
||||||
class Page < Base
|
class Page < Base
|
||||||
|
|
||||||
delegate :seo_title, :meta_keywords, :meta_description, :to => '_source'
|
delegate :title, :seo_title, :meta_keywords, :meta_description, :to => '_source'
|
||||||
|
|
||||||
def title
|
def title
|
||||||
self._source.templatized? ? @context['entry']._label : self._source.title
|
# TODO
|
||||||
|
# self._source.templatized? ? @context['entry']._label : self._source.title
|
||||||
|
self._source.title
|
||||||
end
|
end
|
||||||
|
|
||||||
def slug
|
def slug
|
||||||
self._source.templatized? ? self._source.content_type.slug.singularize : self._source.slug
|
# TODO
|
||||||
|
# self._source.templatized? ? self._source.content_type.slug.singularize : self._source.slug
|
||||||
|
self._source.slug
|
||||||
end
|
end
|
||||||
|
|
||||||
def parent
|
def parent
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
module Locomotive
|
||||||
|
module Liquid
|
||||||
|
module Tags
|
||||||
|
class Find < ::Liquid::Tag
|
||||||
|
|
||||||
|
Syntax = /(#{::Liquid::Expression}+)?/
|
||||||
|
|
||||||
|
def initialize(tag_name, markup, tokens, context)
|
||||||
|
if markup =~ Syntax
|
||||||
|
@options = markup.scan(::Liquid::QuotedFragment)
|
||||||
|
|
||||||
|
syntax_error! if @options.size != 2
|
||||||
|
else
|
||||||
|
syntax_error!
|
||||||
|
end
|
||||||
|
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(context)
|
||||||
|
Rails.logger.debug "\n\n =>>>>>>> #{@options.inspect} / #{context['params'].inspect}"
|
||||||
|
|
||||||
|
permalink = context[@options.last]
|
||||||
|
site = context.registers[:site]
|
||||||
|
type = site.content_types.where(:slug => @options.first).first
|
||||||
|
entry = type.klass_with_custom_fields(:entries).find_by_permalink(permalink)
|
||||||
|
entry_name = @options.first.singularize
|
||||||
|
|
||||||
|
context.scopes.last['content_entry'] = entry
|
||||||
|
context.scopes.last[entry_name] = entry
|
||||||
|
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def syntax_error!
|
||||||
|
raise ::Liquid::SyntaxError.new("Syntax Error in 'find' - Valid syntax: find <content_type>, <permalink>")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
::Liquid::Template.register_tag('find', Find)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,5 @@
|
||||||
module Liquid
|
module Locomotive
|
||||||
module Locomotive
|
module Liquid
|
||||||
module Tags
|
module Tags
|
||||||
class GoogleAnalytics < ::Liquid::Tag
|
class GoogleAnalytics < ::Liquid::Tag
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module Liquid
|
module Locomotive
|
||||||
module Locomotive
|
module Liquid
|
||||||
module Tags
|
module Tags
|
||||||
class InlineEditor < ::Liquid::Tag
|
class InlineEditor < ::Liquid::Tag
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,14 @@ module Locomotive
|
||||||
|
|
||||||
output += @site.locales.collect do |locale|
|
output += @site.locales.collect do |locale|
|
||||||
::Mongoid::Fields::I18n.with_locale(locale) do
|
::Mongoid::Fields::I18n.with_locale(locale) do
|
||||||
fullpath = @site.localized_page_fullpath(@page, locale)
|
# fullpath = @site.localized_page_fullpath(@page, locale)
|
||||||
|
|
||||||
if @page.templatized?
|
# if @page.templatized?
|
||||||
fullpath.gsub!('content_type_template', context['entry']._permalink)
|
# fullpath.gsub!('content_type_template', context['entry']._permalink)
|
||||||
end
|
# end
|
||||||
|
|
||||||
|
# TODO: TO BE TESTED
|
||||||
|
fullpath = @page.compiled_fullpath(@page.wildcards_hash)
|
||||||
|
|
||||||
%(<a href="/#{fullpath}" class="#{locale} #{'current' if locale == context['current_locale']}">#{link_label(locale)}</a>)
|
%(<a href="/#{fullpath}" class="#{locale} #{'current' if locale == context['current_locale']}">#{link_label(locale)}</a>)
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,7 +34,7 @@ module Locomotive
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
raise ::Liquid::SyntaxError.new("Syntax Error in 'nav' - Valid syntax: nav <page|site> <options>")
|
raise ::Liquid::SyntaxError.new("Syntax Error in 'nav' - Valid syntax: nav <page|site>, <options>")
|
||||||
end
|
end
|
||||||
|
|
||||||
super
|
super
|
||||||
|
@ -134,7 +134,7 @@ module Locomotive
|
||||||
|
|
||||||
# Determines whether or not a page should be a part of the menu
|
# Determines whether or not a page should be a part of the menu
|
||||||
def include_page?(page)
|
def include_page?(page)
|
||||||
if !page.listed? || page.templatized? || !page.published?
|
if !page.listed? || page.has_wildcards? || !page.published?
|
||||||
false
|
false
|
||||||
elsif @options[:exclude]
|
elsif @options[:exclude]
|
||||||
(page.fullpath =~ @options[:exclude]).nil?
|
(page.fullpath =~ @options[:exclude]).nil?
|
||||||
|
|
|
@ -59,3 +59,5 @@ module Mongoid#:nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -63,10 +63,7 @@ module Locomotive
|
||||||
|
|
||||||
assigns.merge!(flash.to_hash.stringify_keys) # data from public submissions
|
assigns.merge!(flash.to_hash.stringify_keys) # data from public submissions
|
||||||
|
|
||||||
if @page.templatized? # add instance from content type
|
assigns['params'].merge!(@page.wildcards_hash.stringify_keys) if @page.has_wildcards?
|
||||||
assigns['entry'] = @page.content_entry
|
|
||||||
assigns[@page.target_entry_name] = @page.content_entry # just here to help to write readable liquid code
|
|
||||||
end
|
|
||||||
|
|
||||||
registers = {
|
registers = {
|
||||||
:controller => self,
|
:controller => self,
|
||||||
|
|
|
@ -56,9 +56,6 @@ Locomotive.configure do |config|
|
||||||
# follow the Dependency Injection pattern
|
# follow the Dependency Injection pattern
|
||||||
# config.context_assign_extensions = {}
|
# config.context_assign_extensions = {}
|
||||||
|
|
||||||
# add extra classes other than the defined content types among a site which will potentially used by the templatized pages.
|
|
||||||
config.models_for_templatization = %w(Foo)
|
|
||||||
|
|
||||||
# Rack-cache settings, mainly used for the inline resizing image module. Default options:
|
# Rack-cache settings, mainly used for the inline resizing image module. Default options:
|
||||||
# config.rack_cache = {
|
# config.rack_cache = {
|
||||||
# :verbose => true,
|
# :verbose => true,
|
||||||
|
|
|
@ -71,13 +71,14 @@ describe Locomotive::Liquid::Drops::Page do
|
||||||
render_template('{{ home.title }}').should == 'Home page'
|
render_template('{{ home.title }}').should == 'Home page'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders the content instance highlighted field instead for a templatized page' do
|
# TODO
|
||||||
templatized = FactoryGirl.build(:page, :title => 'Lorem ipsum template', :templatized => true)
|
# it 'renders the content instance highlighted field instead for a templatized page' do
|
||||||
|
# templatized = FactoryGirl.build(:page, :title => 'Lorem ipsum template', :templatized => true)
|
||||||
entry = Locomotive::Liquid::Drops::ContentEntry.new(mock('entry', :_label => 'Locomotive rocks !'))
|
#
|
||||||
|
# entry = Locomotive::Liquid::Drops::ContentEntry.new(mock('entry', :_label => 'Locomotive rocks !'))
|
||||||
render_template('{{ page.title }}', 'page' => templatized, 'entry' => entry).should == 'Locomotive rocks !'
|
#
|
||||||
end
|
# render_template('{{ page.title }}', 'page' => templatized, 'entry' => entry).should == 'Locomotive rocks !'
|
||||||
|
# end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Locomotive::Liquid::Tags::Find do
|
||||||
|
|
||||||
|
it 'is valid if the 2 arguments are present' do
|
||||||
|
lambda do
|
||||||
|
Locomotive::Liquid::Tags::Find.new('find', 'projects, params.permalink', [], {})
|
||||||
|
end.should_not raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid if one of the 2 arguments is missing' do
|
||||||
|
lambda do
|
||||||
|
Locomotive::Liquid::Tags::Find.new('find', 'projects', [], {})
|
||||||
|
end.should raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
# it 'tests' do
|
||||||
|
# tag = Locomotive::Liquid::Tags::Find.new('find', 'projects, params.permalink', [], {})
|
||||||
|
# puts tag.inspect
|
||||||
|
# # attributes = scope.send(:decode, scope.instance_variable_get(:@attributes), ::Liquid::Context.new)
|
||||||
|
# # attributes['active'].should == true
|
||||||
|
# # attributes['price'].should == 42
|
||||||
|
# # attributes['title'].should == 'foo'
|
||||||
|
# # attributes['hidden'].should == false
|
||||||
|
# end
|
||||||
|
|
||||||
|
# it 'decodes more complex options' do
|
||||||
|
# scope = Locomotive::Liquid::Tags::WithScope.new('with_scope', 'price.gt:42.0 price.lt:50', ["{% endwith_scope %}"], {})
|
||||||
|
# attributes = scope.send(:decode, scope.instance_variable_get(:@attributes), ::Liquid::Context.new)
|
||||||
|
# attributes['price.gt'].should == 42.0
|
||||||
|
# attributes['price.lt'].should == 50
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# it 'decodes context variable' do
|
||||||
|
# scope = Locomotive::Liquid::Tags::WithScope.new('with_scope', 'category: params.type', ["{% endwith_scope %}"], {})
|
||||||
|
# attributes = scope.send(:decode, scope.instance_variable_get(:@attributes), ::Liquid::Context.new({ 'params' => { 'type' => 'posts' } }))
|
||||||
|
# attributes['category'].should == 'posts'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# it 'allows order_by option' do
|
||||||
|
# scope = Locomotive::Liquid::Tags::WithScope.new('with_scope', 'order_by:\'name DESC\'', ["{% endwith_scope %}"], {})
|
||||||
|
# attributes = scope.send(:decode, scope.instance_variable_get(:@attributes), ::Liquid::Context.new)
|
||||||
|
# attributes['order_by'].should == 'name DESC'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# it 'stores attributes in the context' do
|
||||||
|
# template = ::Liquid::Template.parse("{% with_scope active:true title:'foo' %}{{ with_scope.active }}-{{ with_scope.title }}{% endwith_scope %}")
|
||||||
|
# text = template.render
|
||||||
|
# text.should == "true-foo"
|
||||||
|
# end
|
||||||
|
|
||||||
|
end
|
|
@ -15,7 +15,7 @@ describe Locomotive::Liquid::Tags::Nav do
|
||||||
Locomotive::Page.new(:title => 'Child #2.1', :fullpath => 'child_2/sub_child_1', :slug => 'sub_child_1', :published => true),
|
Locomotive::Page.new(:title => 'Child #2.1', :fullpath => 'child_2/sub_child_1', :slug => 'sub_child_1', :published => true),
|
||||||
Locomotive::Page.new(:title => 'Child #2.2', :fullpath => 'child_2/sub_child_2', :slug => 'sub_child_2', :published => true),
|
Locomotive::Page.new(:title => 'Child #2.2', :fullpath => 'child_2/sub_child_2', :slug => 'sub_child_2', :published => true),
|
||||||
Locomotive::Page.new(:title => 'Unpublished #2.2', :fullpath => 'child_2/sub_child_unpublishd_2', :slug => 'sub_child_unpublished_2', :published => false),
|
Locomotive::Page.new(:title => 'Unpublished #2.2', :fullpath => 'child_2/sub_child_unpublishd_2', :slug => 'sub_child_unpublished_2', :published => false),
|
||||||
Locomotive::Page.new(:title => 'Templatized #2.3', :fullpath => 'child_2/sub_child_template_3', :slug => 'sub_child_template_3', :published => true, :templatized => true),
|
Locomotive::Page.new(:title => 'Templatized #2.3', :fullpath => 'child_2/sub_child_template_3', :slug => 'sub_child_template_3', :published => true, :wildcard => true),
|
||||||
Locomotive::Page.new(:title => 'Unlisted #2.4', :fullpath => 'child_2/sub_child_unlisted_4', :slug => 'sub_child_unlisted_4', :published => true, :listed => false)
|
Locomotive::Page.new(:title => 'Unlisted #2.4', :fullpath => 'child_2/sub_child_unlisted_4', :slug => 'sub_child_unlisted_4', :published => true, :listed => false)
|
||||||
]
|
]
|
||||||
@home.children.last.stubs(:children_with_minimal_attributes).returns(other_children)
|
@home.children.last.stubs(:children_with_minimal_attributes).returns(other_children)
|
||||||
|
@ -55,7 +55,7 @@ describe Locomotive::Liquid::Tags::Nav do
|
||||||
output.should match /<\/a><\/li><\/ul><\/li><\/ul>/
|
output.should match /<\/a><\/li><\/ul><\/li><\/ul>/
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not render templatized pages' do
|
it 'does not render pages with wildcards' do
|
||||||
output = render_nav('site', {}, 'depth: 2')
|
output = render_nav('site', {}, 'depth: 2')
|
||||||
|
|
||||||
output.should_not match /sub-child-template-3/
|
output.should_not match /sub-child-template-3/
|
||||||
|
|
|
@ -81,6 +81,10 @@ describe 'Locomotive rendering system' do
|
||||||
|
|
||||||
context 'when retrieving page' do
|
context 'when retrieving page' do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@page.fullpath = 'index' # we do not care if the fullpath is consistent or not.
|
||||||
|
end
|
||||||
|
|
||||||
it 'should retrieve the index page /' do
|
it 'should retrieve the index page /' do
|
||||||
@controller.request.fullpath = '/'
|
@controller.request.fullpath = '/'
|
||||||
@controller.current_site.pages.expects(:where).with(:depth => 0, :fullpath.in => %w{index}).returns([@page])
|
@controller.current_site.pages.expects(:where).with(:depth => 0, :fullpath.in => %w{index}).returns([@page])
|
||||||
|
@ -95,13 +99,13 @@ describe 'Locomotive rendering system' do
|
||||||
|
|
||||||
it 'should retrieve it based on the full path' do
|
it 'should retrieve it based on the full path' do
|
||||||
@controller.request.fullpath = '/about_us/team.html'
|
@controller.request.fullpath = '/about_us/team.html'
|
||||||
@controller.current_site.pages.expects(:where).with(:depth => 2, :fullpath.in => %w{about_us/team about_us/content_type_template content_type_template/team}).returns([@page])
|
@controller.current_site.pages.expects(:where).with(:depth => 2, :fullpath.in => %w{about_us/team about_us/* */team */*}).returns([@page])
|
||||||
@controller.send(:locomotive_page).should_not be_nil
|
@controller.send(:locomotive_page).should_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not include the query string' do
|
it 'does not include the query string' do
|
||||||
@controller.request.fullpath = '/about_us/team.html?some=params&we=use'
|
@controller.request.fullpath = '/about_us/team.html?some=params&we=use'
|
||||||
@controller.current_site.pages.expects(:where).with(:depth => 2, :fullpath.in => %w{about_us/team about_us/content_type_template content_type_template/team}).returns([@page])
|
@controller.current_site.pages.expects(:where).with(:depth => 2, :fullpath.in => %w{about_us/team about_us/* */team */*}).returns([@page])
|
||||||
@controller.send(:locomotive_page).should_not be_nil
|
@controller.send(:locomotive_page).should_not be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -118,7 +122,7 @@ describe 'Locomotive rendering system' do
|
||||||
@page.redirect = true
|
@page.redirect = true
|
||||||
@page.redirect_url = 'http://www.example.com/'
|
@page.redirect_url = 'http://www.example.com/'
|
||||||
@controller.request.fullpath = '/contact'
|
@controller.request.fullpath = '/contact'
|
||||||
@controller.current_site.pages.expects(:where).with(:depth => 1, :fullpath.in => %w{contact content_type_template}).returns([@page])
|
@controller.current_site.pages.expects(:where).with(:depth => 1, :fullpath.in => %w{contact *}).returns([@page])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'redirects to the redirect_url' do
|
it 'redirects to the redirect_url' do
|
||||||
|
@ -128,37 +132,22 @@ describe 'Locomotive rendering system' do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'templatized page' do
|
context 'wildcards page' do
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@content_type = FactoryGirl.build(:content_type, :site => nil)
|
@page.attributes = { 'wildcards' => %w(permalink), 'fullpath' => 'projects/*', 'wildcard' => true }
|
||||||
@content_entry = @content_type.entries.build(:_visible => true)
|
|
||||||
@page.templatized = true
|
|
||||||
@page.stubs(:fetch_target_entry).returns(@content_entry)
|
|
||||||
@page.stubs(:fullpath).returns('/projects/content_type_template')
|
|
||||||
@controller.request.fullpath = '/projects/edeneo.html'
|
@controller.request.fullpath = '/projects/edeneo.html'
|
||||||
@controller.current_site.pages.expects(:where).with(:depth => 2, :fullpath.in => %w{projects/edeneo projects/content_type_template content_type_template/edeneo}).returns([@page])
|
@controller.current_site.pages.expects(:where).with(:depth => 2, :fullpath.in => %w{projects/edeneo projects/* */edeneo */*}).returns([@page])
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the content_entry variable' do
|
it 'finds the page' do
|
||||||
page = @controller.send(:locomotive_page)
|
page = @controller.send(:locomotive_page)
|
||||||
page.should_not be_nil
|
page.should_not be_nil
|
||||||
page.content_entry.should == @content_entry
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns the 404 page if the instance does not exist' do
|
it 'assigns values to wildcards' do
|
||||||
@page.stubs(:fetch_target_entry).returns(nil)
|
page = @controller.send(:locomotive_page)
|
||||||
(klass = Locomotive::Page).expects(:published).returns([true])
|
page.wildcards_hash.should == { 'permalink' => 'edeneo' }
|
||||||
@controller.current_site.pages.expects(:not_found).returns(klass)
|
|
||||||
@controller.send(:locomotive_page).should be_true
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'returns the 404 page if the instance is not visible' do
|
|
||||||
@content_entry._visible = false
|
|
||||||
@page.stubs(:fetch_target_entry).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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -172,7 +161,7 @@ describe 'Locomotive rendering system' do
|
||||||
|
|
||||||
it 'should return the 404 page if the page has not been published yet' do
|
it 'should return the 404 page if the page has not been published yet' do
|
||||||
@controller.request.fullpath = '/contact'
|
@controller.request.fullpath = '/contact'
|
||||||
@controller.current_site.pages.expects(:where).with(:depth => 1, :fullpath.in => %w{contact content_type_template}).returns([@page])
|
@controller.current_site.pages.expects(:where).with(:depth => 1, :fullpath.in => %w{contact *}).returns([@page])
|
||||||
(klass = Locomotive::Page).expects(:published).returns([true])
|
(klass = Locomotive::Page).expects(:published).returns([true])
|
||||||
@controller.current_site.pages.expects(:not_found).returns(klass)
|
@controller.current_site.pages.expects(:not_found).returns(klass)
|
||||||
@controller.send(:locomotive_page).should be_true
|
@controller.send(:locomotive_page).should be_true
|
||||||
|
@ -181,7 +170,7 @@ describe 'Locomotive rendering system' do
|
||||||
it 'should not return the 404 page if the page has not been published yet and admin is logged in' do
|
it 'should not return the 404 page if the page has not been published yet and admin is logged in' do
|
||||||
@controller.current_locomotive_account = true
|
@controller.current_locomotive_account = true
|
||||||
@controller.request.fullpath = '/contact'
|
@controller.request.fullpath = '/contact'
|
||||||
@controller.current_site.pages.expects(:where).with(:depth => 1, :fullpath.in => %w{contact content_type_template}).returns([@page])
|
@controller.current_site.pages.expects(:where).with(:depth => 1, :fullpath.in => %w{contact *}).returns([@page])
|
||||||
@controller.send(:locomotive_page).should == @page
|
@controller.send(:locomotive_page).should == @page
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ describe Locomotive::EditableShortText do
|
||||||
describe 'a simple case' do
|
describe 'a simple case' do
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@site = FactoryGirl.create(:site)
|
@site = FactoryGirl.create(:site, :locales => %w(en fr))
|
||||||
@home = @site.pages.root.first
|
@home = @site.pages.root.first
|
||||||
|
|
||||||
@home.update_attributes :raw_template => "{% block body %}{% editable_short_text 'body' %}Lorem ipsum{% endeditable_short_text %}{% endblock %}"
|
@home.update_attributes :raw_template => "{% block body %}{% editable_short_text 'body' %}Lorem ipsum{% endeditable_short_text %}{% endblock %}"
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Locomotive::Page do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
Locomotive::Site.any_instance.stubs(:create_default_pages!).returns(true)
|
||||||
|
Locomotive::Page.any_instance.stubs(:set_default_raw_template).returns(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'wildcards' do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@page = FactoryGirl.build(:page, :parent => FactoryGirl.build(:page), :title => 'Project template', :slug => 'permalink', :wildcard => true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has a fullpath with wildcards' do
|
||||||
|
@page.wildcard?.should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns a nice output of the fullpath' do
|
||||||
|
@page.fullpath = 'archives/*/projects/*'
|
||||||
|
@page.wildcards = %w(month permalink)
|
||||||
|
@page.pretty_fullpath.should == 'archives/:month/projects/:permalink'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'compiles a fullpath with wildcards' do
|
||||||
|
@page.fullpath = 'archives/*/projects/*'
|
||||||
|
@page.wildcards = %w(month permalink)
|
||||||
|
@page.compiled_fullpath('month' => 'june', 'permalink' => 'hello-world').should == 'archives/june/projects/hello-world'
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'building the fullpath' do
|
||||||
|
|
||||||
|
it 'returns "index" for the root page' do
|
||||||
|
@page = FactoryGirl.build(:page)
|
||||||
|
@page.send(:build_fullpath)
|
||||||
|
@page.fullpath.should == 'index'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns "404" for the "page not found" page' do
|
||||||
|
@page = FactoryGirl.build(:page, :slug => '404')
|
||||||
|
@page.send(:build_fullpath)
|
||||||
|
@page.fullpath.should == '404'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes a single "*" if the page enables wildcards' do
|
||||||
|
@page.send(:build_fullpath)
|
||||||
|
@page.fullpath.should == '*'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes a single "*" if the page enables wildcards and if there are a lot of ancestors' do
|
||||||
|
@page.stubs(:parent).returns(FactoryGirl.build(:page, :fullpath => 'archives/projects'))
|
||||||
|
@page.send(:build_fullpath)
|
||||||
|
@page.fullpath.should == 'archives/projects/*'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'includes many "*" when there are ancestors enabling wildcards' do
|
||||||
|
@page.stubs(:parent).returns(FactoryGirl.build(:page, :fullpath => 'archives/*/projects'))
|
||||||
|
@page.send(:build_fullpath)
|
||||||
|
@page.fullpath.should == 'archives/*/projects/*'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'adding wildcards' do
|
||||||
|
|
||||||
|
it 'fills the array of wildcards' do
|
||||||
|
@page.valid?
|
||||||
|
@page.wildcards.should == %w(permalink)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'fills the array of wildcards from ancestors' do
|
||||||
|
@page.parent.stubs(:has_wildcards?).returns(true)
|
||||||
|
@page.parent.wildcards = %w(category month)
|
||||||
|
@page.valid?
|
||||||
|
@page.wildcards.should == %w(category month permalink)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'contains a array of valid wildcards' do
|
||||||
|
@page.slug = 'another permalink'
|
||||||
|
@page.valid?
|
||||||
|
@page.wildcards.should == %w(another-permalink)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'propagating changes' do
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
@home_page = FactoryGirl.create(:page)
|
||||||
|
@archives_page = FactoryGirl.create(:page, :site => @home_page.site, :parent => @home_page, :slug => 'archives')
|
||||||
|
@month_page = FactoryGirl.create(:page, :site => @home_page.site, :parent => @archives_page, :slug => 'month')
|
||||||
|
@projects_page = FactoryGirl.create(:page, :site => @home_page.site, :parent => @month_page, :slug => 'projects')
|
||||||
|
@project_page = FactoryGirl.create(:page, :site => @home_page.site, :parent => @projects_page, :slug => 'project', :wildcard => true)
|
||||||
|
@posts_page = FactoryGirl.create(:page, :site => @home_page.site, :parent => @month_page, :slug => 'posts')
|
||||||
|
|
||||||
|
[@home_page, @archives_page, @month_page, @projects_page, @project_page, @posts_page].map(&:reload)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'keeps the wildcards as they were if we modify a slug of an ancestor' do
|
||||||
|
@archives_page.update_attributes :slug => 'my_archives'
|
||||||
|
@project_page.reload
|
||||||
|
@project_page.fullpath.should == 'my_archives/month/projects/*'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'modifies a wildcard' do
|
||||||
|
@month_page.update_attributes :wildcard => true
|
||||||
|
@month_page.reload
|
||||||
|
@month_page.update_attributes :slug => 'a_month'
|
||||||
|
@project_page.reload
|
||||||
|
@project_page.fullpath.should == 'archives/*/projects/*'
|
||||||
|
@project_page.wildcards.should == %w(a_month project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'turns a page into a wildcards one' do
|
||||||
|
@month_page.update_attributes :wildcard => true
|
||||||
|
@project_page.reload
|
||||||
|
@project_page.fullpath.should == 'archives/*/projects/*'
|
||||||
|
@posts_page.reload
|
||||||
|
@posts_page.fullpath.should == 'archives/*/posts'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'turns off the wildcard property of page' do
|
||||||
|
@month_page.update_attributes :wildcard => true
|
||||||
|
@month_page.reload
|
||||||
|
@month_page.update_attributes :wildcard => false
|
||||||
|
@project_page.reload
|
||||||
|
@project_page.fullpath.should == 'archives/month/projects/*'
|
||||||
|
@project_page.wildcards.should == %w(project)
|
||||||
|
@posts_page.reload
|
||||||
|
@posts_page.fullpath.should == 'archives/month/posts'
|
||||||
|
@posts_page.wildcards.should == []
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'building the hash map asssociating a wildcard name with its value from a path' do
|
||||||
|
|
||||||
|
it 'returns an empty map for non wildcards fullpath' do
|
||||||
|
@page.fullpath = 'index'
|
||||||
|
@page.wildcards = nil
|
||||||
|
@page.match_wildcards('index').should be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'underscores the wildcard name in the returned hash map' do
|
||||||
|
@page.fullpath = 'projects/*'
|
||||||
|
@page.wildcards = %w(my-permalink)
|
||||||
|
@page.match_wildcards('projects/hello-world').should == { 'my_permalink' => 'hello-world' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns a map with one element if the fullpath contains a single wildcard' do
|
||||||
|
@page.fullpath = 'projects/*'
|
||||||
|
@page.wildcards = %w(permalink)
|
||||||
|
@page.match_wildcards('projects/hello-world').should == { 'permalink' => 'hello-world' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns a map with as many elements as there are wildcards in the fullpath' do
|
||||||
|
@page.fullpath = 'archives/*/projects/*'
|
||||||
|
@page.wildcards = %w(month permalink)
|
||||||
|
@page.match_wildcards('archives/june/projects/hello-world').should == {
|
||||||
|
'month' => 'june',
|
||||||
|
'permalink' => 'hello-world'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'stores the map inside a virtual attribute' do
|
||||||
|
@page.fullpath = 'projects/*'
|
||||||
|
@page.wildcards = %w(permalink)
|
||||||
|
@page.match_wildcards('projects/hello-world')
|
||||||
|
@page.wildcards_hash.should == { 'permalink' => 'hello-world' }
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -208,123 +208,123 @@ describe Locomotive::Page do
|
||||||
context '#path combinations' do
|
context '#path combinations' do
|
||||||
|
|
||||||
it 'generates them for a path depth equals to 1' do
|
it 'generates them for a path depth equals to 1' do
|
||||||
Locomotive::Page.path_combinations('foo').should == ['foo', 'content_type_template']
|
Locomotive::Page.path_combinations('foo').should == ['foo', '*']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'generates them for a path depth equals to 2' do
|
it 'generates them for a path depth equals to 2' do
|
||||||
Locomotive::Page.path_combinations('foo/bar').should == ['foo/bar', 'foo/content_type_template', 'content_type_template/bar']
|
Locomotive::Page.path_combinations('foo/bar').should == ['foo/bar', 'foo/*', '*/bar', '*/*']
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'generates them for a path depth equals to 3' do
|
it 'generates them for a path depth equals to 3' do
|
||||||
Locomotive::Page.path_combinations('foo/bar/baz').should == ['foo/bar/baz', 'foo/bar/content_type_template', 'foo/content_type_template/baz', 'content_type_template/bar/baz']
|
Locomotive::Page.path_combinations('foo/bar/baz').should == ['foo/bar/baz', 'foo/bar/*', 'foo/*/baz', 'foo/*/*', '*/bar/baz', '*/bar/*', '*/*/baz', '*/*/*']
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'templatized extension' do
|
# describe 'templatized extension' do
|
||||||
|
#
|
||||||
before(:each) do
|
# before(:each) do
|
||||||
@page = FactoryGirl.build(:page, :parent => FactoryGirl.build(:page, :templatized => false), :templatized => true, :target_klass_name => 'Foo')
|
# @page = FactoryGirl.build(:page, :parent => FactoryGirl.build(:page, :templatized => false), :templatized => true, :target_klass_name => 'Foo')
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'is considered as a templatized page' do
|
# it 'is considered as a templatized page' do
|
||||||
@page.templatized?.should be_true
|
# @page.templatized?.should be_true
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'fills in the slug field' do
|
# it 'fills in the slug field' do
|
||||||
@page.valid?
|
# @page.valid?
|
||||||
@page.slug.should == 'content_type_template'
|
# @page.slug.should == 'content_type_template'
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'returns the target klass' do
|
# it 'returns the target klass' do
|
||||||
@page.target_klass.should == Foo
|
# @page.target_klass.should == Foo
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'has a name for the target entry' do
|
# it 'has a name for the target entry' do
|
||||||
@page.target_entry_name.should == 'foo'
|
# @page.target_entry_name.should == 'foo'
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'uses the find_by_permalink method when fetching the entry' do
|
# it 'uses the find_by_permalink method when fetching the entry' do
|
||||||
Foo.expects(:find_by_permalink)
|
# Foo.expects(:find_by_permalink)
|
||||||
@page.fetch_target_entry('foo')
|
# @page.fetch_target_entry('foo')
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
context '#descendants' do
|
# context '#descendants' do
|
||||||
|
#
|
||||||
before(:each) do
|
# before(:each) do
|
||||||
@home = FactoryGirl.create(:page)
|
# @home = FactoryGirl.create(:page)
|
||||||
@page.attributes = { :parent_id => @home._id, :site => @home.site }; @page.save!
|
# @page.attributes = { :parent_id => @home._id, :site => @home.site }; @page.save!
|
||||||
@sub_page = FactoryGirl.build(:page, :title => 'Subpage', :slug => 'foo', :parent => @page, :site => @home.site, :templatized => false)
|
# @sub_page = FactoryGirl.build(:page, :title => 'Subpage', :slug => 'foo', :parent => @page, :site => @home.site, :templatized => false)
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'inherits the templatized property from its parent' do
|
# it 'inherits the templatized property from its parent' do
|
||||||
@sub_page.valid?
|
# @sub_page.valid?
|
||||||
@sub_page.templatized?.should be_true
|
# @sub_page.templatized?.should be_true
|
||||||
@sub_page.templatized_from_parent?.should be_true
|
# @sub_page.templatized_from_parent?.should be_true
|
||||||
@sub_page.target_klass_name.should == 'Foo'
|
# @sub_page.target_klass_name.should == 'Foo'
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'gets templatized if its parent is' do
|
# it 'gets templatized if its parent is' do
|
||||||
@page.attributes = { :templatized => false, :target_klass_name => nil }; @page.save!
|
# @page.attributes = { :templatized => false, :target_klass_name => nil }; @page.save!
|
||||||
@sub_page.save.should be_true
|
# @sub_page.save.should be_true
|
||||||
@sub_page.templatized?.should be_false
|
# @sub_page.templatized?.should be_false
|
||||||
|
#
|
||||||
@page.attributes = { :templatized => true, :target_klass_name => 'Foo' }; @page.save!
|
# @page.attributes = { :templatized => true, :target_klass_name => 'Foo' }; @page.save!
|
||||||
@sub_page.reload
|
# @sub_page.reload
|
||||||
@sub_page.templatized?.should be_true
|
# @sub_page.templatized?.should be_true
|
||||||
@sub_page.templatized_from_parent?.should be_true
|
# @sub_page.templatized_from_parent?.should be_true
|
||||||
@sub_page.target_klass_name.should == 'Foo'
|
# @sub_page.target_klass_name.should == 'Foo'
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'is not templatized if its parent is no more a templatized page' do
|
# it 'is not templatized if its parent is no more a templatized page' do
|
||||||
@sub_page.save.should be_true
|
# @sub_page.save.should be_true
|
||||||
@page.templatized = false; @page.save!
|
# @page.templatized = false; @page.save!
|
||||||
@sub_page.reload
|
# @sub_page.reload
|
||||||
@sub_page.templatized.should be_false
|
# @sub_page.templatized.should be_false
|
||||||
@sub_page.templatized_from_parent.should be_false
|
# @sub_page.templatized_from_parent.should be_false
|
||||||
@sub_page.target_klass_name.should be_nil
|
# @sub_page.target_klass_name.should be_nil
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
context 'using a content type' do
|
# context 'using a content type' do
|
||||||
|
#
|
||||||
before(:each) do
|
# before(:each) do
|
||||||
@site = FactoryGirl.build(:site)
|
# @site = FactoryGirl.build(:site)
|
||||||
@content_type = FactoryGirl.build(:content_type, :slug => 'posts', :site => @site)
|
# @content_type = FactoryGirl.build(:content_type, :slug => 'posts', :site => @site)
|
||||||
@page.site = @site
|
# @page.site = @site
|
||||||
@page.target_klass_name = 'Locomotive::Entry42'
|
# @page.target_klass_name = 'Locomotive::Entry42'
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'has a name for the target entry' do
|
# it 'has a name for the target entry' do
|
||||||
@site.stubs(:content_types).returns(mock(:find => @content_type))
|
# @site.stubs(:content_types).returns(mock(:find => @content_type))
|
||||||
@page.target_entry_name.should == 'post'
|
# @page.target_entry_name.should == 'post'
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
context '#security' do
|
# context '#security' do
|
||||||
|
#
|
||||||
before(:each) do
|
# before(:each) do
|
||||||
Locomotive::ContentType.stubs(:find).returns(@content_type)
|
# Locomotive::ContentType.stubs(:find).returns(@content_type)
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'is valid if the content type belongs to the site' do
|
# it 'is valid if the content type belongs to the site' do
|
||||||
@page.send(:ensure_target_klass_name_security)
|
# @page.send(:ensure_target_klass_name_security)
|
||||||
@page.errors.should be_empty
|
# @page.errors.should be_empty
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
it 'does not valid the page if the content type does not belong to the site' do
|
# it 'does not valid the page if the content type does not belong to the site' do
|
||||||
@content_type.site = FactoryGirl.build(:site)
|
# @content_type.site = FactoryGirl.build(:site)
|
||||||
@page.send(:ensure_target_klass_name_security)
|
# @page.send(:ensure_target_klass_name_security)
|
||||||
@page.errors[:target_klass_name].should == ['presents a security problem']
|
# @page.errors[:target_klass_name].should == ['presents a security problem']
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
end
|
# end
|
||||||
|
#
|
||||||
end
|
# end
|
||||||
|
|
||||||
describe 'listed extension' do
|
describe 'listed extension' do
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ describe Locomotive::Site do
|
||||||
@site = FactoryGirl.create(:site)
|
@site = FactoryGirl.create(:site)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should create index and 404 pages' do
|
it 'creates index and 404 pages' do
|
||||||
@site.pages.size.should == 2
|
@site.pages.size.should == 2
|
||||||
@site.pages.map(&:fullpath).sort.should == %w{404 index}
|
@site.pages.map(&:fullpath).sort.should == %w{404 index}
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,7 +26,7 @@ describe Locomotive::Snippet do
|
||||||
context 'with a normal top level snippet' do
|
context 'with a normal top level snippet' do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@page = FactoryGirl.create(:page, :site => @site, :slug => 'my_page_here', :raw_template => "{% include 'my_test_snippet' %}")
|
@page = FactoryGirl.create(:page, :site => @site, :parent => @site.pages.root.first, :slug => 'my_page_here', :raw_template => "{% include 'my_test_snippet' %}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates templates with the new snippet template' do
|
it 'updates templates with the new snippet template' do
|
||||||
|
@ -39,7 +39,7 @@ describe Locomotive::Snippet do
|
||||||
context 'for snippets inside of a block' do
|
context 'for snippets inside of a block' do
|
||||||
|
|
||||||
before :each do
|
before :each do
|
||||||
@page = FactoryGirl.create(:page, :site => @site, :slug => 'my_page_here', :raw_template => "{% block main %}{% include 'my_test_snippet' %}{% endblock %}")
|
@page = FactoryGirl.create(:page, :site => @site, :parent => @site.pages.root.first, :slug => 'my_page_here', :raw_template => "{% block main %}{% include 'my_test_snippet' %}{% endblock %}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates templates with the new snippet template' do
|
it 'updates templates with the new snippet template' do
|
||||||
|
@ -54,7 +54,7 @@ describe Locomotive::Snippet do
|
||||||
before :each do
|
before :each do
|
||||||
Mongoid::Fields::I18n.with_locale(:fr) do
|
Mongoid::Fields::I18n.with_locale(:fr) do
|
||||||
@snippet = FactoryGirl.create(:snippet, :site => @site, :slug => 'my_localized_test_snippet', :template => 'a testing template')
|
@snippet = FactoryGirl.create(:snippet, :site => @site, :slug => 'my_localized_test_snippet', :template => 'a testing template')
|
||||||
@page = FactoryGirl.create(:page, :site => @site, :slug => 'my_localized_test_snippet', :raw_template => "{% block main %}{% include 'my_localized_test_snippet' %}{% endblock %}")
|
@page = FactoryGirl.create(:page, :site => @site, :parent => @site.pages.root.first, :slug => 'my_localized_test_snippet', :raw_template => "{% block main %}{% include 'my_localized_test_snippet' %}{% endblock %}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue