templatized page can now use models from the main app + add new liquid filters
This commit is contained in:
parent
39d9c354da
commit
62eaeb10f5
@ -27,7 +27,7 @@ PATH
|
|||||||
carrierwave-mongoid (~> 0.1.3)
|
carrierwave-mongoid (~> 0.1.3)
|
||||||
cells (~> 3.8.0)
|
cells (~> 3.8.0)
|
||||||
codemirror-rails (~> 2.21)
|
codemirror-rails (~> 2.21)
|
||||||
custom_fields (~> 2.0.0.rc3)
|
custom_fields (~> 2.0.0.rc4)
|
||||||
devise (~> 1.5.3)
|
devise (~> 1.5.3)
|
||||||
dragonfly (~> 0.9.8)
|
dragonfly (~> 0.9.8)
|
||||||
flash_cookie_session (~> 1.1.1)
|
flash_cookie_session (~> 1.1.1)
|
||||||
@ -56,7 +56,7 @@ PATH
|
|||||||
PATH
|
PATH
|
||||||
remote: ../gems/custom_fields
|
remote: ../gems/custom_fields
|
||||||
specs:
|
specs:
|
||||||
custom_fields (2.0.0.rc3)
|
custom_fields (2.0.0.rc4)
|
||||||
activesupport (~> 3.2.1)
|
activesupport (~> 3.2.1)
|
||||||
carrierwave-mongoid (~> 0.1.3)
|
carrierwave-mongoid (~> 0.1.3)
|
||||||
mongoid (~> 2.4.3)
|
mongoid (~> 2.4.3)
|
||||||
@ -123,7 +123,7 @@ GEM
|
|||||||
childprocess (0.3.0)
|
childprocess (0.3.0)
|
||||||
ffi (~> 1.0.6)
|
ffi (~> 1.0.6)
|
||||||
chunky_png (1.2.5)
|
chunky_png (1.2.5)
|
||||||
codemirror-rails (2.21)
|
codemirror-rails (2.21.1)
|
||||||
railties (~> 3.0)
|
railties (~> 3.0)
|
||||||
coffee-rails (3.2.2)
|
coffee-rails (3.2.2)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
|
@ -21,4 +21,7 @@ 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
|
@ -111,9 +111,9 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
|||||||
@_enable_checkbox 'templatized',
|
@_enable_checkbox 'templatized',
|
||||||
features: ['slug', 'redirect', 'listed']
|
features: ['slug', 'redirect', 'listed']
|
||||||
on_callback: =>
|
on_callback: =>
|
||||||
@$('li#page_content_type_id_input').show()
|
@$('li#page_target_klass_name_input').show()
|
||||||
off_callback: =>
|
off_callback: =>
|
||||||
@$('li#page_content_type_id_input').hide()
|
@$('li#page_target_klass_name_input').hide()
|
||||||
|
|
||||||
enable_redirect_checkbox: ->
|
enable_redirect_checkbox: ->
|
||||||
@_enable_checkbox 'redirect',
|
@_enable_checkbox 'redirect',
|
||||||
|
@ -15,22 +15,12 @@ module Locomotive
|
|||||||
|
|
||||||
skip_before_filter :verify_authenticity_token
|
skip_before_filter :verify_authenticity_token
|
||||||
|
|
||||||
|
skip_load_and_authorize_resource
|
||||||
|
|
||||||
self.responder = Locomotive::ActionController::Responder # custom responder
|
self.responder = Locomotive::ActionController::Responder # custom responder
|
||||||
|
|
||||||
respond_to :json, :xml
|
respond_to :json, :xml
|
||||||
|
|
||||||
rescue_from CanCan::AccessDenied do |exception|
|
|
||||||
::Locomotive.log "[CanCan::AccessDenied] #{exception.inspect}"
|
|
||||||
|
|
||||||
if request.xhr?
|
|
||||||
render :json => { :error => exception.message }
|
|
||||||
else
|
|
||||||
flash[:alert] = exception.message
|
|
||||||
|
|
||||||
redirect_to pages_url
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def current_ability
|
def current_ability
|
||||||
|
@ -32,6 +32,13 @@ 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'],
|
||||||
|
@ -57,6 +57,10 @@ module Locomotive
|
|||||||
next_or_previous :lt
|
next_or_previous :lt
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.find_by_permalink(permalink)
|
||||||
|
self.where(:_slug => permalink).first
|
||||||
|
end
|
||||||
|
|
||||||
def self.sort_entries!(ids)
|
def self.sort_entries!(ids)
|
||||||
list = self.any_in(:_id => ids.map { |id| BSON::ObjectId.from_string(id.to_s) }).to_a
|
list = self.any_in(:_id => ids.map { |id| BSON::ObjectId.from_string(id.to_s) }).to_a
|
||||||
ids.each_with_index do |id, position|
|
ids.each_with_index do |id, position|
|
||||||
|
@ -18,8 +18,6 @@ module Locomotive
|
|||||||
accepts_nested_attributes_for :editable_elements
|
accepts_nested_attributes_for :editable_elements
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
|
|
||||||
def disable_parent_editable_elements(block)
|
def disable_parent_editable_elements(block)
|
||||||
self.editable_elements.each { |el| el.disabled = true if el.from_parent? && el.block == block }
|
self.editable_elements.each { |el| el.disabled = true if el.from_parent? && el.block == block }
|
||||||
end
|
end
|
||||||
@ -116,8 +114,6 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -20,8 +20,6 @@ module Locomotive
|
|||||||
scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
|
scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
|
|
||||||
def template
|
def template
|
||||||
@template ||= Marshal.load(self.serialized_template.to_s) rescue nil
|
@template ||= Marshal.load(self.serialized_template.to_s) rescue nil
|
||||||
end
|
end
|
||||||
@ -109,8 +107,6 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -7,21 +7,54 @@ module Locomotive
|
|||||||
|
|
||||||
included do
|
included do
|
||||||
|
|
||||||
belongs_to :content_type, :class_name => 'Locomotive::ContentType'
|
|
||||||
|
|
||||||
field :templatized, :type => Boolean, :default => false
|
field :templatized, :type => Boolean, :default => false
|
||||||
|
field :target_klass_name
|
||||||
|
|
||||||
field :content_type_visible_column
|
## validations ##
|
||||||
|
validates_presence_of :target_klass_name, :if => :templatized?
|
||||||
|
validate :ensure_target_klass_name_security
|
||||||
|
|
||||||
|
## callbacks ##
|
||||||
before_validation :set_slug_if_templatized
|
before_validation :set_slug_if_templatized
|
||||||
|
before_validation :ensure_target_klass_name_security
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
def target_klass
|
||||||
|
target_klass_name.constantize
|
||||||
|
end
|
||||||
|
|
||||||
|
def target_entry_name
|
||||||
|
if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
||||||
|
@content_type ||= self.site.content_types.find($1)
|
||||||
|
@content_type.slug.singularize
|
||||||
|
else
|
||||||
|
self.target_klass_name.underscore
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_target_entry(permalink)
|
||||||
|
target_klass.find_by_permalink(permalink)
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
def set_slug_if_templatized
|
def set_slug_if_templatized
|
||||||
self.slug = 'content_type_template' if self.templatized?
|
self.slug = 'content_type_template' if self.templatized?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_target_klass_name_security
|
||||||
|
return if !self.templatized? || self.target_klass_name.blank?
|
||||||
|
|
||||||
|
if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
||||||
|
content_type = Locomotive::ContentType.find($1)
|
||||||
|
|
||||||
|
if content_type.site_id != self.site_id
|
||||||
|
self.errors.add :target_klass_name, :security
|
||||||
|
end
|
||||||
|
elsif !Locomotive.config.models_for_templatization.include?(self.target_klass_name)
|
||||||
|
self.errors.add :target_klass_name, :security
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -7,8 +7,12 @@ module Locomotive
|
|||||||
self.source.ordered_entries_custom_fields.collect(&:as_json)
|
self.source.ordered_entries_custom_fields.collect(&:as_json)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def klass_name
|
||||||
|
self.source.klass_with_custom_fields(:entries).to_s
|
||||||
|
end
|
||||||
|
|
||||||
def included_methods
|
def included_methods
|
||||||
super + %w(name description slug order_by order_direction highlighted_field_name group_by_field_name api_accounts entries_custom_fields)
|
super + %w(name description slug order_by order_direction highlighted_field_name group_by_field_name api_accounts entries_custom_fields klass_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -30,10 +30,10 @@
|
|||||||
|
|
||||||
= f.inputs :name => :advanced_options, :id => 'advanced-options', :class => "inputs foldable #{'folded' if inputs_folded?(@page)}" do
|
= f.inputs :name => :advanced_options, :id => 'advanced-options', :class => "inputs foldable #{'folded' if inputs_folded?(@page)}" do
|
||||||
|
|
||||||
= f.input :content_type_id, :as => :select, :collection => current_site.content_types.all.to_a, :include_blank => false, :wrapper_html => { :style => "#{'display: none' unless @page.templatized?}" }
|
|
||||||
|
|
||||||
= f.input :templatized, :as => :'Locomotive::Toggle', :style => "#{'display: none' if @page.redirect?}"
|
= f.input :templatized, :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' unless @page.templatized?}" }
|
||||||
|
|
||||||
= f.input :published, :as => :'Locomotive::Toggle'
|
= f.input :published, :as => :'Locomotive::Toggle'
|
||||||
|
|
||||||
= f.input :listed, :as => :'Locomotive::Toggle'
|
= f.input :listed, :as => :'Locomotive::Toggle'
|
||||||
|
@ -33,7 +33,7 @@ fr:
|
|||||||
extname_changed: "Nouveau fichier n'a pas l'extension original"
|
extname_changed: "Nouveau fichier n'a pas l'extension original"
|
||||||
array_too_short: "est trop petit (le nombre minimum d'éléments est %{count})"
|
array_too_short: "est trop petit (le nombre minimum d'éléments est %{count})"
|
||||||
liquid_syntax: "Erreur de syntaxe ('%{error}')"
|
liquid_syntax: "Erreur de syntaxe ('%{error}')"
|
||||||
invalid_theme_file: "doit être rempli ou n'est pas un fichier zip"
|
security: "présente un problème de sécurité"
|
||||||
page:
|
page:
|
||||||
liquid_syntax: "Erreur de syntaxe dans les sections de page, veuillez vérifier la syntaxe ('%{error}'/'%{fullpath}')"
|
liquid_syntax: "Erreur de syntaxe dans les sections de page, veuillez vérifier la syntaxe ('%{error}'/'%{fullpath}')"
|
||||||
liquid_extend: "La page '%{fullpath}' étend le contenu d'une page qui n'existe pas"
|
liquid_extend: "La page '%{fullpath}' étend le contenu d'une page qui n'existe pas"
|
||||||
|
@ -54,6 +54,7 @@ en:
|
|||||||
password_confirmation: New password confirmation
|
password_confirmation: New password confirmation
|
||||||
page:
|
page:
|
||||||
seo_title: Title
|
seo_title: Title
|
||||||
|
target_klass_name: Model
|
||||||
site:
|
site:
|
||||||
locales: Languages
|
locales: Languages
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ en:
|
|||||||
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."
|
templatized: "Use the page as a template for a model you defined."
|
||||||
listed: "Control whether to show the page from generated menus."
|
listed: "Control whether to show the page from generated menus."
|
||||||
content_type_id: "The type of content this page will be a template for."
|
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."
|
||||||
|
@ -51,7 +51,7 @@ Locomotive.configure do |config|
|
|||||||
# tell if logs are enabled. Useful for debug purpose.
|
# tell if logs are enabled. Useful for debug purpose.
|
||||||
config.enable_logs = true
|
config.enable_logs = true
|
||||||
|
|
||||||
# Configure the e-mail address which will be shown in the DeviseMailer, NotificationMailer, ...etc
|
# configure the e-mail address which will be shown in the DeviseMailer, NotificationMailer, ...etc
|
||||||
# if you do not put the domain name in the email, Locomotive will take the default domain name depending
|
# if you do not put the domain name in the email, Locomotive will take the default domain name depending
|
||||||
# on your deployment target (server, Heroku, Bushido, ...etc)
|
# on your deployment target (server, Heroku, Bushido, ...etc)
|
||||||
#
|
#
|
||||||
@ -65,6 +65,9 @@ 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,
|
||||||
|
@ -43,7 +43,6 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
def localized?
|
def localized?
|
||||||
Rails.logger.debug "localized? #{@locomotive_localized.inspect}"
|
|
||||||
!!@locomotive_localized
|
!!@locomotive_localized
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@ module Locomotive
|
|||||||
:entitystore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body")
|
:entitystore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body")
|
||||||
},
|
},
|
||||||
:devise_modules => [:rememberable, :database_authenticatable, :token_authenticatable, :recoverable, :trackable, :validatable, :encryptable, { :encryptor => :sha1 }],
|
:devise_modules => [:rememberable, :database_authenticatable, :token_authenticatable, :recoverable, :trackable, :validatable, :encryptable, { :encryptor => :sha1 }],
|
||||||
:context_assign_extensions => { }
|
:context_assign_extensions => { },
|
||||||
|
:models_for_templatization => []
|
||||||
}
|
}
|
||||||
|
|
||||||
cattr_accessor :settings
|
cattr_accessor :settings
|
||||||
|
@ -11,6 +11,10 @@ module Locomotive
|
|||||||
input.to_s.gsub(' ', '-').gsub('/', '-').dasherize
|
input.to_s.gsub(' ', '-').gsub('/', '-').dasherize
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def multi_line(input)
|
||||||
|
input.to_s.gsub("\n", '<br/>')
|
||||||
|
end
|
||||||
|
|
||||||
def concat(input, *args)
|
def concat(input, *args)
|
||||||
result = input.to_s
|
result = input.to_s
|
||||||
args.flatten.each { |a| result << a.to_s }
|
args.flatten.each { |a| result << a.to_s }
|
||||||
@ -21,6 +25,14 @@ module Locomotive
|
|||||||
(index.to_i + 1) % modulo == 0 ? word : ''
|
(index.to_i + 1) % modulo == 0 ? word : ''
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def first(input)
|
||||||
|
input.first
|
||||||
|
end
|
||||||
|
|
||||||
|
def last(input)
|
||||||
|
input.last
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
::Liquid::Template.register_filter(Misc)
|
::Liquid::Template.register_filter(Misc)
|
||||||
|
@ -3,8 +3,6 @@ module Locomotive
|
|||||||
|
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
module InstanceMethods
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def render_locomotive_page
|
def render_locomotive_page
|
||||||
@ -45,7 +43,7 @@ module Locomotive
|
|||||||
page = nil
|
page = nil
|
||||||
else
|
else
|
||||||
if page.templatized?
|
if page.templatized?
|
||||||
@content_entry = page.content_type.entries.where(:_slug => File.basename(path.first)).first
|
@content_entry = page.fetch_target_entry(File.basename(path.first))
|
||||||
|
|
||||||
if @content_entry.nil? || (!@content_entry.visible? && current_locomotive_account.nil?) # content instance not found or not visible
|
if @content_entry.nil? || (!@content_entry.visible? && current_locomotive_account.nil?) # content instance not found or not visible
|
||||||
page = nil
|
page = nil
|
||||||
@ -80,7 +78,7 @@ module Locomotive
|
|||||||
|
|
||||||
if @page.templatized? # add instance from content type
|
if @page.templatized? # add instance from content type
|
||||||
assigns['entry'] = @content_entry
|
assigns['entry'] = @content_entry
|
||||||
assigns[@page.content_type.slug.singularize] = @content_entry # just here to help to write readable liquid code
|
assigns[@page.target_entry_name] = @content_entry # just here to help to write readable liquid code
|
||||||
end
|
end
|
||||||
|
|
||||||
registers = {
|
registers = {
|
||||||
@ -124,6 +122,4 @@ module Locomotive
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
7
spec/dummy/app/models/foo.rb
Normal file
7
spec/dummy/app/models/foo.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
class Foo
|
||||||
|
|
||||||
|
include Mongoid::Document
|
||||||
|
|
||||||
|
field :name
|
||||||
|
|
||||||
|
end
|
@ -66,6 +66,9 @@ 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,
|
||||||
|
Loading…
Reference in New Issue
Block a user