now page can be redirected to another page

Oleg committed Oct 19, 2010
commit d62260b947aa23dbb7894ccacac62e15ad3bad8b
Showing 7 changed files with 37 additions and 3 deletions
app/controllers/cms_content_controller.rb +1 -0
@@ @@ -27,6 +27,7 @@ protected
def load_cms_page
@cms_page = @cms_site.cms_pages.find_by_full_path!("/#{params[:cms_path]}")
+ return redirect_to(@cms_page.target_page.full_path) if @cms_page.target_page
rescue ActiveRecord::RecordNotFound
if @cms_page = @cms_site.cms_pages.find_by_full_path('/404')
render_html(404)
app/models/cms_page.rb +14 -3
@@ @@ -8,6 +8,8 @@ class CmsPage < ActiveRecord::Base
# -- Relationships --------------------------------------------------------
belongs_to :cms_site
belongs_to :cms_layout
+ belongs_to :target_page,
+ :class_name => 'CmsPage'
has_many :cms_blocks,
:dependent => :destroy
accepts_nested_attributes_for :cms_blocks
@@ @@ -30,14 +32,15 @@ class CmsPage < ActiveRecord::Base
validates :full_path,
:presence => true,
:uniqueness => { :scope => :cms_site_id }
+ validate :validate_target_page
# -- Class Methods --------------------------------------------------------
# Tree-like structure for pages
- def self.options_for_select(cms_site, cms_page = nil, current_page = nil, depth = 0, spacer = '. . ')
- return [] if (current_page ||= cms_site.cms_pages.root) == cms_page || !current_page
+ def self.options_for_select(cms_site, cms_page = nil, current_page = nil, depth = 0, exclude_self = true, spacer = '. . ')
+ return [] if (current_page ||= cms_site.cms_pages.root) == cms_page && exclude_self || !current_page
out = [[ "#{spacer*depth}#{current_page.label}", current_page.id ]]
current_page.children.each do |child|
- out += options_for_select(cms_site, cms_page, child, depth + 1, spacer)
+ out += options_for_select(cms_site, cms_page, child, depth + 1, exclude_self, spacer)
end
return out.compact
end
@@ @@ -62,6 +65,14 @@ protected
self.full_path = self.parent ? "#{self.parent.full_path}/#{self.slug}".squeeze('/') : '/'
end
+ def validate_target_page
+ return unless self.target_page
+ p = self
+ while p.target_page do
+ return self.errors.add(:target_page_id, 'Invalid Redirect') if (p = p.target_page) == self
+ end
+ end
+
# Forcing re-saves for child pages so they can update full_paths
def sync_child_pages
children.each{ |p| p.save! } if full_path_changed?
app/views/cms_admin/pages/_form.html.erb +1 -0
@@ @@ -4,6 +4,7 @@
<%= form.text_field :slug, :id => 'slug' %>
<%= form.select :cms_layout_id, CmsLayout.options_for_select(@cms_site), {}, 'data-page-id' => @cms_page.id.to_i, :label => 'Layout' %>
<%= form.select :parent_id, CmsPage.options_for_select(@cms_site, @cms_page) %>
+ <%= form.select :target_page_id, CmsPage.options_for_select(@cms_site, @cms_page, nil, 0, false), :include_blank => true, :label => 'Redirect To Page' %>
</div>
<%= render :partial => 'form_blocks' %>
migrate/01_create_cms.rb b/db/migrate/01_create_cms.rb +1 -0
@@ @@ -28,6 +28,7 @@ class CreateCms < ActiveRecord::Migration
t.integer :cms_site_id
t.integer :cms_layout_id
t.integer :parent_id
+ t.integer :target_page_id
t.string :label
t.string :slug
t.string :full_path
test/fixtures/cms_pages.yml +2 -0
@@ @@ -1,6 +1,7 @@
default:
cms_site: default
parent:
+ target_page:
cms_layout: default
label: Default Page
slug:
@@ @@ -11,6 +12,7 @@ default:
child:
cms_site: default
parent: default
+ target_page:
cms_layout: default
label: Child Page
slug: 'child-page'
test/functional/cms_content_controller_test.rb +8 -0
@@ @@ -49,6 +49,14 @@ class CmsContentControllerTest < ActionController::TestCase
assert_match /custom 404 page content/, response.body
end
+ def test_render_page_with_redirect
+ cms_pages(:child).update_attribute(:target_page, cms_pages(:default))
+ assert_equal cms_pages(:default), cms_pages(:child).target_page
+ get :render_html, :cms_path => 'child-page'
+ assert_response :redirect
+ assert_redirected_to '/'
+ end
+
def test_render_css
get :render_css, :id => cms_layouts(:default)
assert_response :success
test/unit/cms_page_test.rb +10 -0
@@ @@ -26,6 +26,16 @@ class CmsPageTest < ActiveSupport::TestCase
assert_has_errors_on page, :parent_id
end
+ def test_validation_of_target_page
+ page = cms_pages(:child)
+ page.target_page = cms_pages(:default)
+ page.save!
+ assert_equal cms_pages(:default), page.target_page
+ page.target_page = page
+ assert page.invalid?
+ assert_has_errors_on page, :target_page_id
+ end
+
def test_initialization_of_full_path
page = CmsPage.new(new_params)
assert page.invalid?