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)
|
||||
cells (~> 3.8.0)
|
||||
codemirror-rails (~> 2.21)
|
||||
custom_fields (~> 2.0.0.rc3)
|
||||
custom_fields (~> 2.0.0.rc4)
|
||||
devise (~> 1.5.3)
|
||||
dragonfly (~> 0.9.8)
|
||||
flash_cookie_session (~> 1.1.1)
|
||||
@ -56,7 +56,7 @@ PATH
|
||||
PATH
|
||||
remote: ../gems/custom_fields
|
||||
specs:
|
||||
custom_fields (2.0.0.rc3)
|
||||
custom_fields (2.0.0.rc4)
|
||||
activesupport (~> 3.2.1)
|
||||
carrierwave-mongoid (~> 0.1.3)
|
||||
mongoid (~> 2.4.3)
|
||||
@ -123,7 +123,7 @@ GEM
|
||||
childprocess (0.3.0)
|
||||
ffi (~> 1.0.6)
|
||||
chunky_png (1.2.5)
|
||||
codemirror-rails (2.21)
|
||||
codemirror-rails (2.21.1)
|
||||
railties (~> 3.0)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
|
@ -21,4 +21,7 @@ class Locomotive.Models.Page extends Backbone.Model
|
||||
delete hash['editable_elements']
|
||||
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
|
@ -111,9 +111,9 @@ class Locomotive.Views.Pages.FormView extends Locomotive.Views.Shared.FormView
|
||||
@_enable_checkbox 'templatized',
|
||||
features: ['slug', 'redirect', 'listed']
|
||||
on_callback: =>
|
||||
@$('li#page_content_type_id_input').show()
|
||||
@$('li#page_target_klass_name_input').show()
|
||||
off_callback: =>
|
||||
@$('li#page_content_type_id_input').hide()
|
||||
@$('li#page_target_klass_name_input').hide()
|
||||
|
||||
enable_redirect_checkbox: ->
|
||||
@_enable_checkbox 'redirect',
|
||||
|
@ -15,22 +15,12 @@ module Locomotive
|
||||
|
||||
skip_before_filter :verify_authenticity_token
|
||||
|
||||
skip_load_and_authorize_resource
|
||||
|
||||
self.responder = Locomotive::ActionController::Responder # custom responder
|
||||
|
||||
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
|
||||
|
||||
def current_ability
|
||||
|
@ -32,6 +32,13 @@ module Locomotive
|
||||
list
|
||||
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
|
||||
[
|
||||
[t('.cache_strategy.none'), 'none'],
|
||||
|
@ -57,6 +57,10 @@ module Locomotive
|
||||
next_or_previous :lt
|
||||
end
|
||||
|
||||
def self.find_by_permalink(permalink)
|
||||
self.where(:_slug => permalink).first
|
||||
end
|
||||
|
||||
def self.sort_entries!(ids)
|
||||
list = self.any_in(:_id => ids.map { |id| BSON::ObjectId.from_string(id.to_s) }).to_a
|
||||
ids.each_with_index do |id, position|
|
||||
|
@ -18,8 +18,6 @@ module Locomotive
|
||||
accepts_nested_attributes_for :editable_elements
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
def disable_parent_editable_elements(block)
|
||||
self.editable_elements.each { |el| el.disabled = true if el.from_parent? && el.block == block }
|
||||
end
|
||||
@ -116,8 +114,6 @@ module Locomotive
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -20,8 +20,6 @@ module Locomotive
|
||||
scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
def template
|
||||
@template ||= Marshal.load(self.serialized_template.to_s) rescue nil
|
||||
end
|
||||
@ -109,8 +107,6 @@ module Locomotive
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -7,21 +7,54 @@ module Locomotive
|
||||
|
||||
included do
|
||||
|
||||
belongs_to :content_type, :class_name => 'Locomotive::ContentType'
|
||||
|
||||
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 :ensure_target_klass_name_security
|
||||
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
|
||||
self.slug = 'content_type_template' if self.templatized?
|
||||
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
|
||||
|
@ -7,8 +7,12 @@ module Locomotive
|
||||
self.source.ordered_entries_custom_fields.collect(&:as_json)
|
||||
end
|
||||
|
||||
def klass_name
|
||||
self.source.klass_with_custom_fields(:entries).to_s
|
||||
end
|
||||
|
||||
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
|
||||
|
@ -30,10 +30,10 @@
|
||||
|
||||
= 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 :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 :listed, :as => :'Locomotive::Toggle'
|
||||
|
@ -33,7 +33,7 @@ fr:
|
||||
extname_changed: "Nouveau fichier n'a pas l'extension original"
|
||||
array_too_short: "est trop petit (le nombre minimum d'éléments est %{count})"
|
||||
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:
|
||||
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"
|
||||
|
@ -54,6 +54,7 @@ en:
|
||||
password_confirmation: New password confirmation
|
||||
page:
|
||||
seo_title: Title
|
||||
target_klass_name: Model
|
||||
site:
|
||||
locales: Languages
|
||||
|
||||
@ -63,7 +64,7 @@ en:
|
||||
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."
|
||||
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."
|
||||
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."
|
||||
|
@ -51,7 +51,7 @@ Locomotive.configure do |config|
|
||||
# tell if logs are enabled. Useful for debug purpose.
|
||||
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
|
||||
# on your deployment target (server, Heroku, Bushido, ...etc)
|
||||
#
|
||||
@ -65,6 +65,9 @@ Locomotive.configure do |config|
|
||||
# follow the Dependency Injection pattern
|
||||
# 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:
|
||||
# config.rack_cache = {
|
||||
# :verbose => true,
|
||||
|
@ -43,7 +43,6 @@ module Locomotive
|
||||
end
|
||||
|
||||
def localized?
|
||||
Rails.logger.debug "localized? #{@locomotive_localized.inspect}"
|
||||
!!@locomotive_localized
|
||||
end
|
||||
|
||||
|
@ -27,7 +27,8 @@ module Locomotive
|
||||
:entitystore => URI.encode("file:#{Rails.root}/tmp/dragonfly/cache/body")
|
||||
},
|
||||
: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
|
||||
|
@ -11,6 +11,10 @@ module Locomotive
|
||||
input.to_s.gsub(' ', '-').gsub('/', '-').dasherize
|
||||
end
|
||||
|
||||
def multi_line(input)
|
||||
input.to_s.gsub("\n", '<br/>')
|
||||
end
|
||||
|
||||
def concat(input, *args)
|
||||
result = input.to_s
|
||||
args.flatten.each { |a| result << a.to_s }
|
||||
@ -21,6 +25,14 @@ module Locomotive
|
||||
(index.to_i + 1) % modulo == 0 ? word : ''
|
||||
end
|
||||
|
||||
def first(input)
|
||||
input.first
|
||||
end
|
||||
|
||||
def last(input)
|
||||
input.last
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
::Liquid::Template.register_filter(Misc)
|
||||
|
@ -3,8 +3,6 @@ module Locomotive
|
||||
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
protected
|
||||
|
||||
def render_locomotive_page
|
||||
@ -45,7 +43,7 @@ module Locomotive
|
||||
page = nil
|
||||
else
|
||||
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
|
||||
page = nil
|
||||
@ -80,7 +78,7 @@ module Locomotive
|
||||
|
||||
if @page.templatized? # add instance from content type
|
||||
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
|
||||
|
||||
registers = {
|
||||
@ -124,6 +122,4 @@ module Locomotive
|
||||
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
|
||||
# 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:
|
||||
# config.rack_cache = {
|
||||
# :verbose => true,
|
||||
|
Loading…
Reference in New Issue
Block a user