refactor and clean code (wip) + the api controller has been deleted and replace by the entry_submission_controller (+ custom responder)
This commit is contained in:
parent
435d4067c0
commit
4c204ef6a6
10
Gemfile
10
Gemfile
@ -6,22 +6,22 @@ gem 'rake', '0.9.2'
|
||||
|
||||
gem 'rails', '~> 3.1.3'
|
||||
|
||||
gem 'devise', :git => 'git://github.com/plataformatec/devise.git'# FIXME: waiting for the new devise gem coming soon
|
||||
gem 'devise', '~> 1.5.3'
|
||||
gem 'cancan', '~> 1.6.7'
|
||||
|
||||
gem 'bson_ext', '~> 1.4.0'
|
||||
gem 'mongoid', '~> 2.3.3'
|
||||
gem 'mongo', '~> 1.5.2'
|
||||
gem 'bson_ext', '~> 1.5.2'
|
||||
gem 'mongoid', '~> 2.4.0'
|
||||
gem 'locomotive_mongoid_acts_as_tree', :git => 'git@github.com:locomotivecms/mongoid_acts_as_tree.git'
|
||||
# gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git'
|
||||
gem 'custom_fields', :path => '../gems/custom_fields' # DEV
|
||||
# gem 'custom_fields', :git => 'git://github.com/locomotivecms/custom_fields.git', :branch => 'experimental'
|
||||
gem 'kaminari'
|
||||
|
||||
gem 'haml', '~> 3.1.3'
|
||||
gem 'sass-rails', '~> 3.1.4'
|
||||
gem "compass", :git => 'git://github.com/chriseppstein/compass.git'
|
||||
gem 'coffee-script', '~> 2.2.0'
|
||||
gem 'uglifier', '~> 1.0.4'
|
||||
gem 'compass', '~> 0.12.alpha.4'
|
||||
gem 'jquery-rails', '~> 1.0.16'
|
||||
gem 'rails-backbone', '0.5.4'
|
||||
gem 'codemirror-rails'
|
||||
|
43
Gemfile.lock
43
Gemfile.lock
@ -1,22 +1,3 @@
|
||||
GIT
|
||||
remote: git://github.com/chriseppstein/compass.git
|
||||
revision: bffba483754cb9381fa51efd8e2a1f0482a21ac6
|
||||
specs:
|
||||
compass (0.12.alpha.4.bffba48)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.1)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/plataformatec/devise.git
|
||||
revision: a949f9eca24f9d43f516363fbf2f5d004623355e
|
||||
specs:
|
||||
devise (2.0.0.rc)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.0.3)
|
||||
railties (~> 3.1)
|
||||
warden (~> 1.1)
|
||||
|
||||
GIT
|
||||
remote: git@github.com:locomotivecms/mongoid_acts_as_tree.git
|
||||
revision: ca494d22c3d7946385aba1153c017d9c30e9f9d3
|
||||
@ -29,7 +10,7 @@ PATH
|
||||
custom_fields (2.0.0.rc1)
|
||||
activesupport (~> 3.1.3)
|
||||
carrierwave-mongoid (~> 0.1.3)
|
||||
mongoid (~> 2.3.4)
|
||||
mongoid (~> 2.4.0)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
@ -73,7 +54,8 @@ GEM
|
||||
ZenTest (>= 4.4.1)
|
||||
bcrypt-ruby (3.0.1)
|
||||
bson (1.5.2)
|
||||
bson_ext (1.4.0)
|
||||
bson_ext (1.5.2)
|
||||
bson (= 1.5.2)
|
||||
builder (3.0.0)
|
||||
bushido (0.0.35)
|
||||
highline (>= 1.6.1)
|
||||
@ -105,6 +87,10 @@ GEM
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.2.0)
|
||||
compass (0.12.alpha.4)
|
||||
chunky_png (~> 1.2)
|
||||
fssm (>= 0.2.7)
|
||||
sass (~> 3.1)
|
||||
cucumber (1.1.4)
|
||||
builder (>= 2.1.2)
|
||||
diff-lcs (>= 1.1.2)
|
||||
@ -121,6 +107,10 @@ GEM
|
||||
delayed_job_mongoid (1.0.8)
|
||||
delayed_job (~> 3.0.0)
|
||||
mongoid (>= 2.0)
|
||||
devise (1.5.3)
|
||||
bcrypt-ruby (~> 3.0)
|
||||
orm_adapter (~> 0.0.3)
|
||||
warden (~> 1.1)
|
||||
diff-lcs (1.1.3)
|
||||
dragonfly (0.9.9)
|
||||
rack
|
||||
@ -182,7 +172,7 @@ GEM
|
||||
mocha (0.9.12)
|
||||
mongo (1.5.2)
|
||||
bson (= 1.5.2)
|
||||
mongoid (2.3.4)
|
||||
mongoid (2.4.0)
|
||||
activemodel (~> 3.1)
|
||||
mongo (~> 1.3)
|
||||
tzinfo (~> 0.3.22)
|
||||
@ -298,7 +288,7 @@ DEPENDENCIES
|
||||
ZenTest
|
||||
actionmailer-with-request (~> 0.3.0)
|
||||
autotest
|
||||
bson_ext (~> 1.4.0)
|
||||
bson_ext (~> 1.5.2)
|
||||
bushido (= 0.0.35)
|
||||
cancan (~> 1.6.7)
|
||||
capybara
|
||||
@ -306,12 +296,12 @@ DEPENDENCIES
|
||||
cells (~> 3.7.0)
|
||||
codemirror-rails
|
||||
coffee-script (~> 2.2.0)
|
||||
compass!
|
||||
compass (~> 0.12.alpha.4)
|
||||
cucumber-rails
|
||||
custom_fields!
|
||||
database_cleaner
|
||||
delayed_job_mongoid (~> 1.0.8)
|
||||
devise!
|
||||
devise (~> 1.5.3)
|
||||
dragonfly (~> 0.9.8)
|
||||
factory_girl_rails (~> 1.1)
|
||||
flash_cookie_session (~> 1.1.1)
|
||||
@ -328,7 +318,8 @@ DEPENDENCIES
|
||||
locomotive_mongoid_acts_as_tree!
|
||||
mimetype-fu (~> 0.1.2)
|
||||
mocha (= 0.9.12)
|
||||
mongoid (~> 2.3.3)
|
||||
mongo (~> 1.5.2)
|
||||
mongoid (~> 2.4.0)
|
||||
pickle
|
||||
rack-cache (~> 1.1)
|
||||
rails (~> 3.1.3)
|
||||
|
@ -48,7 +48,7 @@ h2. Community
|
||||
h2. Team
|
||||
|
||||
* Developers: "Didier Lafforgue":http://www.nocoffee.fr, "Jacques Crocker":http://www.railsjedi.com, "Mario Visic":http://www.mariovisic.com
|
||||
* Contributors: "Dirk Kelly":http://www.dirkkelly.com, "Raphael Costa":http://raphaelcosta.net (Brazilian Portuguese translation), "Bernd Hauser":http://www.designhunger.de (German translation), "Andrea Frigido":http://www.frisoft.it (Italian translation), "Enrique García":https://github.com/kikito (Spanish translation), "Lars Smit":https://github.com/larssmit (Dutch translation), "PitOn":https://github.com/GarPit (Russian translation)
|
||||
* Contributors: "Dirk Kelly":http://www.dirkkelly.com, "Raphael Costa":http://raphaelcosta.net (Brazilian Portuguese translation), "Bernd Hauser":http://www.designhunger.de (German translation), "Andrea Frigido":http://www.frisoft.it (Italian translation), "Enrique García":https://github.com/kikito (Spanish translation), "Lars Smit":https://github.com/larssmit (Dutch translation), "PitOn":https://github.com/GarPit (Russian translation), "paulsponagl":https://github.com/paulsponagl
|
||||
* UI Designer: "Sacha Greif":http://www.sachagreif.com
|
||||
* IE maintainer: "Alex Sanford":https://github.com/alexsanford
|
||||
|
||||
|
@ -3,13 +3,11 @@
|
||||
#= require_tree ./utils
|
||||
#= require_tree ./models
|
||||
#= require_tree ./views
|
||||
#= require_tree ./routers
|
||||
|
||||
window.Locomotive =
|
||||
mount_on: '/locomotive'
|
||||
Models: {}
|
||||
Collections: {}
|
||||
Routers: {}
|
||||
Views: {}
|
||||
|
||||
window.Locomotive.Views.Memberships = {}
|
@ -13,7 +13,7 @@ class Locomotive.Models.CustomField extends Backbone.Model
|
||||
toJSONForSave: ->
|
||||
_.tap {}, (hash) =>
|
||||
for key, value of @.toJSON()
|
||||
hash[key] = value unless _.include(['select_options', 'type_text', 'created_at', 'updated_at'], key)
|
||||
hash[key] = value unless _.include(['select_options', 'type_text', 'text_formatting_text', 'created_at', 'updated_at'], key)
|
||||
hash.select_options_attributes = @get('select_options').toJSONForSave() if @get('select_options')
|
||||
|
||||
class Locomotive.Models.CustomFieldsCollection extends Backbone.Collection
|
||||
|
@ -23,7 +23,7 @@ class Locomotive.Views.ContentTypes.FormView extends Locomotive.Views.Shared.For
|
||||
|
||||
@enable_liquid_editing() # turn textarea into editable liquid code zone
|
||||
|
||||
@enable_public_form_checkbox()
|
||||
@enable_public_submission_checkbox()
|
||||
|
||||
@enable_order_by_toggler()
|
||||
|
||||
@ -48,10 +48,10 @@ class Locomotive.Views.ContentTypes.FormView extends Locomotive.Views.Shared.For
|
||||
theme: 'default medium'
|
||||
onChange: (editor) => @model.set(raw_item_template: editor.getValue())
|
||||
|
||||
enable_public_form_checkbox: ->
|
||||
@_enable_checkbox 'public_form_enabled',
|
||||
on_callback: => @$('#content_type_public_form_accounts_input').show()
|
||||
off_callback: => @$('#content_type_public_form_accounts_input').hide()
|
||||
enable_public_submission_checkbox: ->
|
||||
@_enable_checkbox 'public_submission_enabled',
|
||||
on_callback: => @$('#content_type_public_submission_accounts_input').show()
|
||||
off_callback: => @$('#content_type_public_submission_accounts_input').hide()
|
||||
|
||||
enable_order_by_toggler: ->
|
||||
@$('#content_type_order_by_input').bind 'change', (event) =>
|
||||
|
@ -1,61 +0,0 @@
|
||||
module Locomotive
|
||||
class ApiContentsController < ActionController::Base
|
||||
|
||||
# FIXME: NEED REFACTORING
|
||||
|
||||
include Locomotive::Routing::SiteDispatcher
|
||||
|
||||
before_filter :require_site
|
||||
|
||||
before_filter :set_content_type
|
||||
|
||||
before_filter :block_content_type_with_disabled_api
|
||||
|
||||
before_filter :sanitize_content_params, :only => :create
|
||||
|
||||
def create
|
||||
@entry = @content_type.entries.build(params[:entry])
|
||||
|
||||
respond_to do |format|
|
||||
if @entry.save
|
||||
format.json { render :json => { :entry => @entry } }
|
||||
format.html do
|
||||
flash[@content_type.slug.singularize] = @entry.aliased_attributes
|
||||
redirect_to params[:success_callback]
|
||||
end
|
||||
else
|
||||
format.json { render :json => { :entry => @content, :errors => @content.errors } }
|
||||
format.html do
|
||||
flash[@content_type.slug.singularize] = @content.aliased_attributes
|
||||
flash['errors'] = @content.errors_to_hash
|
||||
redirect_to params[:error_callback]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def set_content_type
|
||||
@content_type = current_site.content_types.where(:slug => params[:slug]).first
|
||||
end
|
||||
|
||||
def block_content_type_with_disabled_api
|
||||
unless @content_type.api_enabled?
|
||||
respond_to do |format|
|
||||
format.json { render :json => { :error => 'Api not enabled' }, :status => :forbidden }
|
||||
format.html { render :text => 'Api not enabled', :status => :forbidden }
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def sanitize_content_params
|
||||
(params[:content] || {}).each do |key, value|
|
||||
next unless value.is_a?(String)
|
||||
params[:content][key] = Sanitize.clean(value, Sanitize::Config::BASIC)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -3,6 +3,8 @@ module Locomotive
|
||||
|
||||
include Locomotive::Routing::SiteDispatcher
|
||||
|
||||
include Locomotive::ActionController::Helpers
|
||||
|
||||
layout '/locomotive/layouts/application'
|
||||
|
||||
before_filter :require_account
|
||||
@ -17,15 +19,11 @@ module Locomotive
|
||||
|
||||
before_filter :set_current_thread_variables
|
||||
|
||||
helper_method :sections, :current_site_public_url, :switch_to_site_url, :public_page_url, :current_ability
|
||||
helper_method :sections, :current_ability
|
||||
|
||||
# https://rails.lighthouseapp.com/projects/8994/tickets/1905-apphelpers-within-plugin-not-being-mixed-in
|
||||
helper Locomotive::BaseHelper, Locomotive::ContentTypesHelper #, Locomotive::BoxHelper
|
||||
# Dir[File.dirname(__FILE__) + "/../../helpers/**/*_helper.rb"].each do |file|
|
||||
# helper "locomotive/#{File.basename(file, '.rb').gsub(/_helper$/, '')}"
|
||||
# end
|
||||
helper Locomotive::BaseHelper, Locomotive::ContentTypesHelper
|
||||
|
||||
self.responder = Locomotive::Responder # custom responder
|
||||
self.responder = Locomotive::ActionController::Responder # custom responder
|
||||
|
||||
respond_to :html
|
||||
|
||||
@ -44,8 +42,8 @@ module Locomotive
|
||||
protected
|
||||
|
||||
def set_current_thread_variables
|
||||
Thread.current[:account] = current_locomotive_account
|
||||
Thread.current[:site] = current_site
|
||||
Thread.current[:account] = current_locomotive_account
|
||||
Thread.current[:site] = current_site
|
||||
end
|
||||
|
||||
def current_ability
|
||||
@ -56,51 +54,5 @@ module Locomotive
|
||||
authenticate_locomotive_account!
|
||||
end
|
||||
|
||||
def self.sections(main, sub = nil)
|
||||
before_filter do |c|
|
||||
sub = sub.call(c) if sub.respond_to?(:call)
|
||||
sections = { :main => main, :sub => sub }
|
||||
c.instance_variable_set(:@locomotive_sections, sections)
|
||||
end
|
||||
end
|
||||
|
||||
def sections(key = nil)
|
||||
if !key.nil? && key.to_sym == :sub
|
||||
@locomotive_sections[:sub] || self.controller_name.dasherize
|
||||
else
|
||||
@locomotive_sections[:main]
|
||||
end
|
||||
end
|
||||
|
||||
def set_locale
|
||||
I18n.locale = current_locomotive_account.locale rescue Locomotive.config.default_locale
|
||||
end
|
||||
|
||||
# ___ site/page urls builder ___
|
||||
|
||||
def current_site_public_url
|
||||
request.protocol + request.host_with_port
|
||||
end
|
||||
|
||||
def switch_to_site_url(site, options = {})
|
||||
options = { :fullpath => true, :protocol => true }.merge(options)
|
||||
|
||||
url = "#{site.subdomain}.#{Locomotive.config.domain}"
|
||||
url += ":#{request.port}" if request.port != 80
|
||||
|
||||
url = File.join(url, request.fullpath) if options[:fullpath]
|
||||
url = "http://#{url}" if options[:protocol]
|
||||
url
|
||||
end
|
||||
|
||||
def public_page_url(page, options = {})
|
||||
if content = options.delete(:content)
|
||||
File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug)
|
||||
else
|
||||
File.join(current_site_public_url, page.fullpath)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
19
app/controllers/locomotive/public/base_controller.rb
Normal file
19
app/controllers/locomotive/public/base_controller.rb
Normal file
@ -0,0 +1,19 @@
|
||||
module Locomotive
|
||||
module Public
|
||||
class BaseController < ApplicationController
|
||||
|
||||
include Locomotive::Routing::SiteDispatcher
|
||||
|
||||
include Locomotive::ActionController::Helpers
|
||||
|
||||
before_filter :require_site
|
||||
|
||||
protected
|
||||
|
||||
def set_locale
|
||||
logger.info "[public/set_locale] TODO"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,50 @@
|
||||
module Locomotive
|
||||
module Public
|
||||
class ContentEntriesController < BaseController
|
||||
|
||||
before_filter :set_content_type
|
||||
|
||||
before_filter :sanitize_entry_params, :only => :create
|
||||
|
||||
skip_before_filter :verify_authenticity_token
|
||||
|
||||
self.responder = Locomotive::ActionController::PublicResponder # custom responder
|
||||
|
||||
respond_to :html, :json
|
||||
|
||||
def create
|
||||
@entry = @content_type.entries.create(params[:entry])
|
||||
flash[@content_type.slug.singularize] = @entry.to_presenter(:include_errors => true).as_json
|
||||
respond_with @entry, :location => self.callback_url
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def set_content_type
|
||||
@content_type = current_site.content_types.where(:slug => params[:slug]).first
|
||||
|
||||
# check if ability to receive public submissions
|
||||
unless @content_type.public_submission_enabled?
|
||||
respond_to do |format|
|
||||
format.json { render :json => { :error => 'Public submissions not accepted' }, :status => :forbidden }
|
||||
format.html { render :text => 'Public submissions not accepted', :status => :forbidden }
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def callback_url
|
||||
@entry.errors.empty? ? params[:success_callback] : params[:error_callback]
|
||||
end
|
||||
|
||||
def sanitize_entry_params
|
||||
entry_params = params[:entry] || params[:content] || {}
|
||||
entry_params.each do |key, value|
|
||||
next unless value.is_a?(String)
|
||||
entry_params[key] = Sanitize.clean(value, Sanitize::Config::BASIC)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
26
app/controllers/locomotive/public/rendering_controller.rb
Normal file
26
app/controllers/locomotive/public/rendering_controller.rb
Normal file
@ -0,0 +1,26 @@
|
||||
module Locomotive
|
||||
module Public
|
||||
class RenderingController < ApplicationController
|
||||
|
||||
include Locomotive::Routing::SiteDispatcher
|
||||
|
||||
include Locomotive::Render
|
||||
|
||||
before_filter :require_site
|
||||
|
||||
before_filter :authenticate_admin!, :only => [:edit]
|
||||
|
||||
before_filter :validate_site_membership, :only => [:edit]
|
||||
|
||||
def show
|
||||
render_locomotive_page
|
||||
end
|
||||
|
||||
def edit
|
||||
@editing = true
|
||||
render_locomotive_page
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
16
app/controllers/locomotive/public/robots_controller.rb
Normal file
16
app/controllers/locomotive/public/robots_controller.rb
Normal file
@ -0,0 +1,16 @@
|
||||
module Locomotive
|
||||
module Public
|
||||
class RobotsController < BaseController
|
||||
|
||||
include Locomotive::Render
|
||||
|
||||
respond_to :txt
|
||||
|
||||
def show
|
||||
template = ::Liquid::Template.parse(current_site.robots_txt)
|
||||
render :text => template.render('request_host' => self.request.host.downcase)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
14
app/controllers/locomotive/public/sitemaps_controller.rb
Normal file
14
app/controllers/locomotive/public/sitemaps_controller.rb
Normal file
@ -0,0 +1,14 @@
|
||||
module Locomotive
|
||||
module Public
|
||||
class SitemapsController < BaseController
|
||||
|
||||
respond_to :xml
|
||||
|
||||
def show
|
||||
@pages = current_site.pages.published
|
||||
respond_with @pages
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
@ -1,22 +0,0 @@
|
||||
module Locomotive
|
||||
class RenderingController < ActionController::Base
|
||||
|
||||
include Locomotive::Routing::SiteDispatcher
|
||||
|
||||
include Locomotive::Render
|
||||
|
||||
before_filter :require_site
|
||||
before_filter :authenticate_admin!, :only => [:edit]
|
||||
before_filter :validate_site_membership, :only => [:edit]
|
||||
|
||||
def show
|
||||
render_locomotive_page
|
||||
end
|
||||
|
||||
def edit
|
||||
@editing = true
|
||||
render_locomotive_page
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -1,18 +0,0 @@
|
||||
module Locomotive
|
||||
class RobotsController < ActionController::Base
|
||||
|
||||
include Locomotive::Routing::SiteDispatcher
|
||||
|
||||
include Locomotive::Render
|
||||
|
||||
before_filter :require_site
|
||||
|
||||
respond_to :txt
|
||||
|
||||
def show
|
||||
template = ::Liquid::Template.parse(current_site.robots_txt)
|
||||
render :text => template.render('request_host' => self.request.host.downcase)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -1,18 +0,0 @@
|
||||
module Locomotive
|
||||
class SitemapsController < BaseController
|
||||
|
||||
skip_before_filter :require_account, :validate_site_membership, :set_locale
|
||||
|
||||
before_filter :require_site
|
||||
|
||||
respond_to :xml
|
||||
|
||||
skip_load_and_authorize_resource
|
||||
|
||||
def show
|
||||
@pages = current_site.pages.published
|
||||
respond_with @pages
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -4,9 +4,9 @@ module Locomotive
|
||||
default :from => Locomotive.config.mailer_sender
|
||||
|
||||
def new_content_entry(account, entry)
|
||||
@account, @entry = account, entry
|
||||
@account, @entry, @type = account, entry.to_presenter, entry.content_type
|
||||
|
||||
subject = t('locomotive.notifications.new_content_entry.subject', :type => entry.content_type.name, :locale => account.locale)
|
||||
subject = t('locomotive.notifications.new_content_entry.subject', :type => @type.name, :locale => account.locale)
|
||||
|
||||
mail :subject => subject, :to => account.email
|
||||
end
|
||||
|
@ -64,8 +64,8 @@ module Locomotive
|
||||
Locomotive::Liquid::Drops::ContentEntry.new(self)
|
||||
end
|
||||
|
||||
def to_presenter
|
||||
Locomotive::ContentEntryPresenter.new(self)
|
||||
def to_presenter(options = {})
|
||||
Locomotive::ContentEntryPresenter.new(self, options)
|
||||
end
|
||||
|
||||
def as_json(options = {})
|
||||
@ -119,10 +119,10 @@ module Locomotive
|
||||
end
|
||||
|
||||
def send_notifications
|
||||
return if !self.content_type.public_form_enabled? || self.content_type.public_form_accounts.blank?
|
||||
return if !self.content_type.public_submission_enabled? || self.content_type.public_submission_accounts.blank?
|
||||
|
||||
self.content_type.site.accounts.each do |account|
|
||||
next unless self.content_type.public_form_accounts.include?(account._id.to_s)
|
||||
next unless self.content_type.public_submission_accounts.include?(account._id.to_s)
|
||||
|
||||
Locomotive::Notifications.new_content_entry(account, self).deliver
|
||||
end
|
||||
|
@ -11,13 +11,13 @@ module Locomotive
|
||||
field :name
|
||||
field :description
|
||||
field :slug
|
||||
field :label_field_id, :type => BSON::ObjectId
|
||||
field :label_field_id, :type => BSON::ObjectId
|
||||
field :label_field_name
|
||||
field :group_by_field_id, :type => BSON::ObjectId
|
||||
field :group_by_field_id, :type => BSON::ObjectId
|
||||
field :order_by
|
||||
field :order_direction, :default => 'asc'
|
||||
field :public_form_enabled, :type => Boolean, :default => false
|
||||
field :public_form_accounts, :type => Array
|
||||
field :order_direction, :default => 'asc'
|
||||
field :public_submission_enabled, :type => Boolean, :default => false
|
||||
field :public_submission_accounts, :type => Array
|
||||
|
||||
## associations ##
|
||||
belongs_to :site, :class_name => 'Locomotive::Site'
|
||||
@ -53,8 +53,8 @@ module Locomotive
|
||||
[order_by_attribute, direction]
|
||||
end
|
||||
|
||||
def ordered_entries
|
||||
self.entries.order_by([order_by_definition])
|
||||
def ordered_entries(conditions = {})
|
||||
self.entries.order_by([order_by_definition]).where(conditions)
|
||||
end
|
||||
|
||||
def groupable?
|
||||
@ -81,71 +81,6 @@ module Locomotive
|
||||
self.to_presenter.as_json
|
||||
end
|
||||
|
||||
# def list_or_group_contents
|
||||
# if self.groupable?
|
||||
# groups = self.contents.klass.send(:"group_by_#{self.group_by_field._alias}", :ordered_contents)
|
||||
#
|
||||
# # look for items with no category or unknown ones
|
||||
# items_without_category = self.contents.find_all { |c| !self.group_by_field.category_ids.include?(c.send(self.group_by_field_name)) }
|
||||
# if not items_without_category.empty?
|
||||
# groups << { :name => nil, :items => items_without_category }
|
||||
# else
|
||||
# groups
|
||||
# end
|
||||
# else
|
||||
# self.ordered_contents
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# def latest_updated_contents
|
||||
# self.contents.latest_updated.reject { |c| !c.persisted? }
|
||||
# end
|
||||
#
|
||||
# def ordered_contents(conditions = {})
|
||||
# column = self.order_by.to_sym
|
||||
#
|
||||
# list = (if conditions.nil? || conditions.empty?
|
||||
# self.contents
|
||||
# else
|
||||
# conditions_with_names = {}
|
||||
#
|
||||
# conditions.each do |key, value|
|
||||
# # convert alias (key) to name
|
||||
# field = self.entries_custom_fields.detect { |f| f._alias == key }
|
||||
#
|
||||
# case field.kind.to_sym
|
||||
# when :category
|
||||
# if (category_item = field.category_items.where(:name => value).first).present?
|
||||
# conditions_with_names[field._name.to_sym] = category_item._id
|
||||
# end
|
||||
# else
|
||||
# conditions_with_names[field._name.to_sym] = value
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# self.contents.where(conditions_with_names)
|
||||
# end).sort { |a, b| (a.send(column) && b.send(column)) ? (a.send(column) || 0) <=> (b.send(column) || 0) : 0 }
|
||||
#
|
||||
# return list if self.order_manually?
|
||||
#
|
||||
# self.asc_order? ? list : list.reverse
|
||||
# end
|
||||
#
|
||||
# def sort_contents!(ids)
|
||||
# ids.each_with_index do |id, position|
|
||||
# self.contents.find(BSON::ObjectId(id))._position_in_list = position
|
||||
# end
|
||||
# self.save
|
||||
# end
|
||||
#
|
||||
# def highlighted_field
|
||||
# self.entries_custom_fields.detect { |f| f._name == self.highlighted_field_name }
|
||||
# end
|
||||
#
|
||||
# def group_by_field
|
||||
# @group_by_field ||= self.entries_custom_fields.detect { |f| f._name == self.group_by_field_name }
|
||||
# end
|
||||
|
||||
protected
|
||||
|
||||
def order_by_attribute
|
||||
@ -155,7 +90,8 @@ module Locomotive
|
||||
|
||||
def set_default_values
|
||||
self.order_by ||= 'created_at'
|
||||
field = self.entries_custom_fields.find(self.label_field_id) rescue self.entries_custom_fields.first
|
||||
self.label_field_id = self.entries_custom_fields.first._id if self.label_field_id.blank?
|
||||
field = self.entries_custom_fields.find(self.label_field_id)
|
||||
self.label_field_name = field.name
|
||||
end
|
||||
|
||||
@ -177,3 +113,64 @@ module Locomotive
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
# def list_or_group_contents
|
||||
# if self.groupable?
|
||||
# groups = self.contents.klass.send(:"group_by_#{self.group_by_field._alias}", :ordered_contents)
|
||||
#
|
||||
# # look for items with no category or unknown ones
|
||||
# items_without_category = self.contents.find_all { |c| !self.group_by_field.category_ids.include?(c.send(self.group_by_field_name)) }
|
||||
# if not items_without_category.empty?
|
||||
# groups << { :name => nil, :items => items_without_category }
|
||||
# else
|
||||
# groups
|
||||
# end
|
||||
# else
|
||||
# self.ordered_contents
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# def latest_updated_contents
|
||||
# self.contents.latest_updated.reject { |c| !c.persisted? }
|
||||
# end
|
||||
#
|
||||
# def ordered_contents(conditions = {})
|
||||
# column = self.order_by.to_sym
|
||||
#
|
||||
# list = (if conditions.nil? || conditions.empty?
|
||||
# self.contents
|
||||
# else
|
||||
# conditions_with_names = {}
|
||||
#
|
||||
# conditions.each do |key, value|
|
||||
# # convert alias (key) to name
|
||||
# field = self.entries_custom_fields.detect { |f| f._alias == key }
|
||||
#
|
||||
# case field.kind.to_sym
|
||||
# when :category
|
||||
# if (category_item = field.category_items.where(:name => value).first).present?
|
||||
# conditions_with_names[field._name.to_sym] = category_item._id
|
||||
# end
|
||||
# else
|
||||
# conditions_with_names[field._name.to_sym] = value
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# self.contents.where(conditions_with_names)
|
||||
# end).sort { |a, b| (a.send(column) && b.send(column)) ? (a.send(column) || 0) <=> (b.send(column) || 0) : 0 }
|
||||
#
|
||||
# return list if self.order_manually?
|
||||
#
|
||||
# self.asc_order? ? list : list.reverse
|
||||
# end
|
||||
#
|
||||
# def sort_contents!(ids)
|
||||
# ids.each_with_index do |id, position|
|
||||
# self.contents.find(BSON::ObjectId(id))._position_in_list = position
|
||||
# end
|
||||
# self.save
|
||||
# end
|
||||
#
|
||||
# def group_by_field
|
||||
# @group_by_field ||= self.entries_custom_fields.detect { |f| f._name == self.group_by_field_name }
|
||||
# end
|
@ -1,7 +1,7 @@
|
||||
class Locomotive::BasePresenter
|
||||
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
extend ActionView::Helpers::SanitizeHelper::ClassMethods
|
||||
extend ActionView::Helpers::SanitizeHelper::ClassMethods
|
||||
include ActionView::Helpers::TextHelper
|
||||
include ActionView::Helpers::NumberHelper
|
||||
|
||||
@ -20,8 +20,6 @@ class Locomotive::BasePresenter
|
||||
|
||||
def id
|
||||
self.source.persisted? || self.source.embedded? ? self.source._id.to_s : nil
|
||||
# self.persisted? ? self.source._id.to_s : nil
|
||||
# self.source._id.to_s
|
||||
end
|
||||
|
||||
def ability?
|
||||
@ -35,8 +33,8 @@ class Locomotive::BasePresenter
|
||||
def as_json(methods = nil)
|
||||
methods ||= self.included_methods
|
||||
{}.tap do |hash|
|
||||
methods.map(&:to_sym).each do |meth|
|
||||
hash[meth] = self.send(meth) rescue nil
|
||||
methods.each do |meth|
|
||||
hash[meth] = self.send(meth.to_sym) rescue nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -3,20 +3,33 @@ module Locomotive
|
||||
|
||||
delegate :_slug, :_position, :seo_title, :meta_keywords, :meta_description, :to => :source
|
||||
|
||||
# Returns the value of a field in the context of the current entry.
|
||||
#
|
||||
# @params [ CustomFields::Field ] field The field
|
||||
#
|
||||
# @returns [ Object ] The value of the field for the entry
|
||||
#
|
||||
def value_for(field)
|
||||
getter = [*self.getters_for(field.name, field.type)].first.to_sym
|
||||
self.source.send(getter)
|
||||
end
|
||||
|
||||
# Returns the list of getters for an entry
|
||||
#
|
||||
# @returns [ List ] a list of method names (string)
|
||||
#
|
||||
def custom_fields_methods
|
||||
source.custom_fields_recipe['rules'].map do |rule|
|
||||
case rule['type']
|
||||
when 'select' then [rule['name'], "#{rule['name']}_id"]
|
||||
when 'date' then "formatted_#{rule['name']}"
|
||||
when 'file' then "#{rule['name']}_url"
|
||||
else
|
||||
rule['name']
|
||||
end
|
||||
self.source.custom_fields_recipe['rules'].map do |rule|
|
||||
self.getters_for rule['name'], rule['type']
|
||||
end.flatten
|
||||
end
|
||||
|
||||
# Lists of all the attributes editable by a html form
|
||||
#
|
||||
# @returns [ List ] a list of attributes (string)
|
||||
#
|
||||
def safe_attributes
|
||||
source.custom_fields_recipe['rules'].map do |rule|
|
||||
self.source.custom_fields_recipe['rules'].map do |rule|
|
||||
case rule['type']
|
||||
when 'select' then "#{rule['name']}_id"
|
||||
when 'date' then "formatted_#{rule['name']}"
|
||||
@ -27,6 +40,10 @@ module Locomotive
|
||||
end.flatten + %w(_slug seo_title meta_keywords meta_description)
|
||||
end
|
||||
|
||||
def errors
|
||||
self.source.errors.to_hash.stringify_keys
|
||||
end
|
||||
|
||||
def content_type_slug
|
||||
self.source.content_type.slug
|
||||
end
|
||||
@ -36,7 +53,9 @@ module Locomotive
|
||||
end
|
||||
|
||||
def included_methods
|
||||
super + self.custom_fields_methods + %w(_slug _position content_type_slug _file_fields safe_attributes persisted)
|
||||
default_list = %w(_slug _position content_type_slug _file_fields safe_attributes)
|
||||
default_list << 'errors' if !!self.options[:include_errors]
|
||||
super + self.custom_fields_methods + default_list
|
||||
end
|
||||
|
||||
def method_missing(meth, *arguments, &block)
|
||||
@ -47,5 +66,24 @@ module Locomotive
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Gets the names of the getter methods for a field.
|
||||
# The names depend on the field type.
|
||||
#
|
||||
# @params [ String ] name Name of the field
|
||||
# @params [ String ] type Type of the field
|
||||
#
|
||||
# @returns [ Object ] A string or an array of names
|
||||
def getters_for(name, type)
|
||||
case type
|
||||
when 'select' then [name, "#{name}_id"]
|
||||
when 'date' then "formatted_#{name}"
|
||||
when 'file' then "#{name}_url"
|
||||
else
|
||||
name
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -33,6 +33,6 @@
|
||||
|
||||
= f.input :order_direction, :as => :select, :collection => options_for_order_direction, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if @content_type.order_manually?}" }
|
||||
|
||||
= f.input :public_form_enabled, :as => :'Locomotive::Toggle'
|
||||
= f.input :public_submission_enabled, :as => :'Locomotive::Toggle'
|
||||
|
||||
= f.input :public_form_accounts, :as => :select, :collection => options_for_account, :include_blank => false, :multiple => true, :wrapper_html => { :class => 'multiple', :style => (@content_type.public_form_enabled? ? '' : 'display: none') }
|
||||
= f.input :public_submission_accounts, :as => :select, :collection => options_for_account, :include_blank => false, :multiple => true, :wrapper_html => { :class => 'multiple', :style => (@content_type.public_submission_enabled? ? '' : 'display: none') }
|
||||
|
@ -7,8 +7,8 @@
|
||||
= render 'locomotive/shared/actions/contents'
|
||||
|
||||
- content_for :buttons do
|
||||
= local_action_button :show_items, content_entries_url(@content_type.slug_was), :class => 'show'
|
||||
= local_action_button :new_item, new_content_entry_url(@content_type.slug_was), :class => 'new'
|
||||
= local_action_button :show_entries, content_entries_url(@content_type.slug_was), :class => 'show'
|
||||
= local_action_button :new_entry, new_content_entry_url(@content_type.slug_was), :class => 'new'
|
||||
|
||||
%p!= t('.help')
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
- highlighted_field_name = parent.highlighted_field_name rescue ''
|
||||
|
||||
= form.inputs :name => title || :attributes do
|
||||
- form.object.custom_fields.each do |field|
|
||||
- highlighted = highlighted_field_name == field._name
|
||||
- required = highlighted || field.required
|
||||
|
||||
= render "/admin/custom_fields/types/#{field.kind}", :form => form, :parent => parent, :field => field, :required => required, :highlighted => highlighted
|
||||
|
||||
= render '/admin/custom_fields/category_tmpl'
|
@ -42,7 +42,7 @@
|
||||
|
||||
= g.input :select_options, :as => :'Locomotive::Empty', :wrapper_html => { :class => 'extra select-options', :style => 'display: none' }
|
||||
|
||||
= g.input :text_formatting, :as => :select, :collection => options_for_text_formatting, :include_blank => false, :wrapper_html => { :class => 'extra text-formatting', :style => 'display: none' }
|
||||
= g.input :text_formatting, :as => :select, :collection => options_for_text_formatting, :include_blank => false, :wrapper_html => { :class => 'extra text-formatting' }, :input_html => { :class => 'text_formatting' }
|
||||
|
||||
%span.actions
|
||||
= link_to 'toggle', '#', :class => 'toggle'
|
||||
|
@ -1 +1,4 @@
|
||||
= f.input name, :label => field.label, :as => :'Locomotive::Toggle', :hint => field.hint
|
||||
= f.input name,
|
||||
:label => field.label,
|
||||
:hint => field.hint,
|
||||
:as => :'Locomotive::Toggle'
|
@ -1,4 +0,0 @@
|
||||
= form.custom_input field._alias.to_sym, :label => field.label, :hint => field.hint, :css => 'toggle', :required => required do
|
||||
= form.select field._name.to_sym, field.ordered_category_items.collect { |item| [item.name, item.id] }
|
||||
%button.button.light.edit-categories-link{ :type => 'button', :'data-url' => edit_admin_custom_field_path(parent.class.model_name.underscore, parent.slug, field) }
|
||||
%span!= t('.edit_categories')
|
@ -1 +1,5 @@
|
||||
= f.input :"formatted_#{name}", :label => field.label, :hint => field.hint, :input_html => { :maxlength => 10 }, :wrapper_html => { :class => 'date' }
|
||||
= f.input :"formatted_#{name}",
|
||||
:label => field.label,
|
||||
:hint => field.hint,
|
||||
:wrapper_html => { :class => 'date' },
|
||||
:input_html => { :maxlength => 10 }
|
||||
|
@ -1 +1,4 @@
|
||||
= f.input name, :label => field.label, :hint => field.hint, :as => :'Locomotive::File'
|
||||
= f.input name,
|
||||
:label => field.label,
|
||||
:hint => field.hint,
|
||||
:as => :'Locomotive::File'
|
@ -1 +1,5 @@
|
||||
= f.input :"#{name}_id", :as => 'select', :collection => field.ordered_select_options.map { |option| [option.name, option.id] }, :label => field.label, :hint => field.hint
|
||||
= f.input :"#{name}_id",
|
||||
:label => field.label,
|
||||
:hint => field.hint,
|
||||
:as => 'select',
|
||||
:collection => field.ordered_select_options.map { |option| [option.name, option.id] }
|
@ -1 +1,4 @@
|
||||
= f.input name, :label => field.label, :hint => field.hint, :wrapper_html => { :class => "#{'highlighted' if highlighted}" }
|
||||
= f.input name,
|
||||
:label => field.label,
|
||||
:hint => field.hint,
|
||||
:wrapper_html => { :class => "#{'highlighted' if highlighted}" }
|
@ -1 +1,5 @@
|
||||
= f.input field.name.to_sym, :label => field.label, :hint => field.hint, :as => :'Locomotive::Rte', :input_html => { :class => field.text_formatting }
|
||||
= f.input field.name.to_sym,
|
||||
:label => field.label,
|
||||
:hint => field.hint,
|
||||
:as => field.text_formatting == 'html' ? :'Locomotive::Rte' : 'text',
|
||||
:input_html => { :class => field.text_formatting }
|
@ -3,19 +3,20 @@
|
||||
%hr
|
||||
|
||||
%p
|
||||
%b= t('.type', :type => @content_entry.content_type.name, :locale => @account.locale)
|
||||
%b= t('.type', :type => @type.name, :locale => @account.locale)
|
||||
%br
|
||||
%i= @content_entry.content_type.description
|
||||
%i= @type.description
|
||||
|
||||
%hr
|
||||
|
||||
%ul
|
||||
- @content_entry.custom_fields.each do |field|
|
||||
- @type.entries_custom_fields.each do |field|
|
||||
- value = @entry.value_for(field)
|
||||
%li
|
||||
%strong= field.label
|
||||
-
|
||||
%i
|
||||
- if field.file?
|
||||
= link_to File.basename(@content_entry.send(field.name).url), @content_entry.send(field.name).url
|
||||
- if field.type == 'file'
|
||||
= link_to File.basename(value), value
|
||||
- else
|
||||
= @content_entry.send(field.name)
|
||||
= value
|
||||
|
@ -222,14 +222,15 @@ en:
|
||||
content_types:
|
||||
index:
|
||||
new: new model
|
||||
edit: edit model
|
||||
new:
|
||||
title: New model
|
||||
help: "Create your own data model (Projects, People, ...etc). Your model should have one field at least. The items created from this content type would have their first field mandatory."
|
||||
edit:
|
||||
title: Editing model
|
||||
help: "Your model should have one field at least. The items created from this content type would have their first field mandatory."
|
||||
show_items: show items
|
||||
new_item: new item
|
||||
show_entries: show entries
|
||||
new_entry: new entry
|
||||
form:
|
||||
order_by:
|
||||
created_at: 'By creation date'
|
||||
|
@ -41,7 +41,8 @@ en:
|
||||
default_site_template: "Use the default site template. Click <a href='#'>here</a> to upload a site template as a zip file instead."
|
||||
content_type:
|
||||
raw_item_template: Item template
|
||||
public_form_accounts: Notified Accounts
|
||||
public_submission_enabled: Public submission
|
||||
public_submission_accounts: Notified Accounts
|
||||
"custom_fields/field":
|
||||
select_options: "Options"
|
||||
content_entry:
|
||||
@ -95,8 +96,8 @@ en:
|
||||
name: "We suggest you to type the plural form of the model. Ex: Projects, Recipes, Posts, Articles, ...etc"
|
||||
slug: "It will be used as the name of the collection in the liquid templates. Ex: <span class='code'>{{ contents.my_projects }}</span>"
|
||||
raw_item_template: "You can customize the text displayed for each item in the list. Simply use Liquid. Ex: <span class='code'>{{ entry.name }})</span>"
|
||||
public_form_enabled: "It is used to let people from outside to create new instances (example: messages in a contact form)"
|
||||
public_form_accounts: "A notification email will be sent to each of the accounts listed above when a new instance is created"
|
||||
public_submission_enabled: "It is used to let people from outside to create new entries (example: messages in a contact form)"
|
||||
public_submission_accounts: "If the public submission option is enabled and for each entry created, sends a notification email tothe accounts listed above."
|
||||
"custom_fields/field":
|
||||
name: "Name of the property for liquid templates. Ex: <span class='code'>{{ your_object.<name_of_your_field> }}</span>"
|
||||
hint: "Text displayed in the model form just below the field"
|
||||
|
@ -41,8 +41,6 @@ Locomotive::Engine.routes.draw do
|
||||
put :sort, :on => :collection
|
||||
end
|
||||
|
||||
resources :api_contents, :path => 'api/:slug/contents', :controller => 'api_contents', :only => [:create]
|
||||
|
||||
resources :custom_fields, :path => 'custom/:parent/:slug/fields'
|
||||
|
||||
resources :cross_domain_sessions, :only => [:new, :create]
|
||||
@ -58,13 +56,16 @@ end
|
||||
|
||||
Rails.application.routes.draw do
|
||||
# sitemap
|
||||
match '/sitemap.xml' => 'locomotive/sitemaps#show', :format => 'xml'
|
||||
match '/sitemap.xml' => 'locomotive/public/sitemaps#show', :format => 'xml'
|
||||
|
||||
# robots.txt
|
||||
match '/robots.txt' => 'locomotive/robots#show', :format => 'txt'
|
||||
match '/robots.txt' => 'locomotive/public/robots#show', :format => 'txt'
|
||||
|
||||
# public content entry submissions
|
||||
resources :locomotive_entry_submissions, :controller => 'locomotive/public/content_entries', :path => 'entry_submissions/:slug'
|
||||
|
||||
# magic urls
|
||||
match '/' => 'locomotive/rendering#show'
|
||||
match '*path/edit' => 'locomotive/rendering#edit'
|
||||
match '*path' => 'locomotive/rendering#show'
|
||||
match '/' => 'locomotive/public/rendering#show'
|
||||
match '*path/edit' => 'locomotive/public/rendering#edit'
|
||||
match '*path' => 'locomotive/public/rendering#show'
|
||||
end
|
10
doc/TODO
10
doc/TODO
@ -8,9 +8,9 @@ x bugs:
|
||||
x undefined method `_selector' for #<Locomotive::Page:0x00000107434768>
|
||||
x editable_elements => view + handlebar template
|
||||
x editable_short_text => tinymce
|
||||
- editable_file =>
|
||||
x editable_file =>
|
||||
x backbone / handlebar
|
||||
- new formtastic inputs
|
||||
x new formtastic inputs
|
||||
x menu / submenu in full css3 (no images)
|
||||
x fix css in firefox
|
||||
x update page in ajax
|
||||
@ -61,7 +61,11 @@ x edit my site
|
||||
x file
|
||||
x edit
|
||||
x destroy
|
||||
- public_form (previously api something)
|
||||
x public_form (previously api something)
|
||||
x bug text formatting
|
||||
- use list_or_group_entries instead of ordered_entries
|
||||
- bug ui with contents popup
|
||||
- custom_fields: use the appropriate icon to drag select options
|
||||
|
||||
- disallow to click twice on the submit form button (spinner ?)
|
||||
- message to notify people if their browser is too old
|
||||
|
@ -8,10 +8,13 @@
|
||||
- content_types:
|
||||
- category => select
|
||||
- highlighted_field_name => highlighted_field_id (label_field_id)
|
||||
- api_enabled => public_form_enabled
|
||||
- api_accounts => public_form_accounts
|
||||
- api_enabled => public_submission_enabled
|
||||
- api_accounts => public_submission_accounts
|
||||
- contents (content_entries now)
|
||||
- _position_in_list => _position
|
||||
- api_contents:
|
||||
- url => entry_submissions
|
||||
- params[:content] => params[:entries]
|
||||
|
||||
|
||||
collection, selector = Locomotive::ContentType.collection, Locomotive::ContentType.criteria.selector
|
||||
|
@ -6,7 +6,6 @@ require 'locomotive/version'
|
||||
require 'locomotive/core_ext'
|
||||
require 'locomotive/configuration'
|
||||
require 'locomotive/logger'
|
||||
|
||||
require 'locomotive/formtastic'
|
||||
require 'locomotive/dragonfly'
|
||||
require 'locomotive/kaminari'
|
||||
@ -15,7 +14,7 @@ require 'locomotive/mongoid'
|
||||
require 'locomotive/carrierwave'
|
||||
require 'locomotive/custom_fields'
|
||||
require 'locomotive/httparty'
|
||||
require 'locomotive/responder'
|
||||
require 'locomotive/action_controller'
|
||||
require 'locomotive/routing'
|
||||
require 'locomotive/regexps'
|
||||
require 'locomotive/render'
|
||||
@ -76,11 +75,11 @@ module Locomotive
|
||||
self.add_middlewares
|
||||
|
||||
# Load all the dynamic classes (custom fields)
|
||||
# begin
|
||||
# ContentType.all.collect(&:fetch_content_klass)
|
||||
# rescue ::Mongoid::Errors::InvalidDatabase => e
|
||||
# # let assume it's because of the first install (meaning no config.yml file)
|
||||
# end
|
||||
begin
|
||||
ContentType.all.collect { |content_type| content_type.klass_with_custom_fields(:entries) }
|
||||
rescue ::Mongoid::Errors::InvalidDatabase => e
|
||||
# let assume it's because of the first install (meaning no config.yml file)
|
||||
end
|
||||
end
|
||||
|
||||
def self.add_middlewares
|
||||
|
3
lib/locomotive/action_controller.rb
Normal file
3
lib/locomotive/action_controller.rb
Normal file
@ -0,0 +1,3 @@
|
||||
require 'locomotive/action_controller/helpers'
|
||||
require 'locomotive/action_controller/responder'
|
||||
require 'locomotive/action_controller/public_responder'
|
66
lib/locomotive/action_controller/helpers.rb
Normal file
66
lib/locomotive/action_controller/helpers.rb
Normal file
@ -0,0 +1,66 @@
|
||||
module Locomotive
|
||||
module ActionController
|
||||
module Helpers
|
||||
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
helper_method :current_site_public_url, :switch_to_site_url, :public_page_url
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
|
||||
def set_locale
|
||||
I18n.locale = current_locomotive_account.locale rescue Locomotive.config.default_locale
|
||||
end
|
||||
|
||||
def sections(key = nil)
|
||||
if !key.nil? && key.to_sym == :sub
|
||||
@locomotive_sections[:sub] || self.controller_name.dasherize
|
||||
else
|
||||
@locomotive_sections[:main]
|
||||
end
|
||||
end
|
||||
|
||||
# ___ site/page urls builder ___
|
||||
|
||||
def current_site_public_url
|
||||
request.protocol + request.host_with_port
|
||||
end
|
||||
|
||||
def switch_to_site_url(site, options = {})
|
||||
options = { :fullpath => true, :protocol => true }.merge(options)
|
||||
|
||||
url = "#{site.subdomain}.#{Locomotive.config.domain}"
|
||||
url += ":#{request.port}" if request.port != 80
|
||||
|
||||
url = File.join(url, request.fullpath) if options[:fullpath]
|
||||
url = "http://#{url}" if options[:protocol]
|
||||
url
|
||||
end
|
||||
|
||||
def public_page_url(page, options = {})
|
||||
if content = options.delete(:content)
|
||||
File.join(current_site_public_url, page.fullpath.gsub('content_type_template', ''), content._slug)
|
||||
else
|
||||
File.join(current_site_public_url, page.fullpath)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
|
||||
def sections(main, sub = nil)
|
||||
before_filter do |c|
|
||||
sub = sub.call(c) if sub.respond_to?(:call)
|
||||
sections = { :main => main, :sub => sub }
|
||||
c.instance_variable_set(:@locomotive_sections, sections)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
17
lib/locomotive/action_controller/public_responder.rb
Normal file
17
lib/locomotive/action_controller/public_responder.rb
Normal file
@ -0,0 +1,17 @@
|
||||
module Locomotive
|
||||
module ActionController
|
||||
class PublicResponder < ::ActionController::Responder
|
||||
|
||||
def navigation_behavior(error)
|
||||
if get?
|
||||
raise error
|
||||
elsif has_errors? && default_action
|
||||
redirect_to navigation_location
|
||||
else
|
||||
redirect_to navigation_location
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
63
lib/locomotive/action_controller/responder.rb
Normal file
63
lib/locomotive/action_controller/responder.rb
Normal file
@ -0,0 +1,63 @@
|
||||
module Locomotive
|
||||
module ActionController
|
||||
class Responder < ::ActionController::Responder
|
||||
|
||||
include ::Responders::FlashResponder
|
||||
|
||||
# by default flash_now messages if the resource has errors
|
||||
def set_flash_now?
|
||||
super || has_errors?
|
||||
end
|
||||
|
||||
def to_json
|
||||
if get?
|
||||
display resource
|
||||
elsif has_errors?
|
||||
with_flash_message(:alert) do
|
||||
display resource.errors, :status => :unprocessable_entity
|
||||
end
|
||||
elsif post?
|
||||
in_header = controller.request.headers['X-Flash'] == 'true'
|
||||
with_flash_message(:notice, in_header) do
|
||||
display resource, :location => api_location
|
||||
end
|
||||
elsif put?
|
||||
with_flash_message do |message|
|
||||
display resource, :status => :ok, :location => api_location
|
||||
end
|
||||
elsif delete?
|
||||
with_flash_message do |message|
|
||||
display resource, :status => :ok, :location => api_location
|
||||
end
|
||||
elsif has_empty_resource_definition?
|
||||
display empty_resource, :status => :ok
|
||||
else
|
||||
with_flash_message do
|
||||
head :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def with_flash_message(type = :notice, in_header = true)
|
||||
if in_header
|
||||
set_flash_message!
|
||||
message = controller.flash[type]
|
||||
|
||||
controller.headers['X-Message'] = message
|
||||
controller.headers['X-Message-Type'] = type
|
||||
|
||||
yield if block_given?
|
||||
|
||||
controller.flash.discard # reset flash messages !
|
||||
else
|
||||
set_flash_message!
|
||||
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
@ -24,7 +24,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
initializer 'locomotive.action_controller' do |app|
|
||||
ActionController::Base.wrap_parameters :format => [:json]
|
||||
::ActionController::Base.wrap_parameters :format => [:json]
|
||||
end
|
||||
|
||||
end
|
||||
|
79
lib/locomotive/liquid/drops/content_types.rb
Normal file
79
lib/locomotive/liquid/drops/content_types.rb
Normal file
@ -0,0 +1,79 @@
|
||||
module Locomotive
|
||||
module Liquid
|
||||
module Drops
|
||||
class ContentTypes < ::Liquid::Drop
|
||||
|
||||
def before_method(meth)
|
||||
type = @context.registers[:site].content_types.where(:slug => meth.to_s).first
|
||||
ProxyCollection.new(type)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ProxyCollection < ::Liquid::Drop
|
||||
|
||||
def initialize(content_type)
|
||||
@content_type = content_type
|
||||
@collection = nil
|
||||
end
|
||||
|
||||
def first
|
||||
self.collection.first
|
||||
end
|
||||
|
||||
def last
|
||||
self.collection.last
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
self.collection.each(&block)
|
||||
end
|
||||
|
||||
def each_with_index(&block)
|
||||
self.collection.each_with_index(&block)
|
||||
end
|
||||
|
||||
def count
|
||||
@count ||= self.collection.count
|
||||
end
|
||||
|
||||
alias :size :count
|
||||
alias :length :count
|
||||
|
||||
def empty?
|
||||
self.collection.empty?
|
||||
end
|
||||
|
||||
def any?
|
||||
self.collection.any?
|
||||
end
|
||||
|
||||
def public_submission_url
|
||||
@context.registers[:controller].main_app.locomotive_entry_submissions_url(@content_type.slug)
|
||||
end
|
||||
|
||||
def before_method(meth)
|
||||
klass = @content_type.entries.klass # delegate to the proxy class
|
||||
|
||||
if (meth.to_s =~ /^group_by_.+$/) == 0
|
||||
klass.send(meth, :ordered_entries)
|
||||
else
|
||||
Rails.logger.warn "[Liquid template] trying to call #{meth} on a content_type object"
|
||||
# klass.send(meth)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def paginate(options = {})
|
||||
@collection.page(options[:page]).per(options[:per_page])
|
||||
end
|
||||
|
||||
def collection
|
||||
@collection ||= @content_type.ordered_entries(@context['with_scope'])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
@ -1,79 +1,81 @@
|
||||
module Locomotive
|
||||
module Liquid
|
||||
module Drops
|
||||
class Contents < ::Liquid::Drop
|
||||
# DEPRECATED
|
||||
|
||||
# TODO: refactoring
|
||||
|
||||
def before_method(meth)
|
||||
type = @context.registers[:site].content_types.where(:slug => meth.to_s).first
|
||||
ProxyCollection.new(type)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class ProxyCollection < ::Liquid::Drop
|
||||
|
||||
def initialize(content_type)
|
||||
@content_type = content_type
|
||||
@collection = nil
|
||||
end
|
||||
|
||||
def first
|
||||
self.collection.first
|
||||
end
|
||||
|
||||
def last
|
||||
self.collection.last
|
||||
end
|
||||
|
||||
def each(&block)
|
||||
self.collection.each(&block)
|
||||
end
|
||||
|
||||
def each_with_index(&block)
|
||||
self.collection.each_with_index(&block)
|
||||
end
|
||||
|
||||
def size
|
||||
self.collection.size
|
||||
end
|
||||
|
||||
alias :length :size
|
||||
|
||||
def empty?
|
||||
self.collection.empty?
|
||||
end
|
||||
|
||||
def any?
|
||||
self.collection.any?
|
||||
end
|
||||
|
||||
def api
|
||||
{ 'create' => @context.registers[:controller].send('api_contents_url', @content_type.slug) }
|
||||
end
|
||||
|
||||
def before_method(meth)
|
||||
klass = @content_type.entries.klass # delegate to the proxy class
|
||||
|
||||
if (meth.to_s =~ /^group_by_.+$/) == 0
|
||||
klass.send(meth, :ordered_contents)
|
||||
else
|
||||
klass.send(meth)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def paginate(options = {})
|
||||
@collection = Kaminari.paginate_array(self.collection).page(options[:page]).per(options[:per_page])
|
||||
end
|
||||
|
||||
def collection
|
||||
@collection ||= @content_type.ordered_contents(@context['with_scope'])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
# module Locomotive
|
||||
# module Liquid
|
||||
# module Drops
|
||||
# class Contents < ::Liquid::Drop
|
||||
#
|
||||
# # TODO: refactoring
|
||||
#
|
||||
# def before_method(meth)
|
||||
# type = @context.registers[:site].content_types.where(:slug => meth.to_s).first
|
||||
# ProxyCollection.new(type)
|
||||
# end
|
||||
#
|
||||
# end
|
||||
#
|
||||
# class ProxyCollection < ::Liquid::Drop
|
||||
#
|
||||
# def initialize(content_type)
|
||||
# @content_type = content_type
|
||||
# @collection = nil
|
||||
# end
|
||||
#
|
||||
# def first
|
||||
# self.collection.first
|
||||
# end
|
||||
#
|
||||
# def last
|
||||
# self.collection.last
|
||||
# end
|
||||
#
|
||||
# def each(&block)
|
||||
# self.collection.each(&block)
|
||||
# end
|
||||
#
|
||||
# def each_with_index(&block)
|
||||
# self.collection.each_with_index(&block)
|
||||
# end
|
||||
#
|
||||
# def size
|
||||
# self.collection.size
|
||||
# end
|
||||
#
|
||||
# alias :length :size
|
||||
#
|
||||
# def empty?
|
||||
# self.collection.empty?
|
||||
# end
|
||||
#
|
||||
# def any?
|
||||
# self.collection.any?
|
||||
# end
|
||||
#
|
||||
# def api
|
||||
# { 'create' => @context.registers[:controller].send('api_contents_url', @content_type.slug) }
|
||||
# end
|
||||
#
|
||||
# def before_method(meth)
|
||||
# klass = @content_type.entries.klass # delegate to the proxy class
|
||||
#
|
||||
# if (meth.to_s =~ /^group_by_.+$/) == 0
|
||||
# klass.send(meth, :ordered_contents)
|
||||
# else
|
||||
# klass.send(meth)
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# protected
|
||||
#
|
||||
# def paginate(options = {})
|
||||
# @collection = Kaminari.paginate_array(self.collection).page(options[:page]).per(options[:per_page])
|
||||
# end
|
||||
#
|
||||
# def collection
|
||||
# @collection ||= @content_type.ordered_contents(@context['with_scope'])
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
@ -61,7 +61,8 @@ module Locomotive
|
||||
assigns = {
|
||||
'site' => current_site,
|
||||
'page' => @page,
|
||||
'contents' => Locomotive::Liquid::Drops::Contents.new,
|
||||
'models' => Locomotive::Liquid::Drops::ContentTypes.new,
|
||||
'contents' => Locomotive::Liquid::Drops::ContentTypes.new, # DEPRECATED
|
||||
'current_page' => self.params[:page],
|
||||
'params' => self.params,
|
||||
'path' => request.path,
|
||||
@ -72,10 +73,12 @@ module Locomotive
|
||||
|
||||
assigns.merge!(Locomotive.config.context_assign_extensions)
|
||||
|
||||
assigns.merge!(flash.to_hash.stringify_keys) # data from api
|
||||
Rails.logger.debug flash.to_hash.stringify_keys.inspect
|
||||
|
||||
assigns.merge!(flash.to_hash.stringify_keys) # data from public submissions
|
||||
|
||||
if @page.templatized? # add instance from content type
|
||||
assigns['content_entry'] = @content_entry
|
||||
assigns['entry'] = @content_entry
|
||||
assigns[@page.content_type.slug.singularize] = @content_entry # just here to help to write readable liquid code
|
||||
end
|
||||
|
||||
@ -111,7 +114,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
def editing_page?
|
||||
@editing
|
||||
!!@editing
|
||||
end
|
||||
|
||||
def page_status
|
||||
|
@ -1,61 +0,0 @@
|
||||
module Locomotive
|
||||
class Responder < ::ActionController::Responder
|
||||
|
||||
include ::Responders::FlashResponder
|
||||
|
||||
# by default flash_now messages if the resource has errors
|
||||
def set_flash_now?
|
||||
super || has_errors?
|
||||
end
|
||||
|
||||
def to_json
|
||||
if get?
|
||||
display resource
|
||||
elsif has_errors?
|
||||
with_flash_message(:alert) do
|
||||
display resource.errors, :status => :unprocessable_entity
|
||||
end
|
||||
elsif post?
|
||||
in_header = controller.request.headers['X-Flash'] == 'true'
|
||||
with_flash_message(:notice, in_header) do
|
||||
display resource, :location => api_location
|
||||
end
|
||||
elsif put?
|
||||
with_flash_message do |message|
|
||||
display resource, :status => :ok, :location => api_location
|
||||
end
|
||||
elsif delete?
|
||||
with_flash_message do |message|
|
||||
display resource, :status => :ok, :location => api_location
|
||||
end
|
||||
elsif has_empty_resource_definition?
|
||||
display empty_resource, :status => :ok
|
||||
else
|
||||
with_flash_message do
|
||||
head :ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def with_flash_message(type = :notice, in_header = true)
|
||||
if in_header
|
||||
set_flash_message!
|
||||
message = controller.flash[type]
|
||||
|
||||
controller.headers['X-Message'] = message
|
||||
controller.headers['X-Message-Type'] = type
|
||||
|
||||
yield if block_given?
|
||||
|
||||
controller.flash.discard # reset flash messages !
|
||||
else
|
||||
set_flash_message!
|
||||
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
||||
s.required_rubygems_version = '>= 1.3.6'
|
||||
s.rubyforge_project = 'nowarning'
|
||||
|
||||
s.add_dependency 'rails', '~> 3.0.10'
|
||||
s.add_dependency 'rails', '~> 3.1.3'
|
||||
s.add_dependency 'warden'
|
||||
s.add_dependency 'devise', '1.3.4'
|
||||
s.add_dependency 'devise_bushido_authenticatable', '1.0.0.alpha10'
|
||||
|
Loading…
Reference in New Issue
Block a user