Created
January 29, 2012 02:12
-
-
Save rossnelson/1696783 to your computer and use it in GitHub Desktop.
Locomotive's multi site magic
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Admin | |
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Locomotive | |
module Render | |
extend ActiveSupport::Concern | |
module InstanceMethods | |
protected | |
def render_locomotive_page | |
if request.fullpath =~ /^\/admin\// | |
render :template => '/admin/errors/404', :layout => '/admin/layouts/box', :status => :not_found | |
else | |
@page = locomotive_page | |
redirect_to(@page.redirect_url) and return if @page.present? && @page.redirect? | |
render_no_page_error and return if @page.nil? | |
output = @page.render(locomotive_context) | |
self.prepare_and_set_response(output) | |
end | |
end | |
def render_no_page_error | |
render :template => '/admin/errors/no_page', :layout => false | |
end | |
def locomotive_page | |
path = (params[:path] || request.fullpath).clone # TODO: params[:path] is more consistent | |
path = path.split('?').first # take everything before the query string or the lookup fails | |
path.gsub!(/\.[a-zA-Z][a-zA-Z0-9]{2,}$/, '') # remove the page extension | |
path.gsub!(/^\//, '') # remove the leading slash | |
path = 'index' if path.blank? | |
if path != 'index' | |
dirname = File.dirname(path).gsub(/^\.$/, '') # also look for templatized page path | |
path = [path, File.join(dirname, 'content_type_template').gsub(/^\//, '')] | |
end | |
if page = current_site.pages.any_in(:fullpath => [*path]).first | |
if not page.published? and current_admin.nil? | |
page = nil | |
else | |
if page.templatized? | |
@content_instance = page.content_type.contents.where(:_slug => File.basename(path.first)).first | |
if @content_instance.nil? || (!@content_instance.visible? && current_admin.nil?) # content instance not found or not visible | |
page = nil | |
end | |
end | |
end | |
end | |
page || not_found_page | |
end | |
def locomotive_context | |
assigns = { | |
'site' => current_site, | |
'page' => @page, | |
'asset_collections' => Locomotive::Liquid::Drops::AssetCollections.new, # depracated, will be removed shortly | |
'contents' => Locomotive::Liquid::Drops::Contents.new, | |
'current_page' => self.params[:page], | |
'params' => self.params, | |
'path' => request.path, | |
'url' => request.url, | |
'now' => Time.now.utc, | |
'today' => Date.today | |
} | |
assigns.merge!(Locomotive.config.context_assign_extensions) | |
assigns.merge!(flash.stringify_keys) # data from api | |
if @page.templatized? # add instance from content type | |
assigns['content_instance'] = @content_instance | |
assigns[@page.content_type.slug.singularize] = @content_instance # just here to help to write readable liquid code | |
end | |
registers = { | |
:controller => self, | |
:site => current_site, | |
:page => @page, | |
:inline_editor => self.editing_page?, | |
:current_admin => current_admin | |
} | |
::Liquid::Context.new({}, assigns, registers) | |
end | |
def prepare_and_set_response(output) | |
flash.discard | |
response.headers['Content-Type'] = 'text/html; charset=utf-8' | |
if @page.with_cache? | |
fresh_when :etag => @page, :last_modified => @page.updated_at.utc, :public => true | |
if @page.cache_strategy != 'simple' # varnish | |
response.cache_control[:max_age] = @page.cache_strategy | |
end | |
end | |
render :text => output, :layout => false, :status => page_status unless performed? | |
end | |
def not_found_page | |
current_site.pages.not_found.published.first | |
end | |
def editing_page? | |
@editing | |
end | |
def page_status | |
@page.not_found? ? :not_found : :ok | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Locomotive | |
module Routing | |
module SiteDispatcher | |
extend ActiveSupport::Concern | |
included do | |
if self.respond_to?(:before_filter) | |
before_filter :fetch_site | |
helper_method :current_site | |
end | |
end | |
module InstanceMethods | |
protected | |
def fetch_site | |
Locomotive.log "[fetch site] host = #{request.host} / #{request.env['HTTP_HOST']}" | |
if Locomotive.config.multi_sites? | |
@current_site ||= Site.match_domain(request.host).first | |
else | |
@current_site ||= Site.first | |
end | |
end | |
def current_site | |
@current_site || fetch_site | |
end | |
def require_site | |
return true if current_site | |
redirect_to admin_installation_url and return false if Account.count == 0 || Site.count == 0 | |
render_no_site_error and return false | |
end | |
def render_no_site_error | |
render :template => '/admin/errors/no_site', :layout => false, :status => :not_found | |
end | |
def validate_site_membership | |
return true if current_site.present? && current_site.accounts.include?(current_admin) | |
sign_out(current_admin) | |
flash[:alert] = I18n.t(:no_membership, :scope => [:devise, :failure, :admin]) | |
redirect_to new_admin_session_url and return false | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment