-
Notifications
You must be signed in to change notification settings - Fork 260
Improve Content APIs
There are a number of features that could be added to portlets/CMS APIs to reduce the amount of custom code required to do interesting things. Here's a few
required current behavior
class SomeCustomPortlet < Cms::Portlet
def render
@page = @controller.instance_variable_get("@page")
end
end
- Create a project specific subdirectory i.e.
lib/project_name
- Create a module with a matching name:
# In lib/project_name/page_comment_extensions.rb
module ProjectName
module PageCommentExtensions
extend ActiveSupport::Concern
included do
scope :published, where(:published => true)
end
def some_method
# Do whatever
end
module ClassMethods
def columns_for_index
[{:label => "Path", :method => :path},
{:label => "Name", :method => :name}]
end
end
end
end
- Include the module so it will work in both development and production
# In config/application.rb
config.to_prepare do
BcmsPageComments::PageComment.send(:include, ProjectName::PageCommentsExtensions)
end
Updating the views that are stored in the database is a bit of duplication. First, you need to update the code view (i.e. app/views/cms/model_name/render.html.erb. Then you need to write some code to update the view, like so:
# In db/migrate/XYZ_my_update.rb
def change
update_portlet_template('My Custom Portlet') do |template|
template.gsub("<% form_tag", "<%= form_tag") # Rails 3 syntax change
end
end
def update_portlet_template(name)
portlet = Cms::Portlet.where(:name => name).first
if portlet
portlet.template = yield(portlet.template)
portlet.save!
puts "Updated #{portlet} template"
else
puts "Couldn't find a portlet named #{name}' to update its template. You will need to manually update it."
end
end
Modules that add filters to controller are hard to customize. You need to write a bunch of skip_filter then rebuild the entire change to add your own filters. It would probably be good to reevaluate how these work, possibly as middleware to be more reorderable. Here's an example which shows the problem, specifically a custom controller than needs CMS authentication behavior.
# Want to return the current user
class UserController < ApplicationController
# These add filters, but we want to insert some of our own.
include Cms::Acts::ContentPage
include Cas::Authentication
include NetForum::Enterprise::Authentication
# So we have to remove ALL filters
skip_filter(*_process_action_callbacks.map(&:filter))
# Then explicitly readd them.
before_filter :verify_cas_configured
before_filter CASClient::Frameworks::Rails::GatewayFilter, :only => :logout
before_filter :login_from_cas_ticket
before_filter :check_access_to_page, :only => :logout
# Return JSON data on the current user.
def index
ActiveRecord::Base.include_root_in_json = false
user = current_user
respond_to do |format|
format.json { render :json => user }
end
end
def logout
@final_destination = session[:final_destination]
if @final_destination
redirect_to @final_destination
else
redirect_to "/"
end
end
end