templatized pages can have now sub pages

This commit is contained in:
Didier Lafforgue 2012-03-26 16:31:28 +02:00
parent a8d57794de
commit ed15c0d6b5
6 changed files with 138 additions and 80 deletions

View File

@ -66,14 +66,14 @@ GEM
remote: http://rubygems.org/
specs:
RedCloth (4.2.9)
actionmailer (3.2.1)
actionpack (= 3.2.1)
actionmailer (3.2.2)
actionpack (= 3.2.2)
mail (~> 2.4.0)
actionmailer-with-request (0.3.0)
rails (>= 3)
actionpack (3.2.1)
activemodel (= 3.2.1)
activesupport (= 3.2.1)
actionpack (3.2.2)
activemodel (= 3.2.2)
activesupport (= 3.2.2)
builder (~> 3.0.0)
erubis (~> 2.7.0)
journey (~> 1.0.1)
@ -81,18 +81,18 @@ GEM
rack-cache (~> 1.1)
rack-test (~> 0.6.1)
sprockets (~> 2.1.2)
activemodel (3.2.1)
activesupport (= 3.2.1)
activemodel (3.2.2)
activesupport (= 3.2.2)
builder (~> 3.0.0)
activerecord (3.2.1)
activemodel (= 3.2.1)
activesupport (= 3.2.1)
arel (~> 3.0.0)
activerecord (3.2.2)
activemodel (= 3.2.2)
activesupport (= 3.2.2)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activeresource (3.2.1)
activemodel (= 3.2.1)
activesupport (= 3.2.1)
activesupport (3.2.1)
activeresource (3.2.2)
activemodel (= 3.2.2)
activesupport (= 3.2.2)
activesupport (3.2.2)
i18n (~> 0.6)
multi_json (~> 1.0)
addressable (2.2.7)
@ -115,7 +115,7 @@ GEM
carrierwave-mongoid (0.1.3)
carrierwave (>= 0.5.6)
mongoid (~> 2.1)
cells (3.8.2)
cells (3.8.3)
actionpack (~> 3.0)
railties (~> 3.0)
childprocess (0.3.1)
@ -140,7 +140,7 @@ GEM
capybara (>= 1.1.2)
cucumber (>= 1.1.8)
nokogiri (>= 1.5.0)
database_cleaner (0.7.1)
database_cleaner (0.7.2)
devise (1.5.3)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3)
@ -175,7 +175,7 @@ GEM
formtastic (2.0.2)
rails (~> 3.0)
fssm (0.2.8.1)
gherkin (2.9.0)
gherkin (2.9.1)
json (>= 1.4.6)
haml (3.1.4)
highline (1.6.11)
@ -193,8 +193,8 @@ GEM
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
railties (>= 3.0.0)
kgio (2.7.2)
launchy (2.0.5)
kgio (2.7.4)
launchy (2.1.0)
addressable (~> 2.2.6)
locomotive-aloha-rails (0.20.1.1)
actionpack (~> 3.2.1)
@ -203,16 +203,16 @@ GEM
locomotive-tinymce-rails (3.4.7.1)
actionpack (~> 3.2.1)
locomotive_liquid (2.2.2)
mail (2.4.1)
mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.17.2)
mime-types (1.18)
mimetype-fu (0.1.2)
mocha (0.9.12)
mongo (1.5.2)
bson (= 1.5.2)
mongoid (2.4.6)
mongoid (2.4.7)
activemodel (~> 3.1)
mongo (~> 1.3)
tzinfo (~> 0.3.22)
@ -221,34 +221,34 @@ GEM
net-scp (1.0.4)
net-ssh (>= 1.99.1)
net-ssh (2.3.0)
nokogiri (1.5.0)
orm_adapter (0.0.6)
nokogiri (1.5.2)
orm_adapter (0.0.7)
pickle (0.4.10)
cucumber (>= 0.8)
rake
polyglot (0.3.3)
rack (1.4.1)
rack-cache (1.1)
rack-cache (1.2)
rack (>= 0.4)
rack-ssl (1.3.2)
rack
rack-test (0.6.1)
rack (>= 1.0)
rails (3.2.1)
actionmailer (= 3.2.1)
actionpack (= 3.2.1)
activerecord (= 3.2.1)
activeresource (= 3.2.1)
activesupport (= 3.2.1)
rails (3.2.2)
actionmailer (= 3.2.2)
actionpack (= 3.2.2)
activerecord (= 3.2.2)
activeresource (= 3.2.2)
activesupport (= 3.2.2)
bundler (~> 1.0)
railties (= 3.2.1)
railties (= 3.2.2)
rails-backbone (0.6.1)
coffee-script (~> 2.2.0)
ejs (~> 1.0.0)
railties (>= 3.1.0)
railties (3.2.1)
actionpack (= 3.2.1)
activesupport (= 3.2.1)
railties (3.2.2)
actionpack (= 3.2.2)
activesupport (= 3.2.2)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
@ -281,14 +281,14 @@ GEM
sanitize (2.0.3)
nokogiri (>= 1.4.4, < 1.6)
sass (3.1.15)
sass-rails (3.2.4)
sass-rails (3.2.5)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
selenium-webdriver (2.19.0)
selenium-webdriver (2.20.0)
childprocess (>= 0.2.5)
ffi (~> 1.0.9)
multi_json (~> 1.0.4)
ffi (~> 1.0)
multi_json (~> 1.0)
rubyzip
shoulda-matchers (1.0.0)
sprockets (2.1.2)
@ -301,7 +301,7 @@ GEM
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.31)
tzinfo (0.3.32)
uglifier (1.2.3)
execjs (>= 0.3.0)
multi_json (>= 1.0.2)

