MuckContents
Add contents to you website. News stories, blog posts and pages are all basically a page with content and a title. Muck content makes it easy to add this content to your website.
Gems
Note that all gems below should be installed automatically as a muck-contents has them set as a dependency.
sudo gem install muck-contents
Configure environment.rb
Paste in the following:
config.gem "will_paginate"
config.gem "authlogic"
config.gem "searchlogic"
config.gem "bcrypt-ruby", :lib => "bcrypt", :version => ">=2.0.5"
config.gem "acts-as-taggable-on"
config.gem "awesome_nested_set"
config.gem "friendly_id"
config.gem "sanitize"
config.gem 'paperclip'
config.gem 'tiny_mce'
config.gem 'fleakr'
config.gem "uploader"
config.gem "babelphish"
config.gem 'muck-engine', :lib => 'muck_engine'
config.gem 'muck-users', :lib => 'muck_users'
config.gem 'muck-activities', :lib => 'muck_activities'
config.gem 'muck-solr', :lib => 'acts_as_solr'
config.gem 'muck-comments', :lib => 'muck_comments'
Gem configuration and setup
In your app do
script/generate friendly_id
script/generate acts_as_taggable_on_migration
rake db:migrate
Setup
Global Config
Add the following settings to your global_config.yml file and change as is appropriate for your application. In particular be sure to set content_css to any css files you want to have show up in your tinymce editor.
# Content options
content_git_repository: "#{File.join(RAILS_ROOT, 'repo', RAILS_ENV)}"
enable_auto_translations: true
content_enable_solr: false
content_css: ['/stylesheets/reset.css', '/stylesheets/styles.css']
flickr_api_key: #get from www.flickr.com/services/api/misc.api_keys.html
Initializer
Running rake muck:contents:sync will copy all the needed javascript, image and css files into your project. It will also create an initializer called mce_options.rb. That file contains two basic configurations for tinymce as well as examples on how to create templates. It is recommended that you don’t modify that file as it will be overwritten the next time you run rake muck:contents:sync. Instead use it as an example and create the desired tinymce setup.
User model
Add the following method to your user model and modify it according to your specific needs:
def can_add_root_content?
admin?
end
This method determines who can add content to any url on your website. For example, if you type in www.example.com/a/test/page and that page does not exist, muck contents will automatically create a page for you at that location if the logged in user has a method can_add_root_content? that returns true.
Content models
Create the following models in your project. This let’s you add any other methods that you see fit.
class Content < ActiveRecord::Base
# This assumes you are using GlobalConfig. You can also set these values directly in the model
acts_as_muck_content(
:git_repository => GlobalConfig.content_git_repository,
:enable_translations => GlobalConfig.enable_auto_translations,
:enable_solr => GlobalConfig.content_enable_solr
)
end
class ContentTranslation < ActiveRecord::Base
acts_as_muck_content_translation
end
class ContentPermission < ActiveRecord::Base
end
Application controller
Add acts_as_muck_content_handler if you want muck_contents to intercept pages that are not found and provide authorized users and opportunity to add them.
class ApplicationController < ActionController::Base
acts_as_muck_content_handler
end
Contents controller
Create a ContentsController and inherit from Muck::ContentsController. Unfortunately, due to routing issues this is required or we’d have to hard code the routes to go to muck/contents which prevent modification of the contents_controller.
class ContentsController < Muck::ContentsController
end
Add a route for the new controller:
ActionController::Routing::Routes.draw do |map|
map.resource :contents
end
Override the contents controller to change the the security model. For example:
class ContentsController < Muck::ContentsController
# Modify this method to change how permissions are checked to see if a user can content.
# Each model that implements 'has_muck_content' can (and should) override can_add_content? to
# change how content permissions are handled.
def (user, parent, content)
parent.can_add_content?(user)
end
# Setups up the layouts that are available in the 'layouts' pulldown.
# Override this method to change the available layouts. Note that the
# layout will need to exist in your 'views/layouts' directory
def setup_layouts
@content_layouts = []
@content_layouts << OpenStruct.new(:name => 'A Great Layout', :value => 'great_layout')
@content_layouts << OpenStruct.new(:name => 'Default', :value => 'default')
end
end
Uploader
muck-contents uses the uploader gem and thus requires all the configuration to make that gem function. This includes the addition of and uploads controller and upload model. See that gem for more information. If you have generated your project using the rails template generator (github.com/jbasdf/rails-templates) then it should be setup for you. The actual uploading of files and images will be handled by the uploads controller. The security for uploads to your site should be handled in that controller.
Example uploads controller:
class UploadsController < Uploader::UploadsController
before_filter :login_required
before_filter :setup_parent, :only => [:index, :create, :swfupload, :photos, :files]
def index
@upload = Upload.new
@uploads = @parent.uploads.paginate(:page => @page, :per_page => @per_page, :order => 'created_at desc')
respond_to do |format|
format.html { render }
format.rss { render :layout => false }
end
end
def photos
@images = @parent.uploads.images.paginate(:page => @page, :per_page => @per_page, :order => 'created_at desc')
respond_to do |format|
format.html { render }
format.rss { render :layout => false }
end
end
def files
@files = @parent.uploads.files.paginate(:page => @page, :per_page => @per_page, :order => 'created_at desc')
respond_to do |format|
format.js { render :json => basic_uploads_json(@files) }
end
end
protected
def get_upload_text(upload)
render_to_string( :partial => 'uploads/upload_row', :object => upload, :locals => { :style => 'style="display:none;"', :parent => @parent } )
end
def get_redirect
@parent
end
def (user, upload_parent)
return true if upload_parent.blank?
upload_parent.can_edit?(user)
end
def
= t("uploader.permission_denied")
respond_to do |format|
format.html do
flash[:notice] =
redirect_to get_redirect
end
format.js { render :text => }
format.json { render :json => { :success => false, :message => } }
end
end
end
Example upload model:
NOTE: you must define icon, thumb, small, medium and large as styles. They can be any size you like.
class Upload < ActiveRecord::Base
acts_as_uploader :enable_s3 => false,
:has_attached_file => {
:url => "/system/:attachment/:id_partition/:style/:basename.:extension",
:path => ":rails_root/public/system/:attachment/:id_partition/:style/:basename.:extension",
:styles => { :icon => "30x30!",
:thumb => "100>",
:small => "150>",
:medium => "300>",
:large => "660>" },
:default_url => "/images/profile_default.jpg",
:storage => :s3,
:s3_credentials => AMAZON_S3_CREDENTIALS,
:bucket => "assets.#{GlobalConfig.application_url}",
:s3_host_alias => "assets.#{GlobalConfig.application_url}",
:convert_options => {
:all => '-quality 80'
}
},
:s3_path => ':id_partition/:style/:basename.:extension'
acts_as_taggable
named_scope :public, :conditions => "is_public = true"
named_scope :tagged_with, lambda {|tag_name| {:conditions => ["tags.name = ?", tag_name], :include => :tags} }
end
Testing
This gem uses a full rails application in the test directory for testing and development. By default there isn’t a global_config.yml setup.
Use global_config.sample.yml to set one up.
Copyright © 2009 Tatemae, released under the MIT license