I'm not sure if this will work for everyone, but here's my solution to this issue.
Requirements: this will only work for posts that have the "post_of_posttype", "heirarchy_post" or "post_of_category_post_type" route formats.
The following code is extending the functionality of Camaleon's frontend controller method render_post by simply adding a redirect when the params don't match the @post.the_path. Seems to work for my purposes. Hopefully it will help someone else.
Create a new file in your config/initializers folder and place the following code:
# config/initializers/camaleon_custom_post.rb
CamaleonCms::FrontendController.class_eval do
# render a post
# post_or_slug_or_id: slug_post | id post | post object
# from_url: true/false => true (true, permit eval hooks "on_render_post")
def render_post(post_or_slug_or_id, from_url = false, status = nil)
if post_or_slug_or_id.is_a?(String) # slug
@post = current_site.the_posts.find_by_slug(post_or_slug_or_id)
elsif post_or_slug_or_id.is_a?(Integer) # id
@post = current_site.the_posts.where(id: post_or_slug_or_id).first
else # model
@post = post_or_slug_or_id
end
unless @post.present?
if params[:format] == 'html' || !params[:format].present?
page_not_found()
else
head 404
end
else
@post = @post.decorate
if ["post_of_posttype","hierarchy_post"].include? @post.the_post_type.contents_route_format
if params[:parent_title].nil? && params[:post_type_title].nil?
params_path = "/" + params[:slug]
elsif !params[:parent_title].nil?
params_path = "/" + params[:parent_title] + "/" + params[:slug]
elsif !params[:post_type_title].nil?
params_path = "/" + params[:post_type_title] + "/" + params[:slug]
end
unless (@post.the_path === params_path)
redirect_to @post.the_url, status: 301 and return
end
elsif @post.the_post_type.contents_route_format === "post_of_category_post_type"
if [params[:post_type_title],params[:label_cat],params[:category_id],params[:title]].all?
params_path = [params[:post_type_title],params[:label_cat],params[:category_id] + "-" + params[:title],params[:slug]].join("/")
params_path.prepend("/")
unless (@post.the_path === params_path)
redirect_to @post.the_url, status: 301 and return
end
else
redirect_to @post.the_url, status: 301 and return
end
end
@object = @post
@cama_visited_post = @post
@post_type = @post.the_post_type
@comments = @post.the_comments
@categories = @post.the_categories
@post.increment_visits!
# todo: can_visit? if not redirect home page
home_page = @_site_options[:home_page] rescue nil
if lookup_context.template_exists?("page_#{@post.id}")
r_file = "page_#{@post.id}"
elsif @post.get_template(@post_type).present? && lookup_context.template_exists?(@post.get_template(@post_type))
r_file = @post.get_template(@post_type)
elsif home_page.present? && @post.id.to_s == home_page
r_file = "index"
elsif lookup_context.template_exists?("post_types/#{@post_type.the_slug}/single")
r_file = "post_types/#{@post_type.the_slug}/single"
elsif lookup_context.template_exists?("#{@post_type.slug}")
r_file = "#{@post_type.slug}"
else
r_file = "single"
end
layout_ = nil
meta_layout = @post.get_layout(@post_type)
layout_ = meta_layout if meta_layout.present? && lookup_context.template_exists?("layouts/#{meta_layout}")
r = {post: @post, post_type: @post_type, layout: layout_, render: r_file}
hooks_run("on_render_post", r) if from_url
if status.present?
render r[:render], (!r[:layout].nil? ? {layout: r[:layout], status: status} : {status: status})
else
render r[:render], (!r[:layout].nil? ? {layout: r[:layout]} : {})
end
end
end
end
Seems kind of strange the mandatory redirect for non-accurate urls is not in the core camaleon application, but perhaps most people who use this cms are creating internally facing apps. Anyway, if that's not the case, I think this should be a priority fix.