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
Add the following to your Gemfile:
gem 'muck-contents'
Note about TinyMCE
Watch out for updates to the TinyMCE gem. The author has chosen to overwrite all files in the tiny mce asset directories when the server starts up. This will delete the muck related plugins in the tiny_mce/plugins directory.
Gem configuration and setup
In your app do
script/generate friendly_id
script/generate acts_as_taggable_on_migration
rake db:migrate
Setup
Muck Contents Initializer
Create a new initializer or add the following to muck.rb 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. Example:
MuckContents.configure do |config|
config.sanitize_content = true
config.enable_auto_translations = false # If true then all content objects will automatically be translated into all languages supported by Google Translate
config.translate_to = ['es', 'fr'] # If auto translate is enabled this indicates which languages to translate the content into. Specify Babelphish::GoogleTranslate::LANGUAGES to translate to all available language (not recommended).
config.enable_sunspot = false # This enables or disables sunspot for profiles. Only use acts_as_solr or sunspot not both. Sunspot does not include multicore support.
config.enable_solr = true # Enables solr for the content system. If you are using solr then set this to true. If you do not wish to setup and manage solr
# then set this value to false (but search will be disabled).
config.enable_comments = false
# CSS files that should be fed into the tiny_mce content editor.
# Note that Rails will typically generate a single all.css stylesheet. Setting the stylesheets here let's
# the site administrator control which css is present in the content editor and thus which css an end
# user has access to to style their content.
if Rails.env.production?
config.content_css = ['/stylesheets/all.css']
else
config.content_css = ['/stylesheets/reset.css', '/stylesheets/styles.css']
end
end
Tests
Muck-Contents inserts an exception handler. If this handler is not loaded the gem will prevent your application from loading. This is mainly a problem in tests where show_exceptions is set to false. Enable ‘show_exceptions’ in test.rb:
RailsTest::Application.configure do
config.action_dispatch.show_exceptions = true # Must be true to include the rack middleware require to generate missing page exceptions
end
Tiny MCE 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.
Attach content to a parent model
Content can be scoped to a specific model. ie
class User < ActiveRecord::Base
include MuckContents::Models::MuckContentable
end
Then the user’s content can be accessed via:
@user.contents
Content Permissions
By default users are not allowed to add content. Add ‘can_add_root_content?’ to your user model to determine which users can add content to the root of the website. A default configuration might be admins only:
class User < ActiveRecord::Base
def can_add_root_content?
admin?
end
end
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
include MuckContents::Models::MuckContent
end
class ContentTranslation < ActiveRecord::Base
include MuckContents::Models::MuckContentTranslation
end
class ContentPermission < ActiveRecord::Base
include MuckContents::Models::MuckContentPermission
end
Contents controller
Optionally create a ContentsController and inherit from Muck::ContentsController. This step is only needed if you intend to override the default contents controller functionality.
class ContentsController < Muck::ContentsController
end
Add a route for the new controller:
MyApp::Application.routes.draw do
resources :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, :multiupload, :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. Be sure to look at the ‘uploader’ gem documentation for more information on setting up uploads.
class Upload < ActiveRecord::Base
include Uploader::Models::Upload
# only allow images:
# validates_attachment_content_type :file, :content_type => ['image/jpeg', 'image/pjpeg', 'image/jpg']
# limit uploads to 10 MB
# validates_attachment_size :local, :less_than => 10.megabytes
# The following method is implemented in the upload model mixin. This is the method destroy will check to see if
# the user has permission to delete the object. Add additional logic as needed or if the existing logic
# looks fine then feel free to delete this comment and the can_edit? method.
def can_edit?(check_user)
return false if user.blank?
check_user == self.user
end
end
Tips
If friendly_id starts producing errors like this then you need to redo your slugs:
ActiveRecord::StatementInvalid (Mysql::Error: Duplicate entry 'my-content-page-/-2' for key 2: UPDATE `slugs` SET `scope` = '/', `sequence` = 2 WHERE `id` = 189):
Run this and you should be good to go:
rake friendly_id:redo_slugs MODEL=Content
Cleanup old slugs with:
rake friendly_id:remove_old_slugs MODEL=Content
Testing
This gem uses a full rails application in the test directory for testing and development. Running rake spec there will run the tests.
Copyright © 2009-2010 Tatemae, released under the MIT license