View File

@ -3,10 +3,89 @@ module Locomotive
module Page
module Render
extend ActiveSupport::Concern
def render(context)
self.template.render(context)
end
module ClassMethods
# Given both a site and a path, this method tries
# to get the matching page.
# If the page is templatized, the related content entry is
# associated to the page (page.content_entry stores the entry).
# If no page is found, then it returns the 404 one instead.
#
# @param [ Site ] site The site where to find the page
# @param [ String ] path The fullpath got from the request
# @param [ Boolean ] logged_in True if someone is logged in Locomotive
#
# @return [ Page ] The page matching the criteria OR the 404 one if none
#
def fetch_page_from_path(site, path, logged_in)
page = nil
matching_paths = path == 'index' ? %w(index) : path_combinations(path)
site.pages.any_in(:fullpath => matching_paths).each do |_page|
if !_page.published? && !logged_in
next
else
if _page.templatized?
%r(^#{_page.fullpath.gsub('content_type_template', '([^\/]+)')}$) =~ path
permalink = $1
_page.content_entry = _page.fetch_target_entry(permalink)
if _page.content_entry.nil? || (!_page.content_entry.visible? && !logged_in) # content instance not found or not visible
next
end
end
end
page = _page
break
end
page || site.pages.not_found.published.first
end
# Calculate all the combinations possible based on the
# fact that one of the segment of the path could be
# a content type from a templatized page.
# We postulate that there is only one templatized page in a path
# (ie: no nested templatized pages)
#
# @param [ String ] path The path to the page
#
# @return [ Array ] An array of all the combinations
#
def path_combinations(path)
_path_combinations(path.split('/'))
end
#:nodoc:
def _path_combinations(segments, can_include_template = true)
return nil if segments.empty?
segment = segments.shift
(can_include_template ? [segment, 'content_type_template'] : [segment]).map do |_segment|
if (_combinations = _path_combinations(segments.clone, can_include_template && _segment != 'content_type_template'))
[*_combinations].map do |_combination|
File.join(_segment, _combination)
end
else
[_segment]
end
end.flatten
end
end
end
end
end

View File

@ -20,6 +20,9 @@ module Locomotive
## scopes ##
scope :templatized, :where => { :templatized => true }
## virtual attributes ##
attr_accessor :content_entry
end
# Returns the class specified by the target_klass_name property

View File

@ -38,6 +38,10 @@ module Locomotive
Page.quick_tree(self)
end
def fetch_page(path, logged_in)
Locomotive::Page.fetch_page_from_path self, path, logged_in
end
def accounts
Account.criteria.in(:_id => self.memberships.map(&:account_id))
end

View File

@ -26,28 +26,7 @@ module Locomotive
end
def locomotive_page
page = nil
path = self.locomotive_page_path
current_site.pages.any_in(:fullpath => [*path]).each do |_page|
if not _page.published? and current_locomotive_account.nil?
next
else
if _page.templatized?
@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
next
end
end
end
page = _page
break
end
page || not_found_page
current_site.fetch_page self.locomotive_page_path, current_locomotive_account.present?
end
def locomotive_page_path
@ -58,11 +37,6 @@ module Locomotive
path = 'index' if path.blank? || path == '_edit'
if path != 'index'
dirname = File.dirname(path).gsub(/^\.$/, '') # also look for templatized page path
path = [path, File.join(dirname, 'content_type_template').gsub(/^\//, '')]
end
path
end
@ -75,6 +49,7 @@ module Locomotive
'current_page' => self.params[:page],
'params' => self.params,
'path' => request.path,
'fullpath' => request.fullpath,
'url' => request.url,
'now' => Time.now.utc,
'today' => Date.today,
@ -88,8 +63,8 @@ module Locomotive
assigns.merge!(flash.to_hash.stringify_keys) # data from public submissions
if @page.templatized? # add instance from content type
assigns['entry'] = @content_entry
assigns[@page.target_entry_name] = @content_entry # just here to help to write readable liquid code
assigns['entry'] = @page.content_entry
assigns[@page.target_entry_name] = @page.content_entry # just here to help to write readable liquid code
end
registers = {
@ -120,10 +95,6 @@ module Locomotive
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

View File

@ -95,13 +95,13 @@ describe 'Locomotive rendering system' do
it 'should retrieve it based on the full path' do
@controller.request.fullpath = '/about_us/team.html'
@controller.current_site.pages.expects(:any_in).with({ :fullpath => %w{about_us/team about_us/content_type_template} }).returns([@page])
@controller.current_site.pages.expects(:any_in).with({ :fullpath => %w{about_us/team about_us/content_type_template content_type_template/team} }).returns([@page])
@controller.send(:locomotive_page).should_not be_nil
end
it 'does not include the query string' do
@controller.request.fullpath = '/about_us/team.html?some=params&we=use'
@controller.current_site.pages.expects(:any_in).with({ :fullpath => %w{about_us/team about_us/content_type_template} }).returns([@page])
@controller.current_site.pages.expects(:any_in).with({ :fullpath => %w{about_us/team about_us/content_type_template content_type_template/team} }).returns([@page])
@controller.send(:locomotive_page).should_not be_nil
end
@ -135,13 +135,15 @@ describe 'Locomotive rendering system' do
@content_entry = @content_type.entries.build(:_visible => true)
@page.templatized = true
@page.stubs(:fetch_target_entry).returns(@content_entry)
@page.stubs(:fullpath).returns('/projects/content_type_template')
@controller.request.fullpath = '/projects/edeneo.html'
@controller.current_site.pages.expects(:any_in).with({ :fullpath => %w{projects/edeneo projects/content_type_template} }).returns([@page])
@controller.current_site.pages.expects(:any_in).with({ :fullpath => %w{projects/edeneo projects/content_type_template content_type_template/edeneo} }).returns([@page])
end
it 'sets the content_entry variable' do
@controller.send(:locomotive_page).should_not be_nil
@controller.instance_variable_get(:@content_entry).should == @content_entry
page = @controller.send(:locomotive_page)
page.should_not be_nil
page.content_entry.should == @content_entry
end
it 'returns the 404 page if the instance does not exist' do
@ -149,7 +151,6 @@ describe 'Locomotive rendering system' do
(klass = Locomotive::Page).expects(:published).returns([true])
@controller.current_site.pages.expects(:not_found).returns(klass)
@controller.send(:locomotive_page).should be_true
@controller.instance_variable_get(:@content_entry).should be_nil
end
it 'returns the 404 page if the instance is not visible' do