PullMonkey Blog

23 Dec

Simple CMS Plugin for Ruby on Rails Tutorial


The SimpleCMS Plugin

Created by Slaive and PullMonkey (December 2007)

Check out the demo - http://pullmonkey.com/projects/simple_cms

This is still a work in progress so feel free to notify me of any bugs, problems, or suggestions of how to make it better.

This plugin is built for rails 2.0.2. So if you are using an older version of rails then you will need to edit each of the controllers

1
2
3
4
5
6
7

From:
  self.view_paths << File.join(File.dirname(__FILE__), '..', 'views')

To:
  self.template_root = File.join(File.dirname(__FILE__), '..', 'views')

Imaging Processor

For this plugin to be fully functional you will need to install one of the following Image Processing gems:

  • ImageScience - A light inline-Ruby library that only resizes images.
  • RMagick - The grand-daddy, both in terms of advanced image processing features and memory usage.
  • minimagick - It's much easier on memory than RMagick because it runs the ImageMagick command in a shell.

Any one of these gems will work.

Install SimpleCMS and Dependencies

1
2
3

ruby script/plugin install http://svn.pullmonkey.com/plugins/trunk/simple_cms/

The simple_cms plugin requires the attachment_fu, responds_to_parent, acts_as_versioned, and coderay plugins as well. To make this easier I there is a built-in rake process

1
2
3

rake simple_cms:install_dependencies

However if this doesn't work then you can do it the normal way:

1
2
3
4
5
6

ruby script/plugin install http://svn.pullmonkey.com/plugins/trunk/attachment_fu/
ruby script/plugin install http://svn.pullmonkey.com/plugins/trunk/responds_to_parent/
ruby script/plugin install http://svn.pullmonkey.com/plugins/trunk/acts_as_versioned/
ruby script/plugin install http://svn.pullmonkey.com/plugins/trunk/coderay/

The Javascript/css Files

This plugin requires a great deal of javascript and css files that will need to be copied to the corresponding folder in your public/ directory. These files are located in the simple_cms/assets/ directory.

These files should have been copied over when you install the plugin. However, I built in a couple rake task commands to help you out installing and uninstalling these files if you need to.

1
2
3
4

rake simple_cms:install
rake simple_cms:uninstall

Creating the Tables

You will need to create 3 tables in your database.

  • simple_cms_items
  • simple_cms_images
  • simple_cms_media

To have the migration tables generated for you use this command:

1
2
3

ruby script/generate simple_cms_migrations

The tables should look like this:

create_simple_cms_items.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

class CreateSimpleCmsItems < ActiveRecord::Migration
  def self.up
    create_table :simple_cms_items do |t|
      t.column :params,     :string
      t.column :data,       :text
      t.column :position,   :integer
      t.column :created_at, :datetime
      t.column :updated_at, :datetime
      t.column :created_by, :string
      t.column :updated_by, :string
    end
    SimpleCmsItem.create_versioned_table
  end

  def self.down
    SimpleCmsItem.drop_versioned_table
    drop_table :simple_cms_items
  end
end

create_simple_cms_images.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

class CreateSimpleCmsImages < ActiveRecord::Migration
  def self.up
    create_table :simple_cms_images do |t|
      t.column :parent_id,    :integer
      t.column :content_type, :string
      t.column :filename,     :string
      t.column :thumbnail,    :string
      t.column :size,         :integer
      t.column :width,        :integer
      t.column :height,       :integer
    end
  end

  def self.down
    drop_table :simple_cms_images
  end
end

create_simple_cms_medias.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

class CreateSimpleCmsMedias < ActiveRecord::Migration
  def self.up
    create_table :simple_cms_medias do |t|
      t.column :parent_id,    :integer
      t.column :content_type, :string
      t.column :filename,     :string
      t.column :thumbnail,    :string
      t.column :size,         :integer
      t.column :width,        :integer
      t.column :height,       :integer
    end
  end

  def self.down
    drop_table :simple_cms_medias
  end
end

There is one more migration file you should have. It's called change_items_data_colmn and it looks like this:

1
2
3
4
5
6
7
8
9
10
11

class ChangeItemsDataColumn < ActiveRecord::Migration
  def self.up
    change_column :simple_cms_items, :data, :text, :limit => 10000000
  end

  def self.down
    change_column :simple_cms_items, :data, :text
  end
end

This is a change to the simple_cms_items table data column. This allows you to store up to 10 megabytes of text instead of the 65 kilobytes it defaulted to.

Remember to rake your tables into your databases once you have generated them.

1
2
3

rake db:migrate

Javascript and css Include Tags

You will need to make sure you have javascript include tags for your defaults and simple_cms and stylesheet link tags for the simple_cms and coderay stylesheets. Your app/views/layouts/application.rhtml should look something like this:

1
2
3
4
5
6
7
8
9
10
11

<html>
  <head>
    <%= javascript_include_tag :defaults, "simple_cms" %>
    <%= stylesheet_link_tag "simple_cms", "coderay" %>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

In Your View

Having the simple_cms plugin show up is really pretty simple. Anywhere you want to have the simple_cms to show up you put one line as simple as this:

1
2
3

<%= render :simpleCMS => "YourLabel", :admin => true %>

Here is another example with more options:

1
2
3
4
5
6

<%= render :simpleCMS => "label", :admin => true,
                                  :user => "UserName",
                                  :prefix => "/whatever/your/prefix/is",
                                  :reusable => true %>

  • :simpleCMS takes a label. Changing this label means losing all your current content and creating a new one. However, you can always change it back.
  • :admin takes true or false. The default is false. If you pass true then when you run your mouse over the content a blue highlight box will appear and you will be able to click on the box and edit the content. If you pass false then you will only be able to see the content but not edit any of it.
  • :user is optional and it takes any string you pass it.
  • :prefix is optional. This is where you pass your prefix if you have one.
  • :reusable takes true or false. Default is false. Set this true if you want to use this same content on multiple pages. The label must be the same on all pages you are using this content. *NOTE* you will lose all current data for this content if you change this as it gives the content a different id and changes the params of how it is called.



31 Responses to “Simple CMS Plugin for Ruby on Rails Tutorial”

  1. By celpjefscycle on Dec 23, 2007 | Reply

    Thanks for information. <br/>many interesting things <br/>Celpjefscylc

  2. By aka on Dec 23, 2007 | Reply

    This is a good thing. thanks

  3. By anonymous on Dec 23, 2007 | Reply

    Does simple cms do any caching?

  4. By charlie on Dec 23, 2007 | Reply

    No, but that is a good idea. Hopefully in the next release.

  5. By jagdish on Dec 23, 2007 | Reply

    Hey I have installed this plugin in my application. I followed all the as stated here. But in my application view file it comes only like this:

    Admin: enable disable
    Click to add content here.

    And nothing more than this.

    Plz let me know how to use it……

    Waiting for reply…………..

  6. By slaive on Dec 23, 2007 | Reply

    @jagdish

    Well the first thing to do would be to check that the simple_cms.css file is in your public/stylesheets folder.

    Are you using IE or Firefox?

    If you are using Firefox use firebug and see if there are any errors when you load the page.

    If you are using IE there will be a yellow triangle in the bottom left corner that you can click on if there are any errors.

    Let me know what you find. There might be javascript errors in IE with the Admin enable/disable.

  7. By Simon Jones on Dec 23, 2007 | Reply

    Hi,

    I downloaded and tried to install this, this evening, but am having problems with the usage. I followed the guide and everything appears to have set up OK, the JS & CSS files have been copied into place, and included in the application.rhtml layout view. I have then included a simpleCMS field on my home page.

    I get a link that appears to be working, but when I click on it I am forwarded to an error page showing:

    Routing Error

    no route found to match "/simple_cms_items/edit/1" with {:method=>:get}

    Any ideas? I thought maybe the controllers/models/views etc might need to be copied in to my main applications folders, but this didn’t work so I got rid of those and just left them in plugins folder.

    I also thought maybe the routes folder might need changing but had no idea what to change it to…

    Not seeing any errors on firebug.

    Any help much appreciated!

    Thanks,

    Simon

  8. By slaive on Dec 23, 2007 | Reply

    @Simon Jones

    You shouldn’t have to change anything in the routes file or move the views over or anything.

    The problem could be that you have a prefix for your webpage that you need to pass to the simple_cms in the render using the :prefix option.

    Play around with that a bit and let me know if it still doesn’t work.

  9. By Avram on Dec 23, 2007 | Reply

    Hey, this plugin is really nice, thanks.

    Is it possible to organize uploaded assets into folders, so there isn’t a huge list of say photos to choose from?

  10. By slaive on Dec 23, 2007 | Reply

    As of right now, no there isn’t, but I will keep that in mind for future versions. Thanks for the comment!

  11. By Avram on Dec 23, 2007 | Reply

    slaive,

    Ok, after an exhaustive review of Rails CMS’s, I’ve selected SimpleCMS for a development effort I’m pretty deep into. I’m going to need to be adding a little bit of functionality to it on my side. If you like what I’m doing, I’d be happy to contribute it back to the main project.

    Would you mind emailing me out of band for a little chat about my intentions? I’d like your feedback.

    Thanks,
    Avram

  12. By Peter on Dec 23, 2007 | Reply

    Hi,
    Thanks for this wonderful and useful plugin!
    This evening i’ve played around a bit trying to get rails page-caching to work with the simple_cms plugin. The idea is to render both the admin version of the cms_item and the public version of the cms_item on a page and based on a cookie decide what version to show. I ran into some problems with this, probably because of all the the session variables which get set when the render method gets invoked. I wondered did you ever try to cache pages with simple cms items on it? Do you have a suggestion of i could proceed and implement it?

    Thanks!
    Cheers,
    Peter

  13. By slaive on Dec 23, 2007 | Reply

    Peter,

    I have not yet gotten a chance to really do much with caching yet. It is on my list though. Let me know if you figure it out before I do. ;)

  14. By Peter on Dec 23, 2007 | Reply

    Thanks I’ll let you know, although i don’t think i’ll get far with my limited ruby and rails knowledge.

    Today i installed simple_cms for a rails 2.1 site. I had to tweak a bit to get it to work, let me tell what i did:
    -the version of acts_as_versioned that is installed with the rake task doesn’t work with rails 2.1, i installed a version from github instead.
    -in all simple_cms i had to use the append_view_path method: self.append_view_path (File.join(File.dirname(__FILE__), ‘..’, ‘views’))
    -rails couldn’t find the _simple_cms_item.rhtml partial, i ended up copying it to the view folder of my own app.
    -in simple_cms.rb i had to add a unless text.nil? in line 82. after the text.scan block.

  15. By slaive on Dec 23, 2007 | Reply

    Peter,

    I have not yet upgraded to rails 2.1 so thanks for the update on what needs to be changed.

    However, in lib/simple_cms.rb in the shared_path method is where we set a path to the _simple_cms_item.rhtml partial so you might want to look at that.

    The other thing is that I believe you would want to use "fragment caching" for the simple_cms plugin. Although I haven’t had a chance to make it work myself yet.

  16. By charlie on Dec 23, 2007 | Reply

    @Peter,Slaive - Made a couple changes for simple cms and 2.1, I will share them here and Slaive can take a crack at them.
    1) in plugins/simple_cms/lib/simple_cms.rb you can replaced the shared_path method with this:
    def shared_path(partial_path)
    return "shared/#{partial_path}"
    end
    2) in plugins/simple_cms/init.rb you can append the view paths for simple cms like this (this way you DO NOT have to take the simple_cms_item partial out of the plugin and place it in your view path):

    class ActionController::Base
    def self.inherited(klass)
    klass.append_view_path(File.join(File.dirname(__FILE__), ‘app’, ‘views’))
    super
    end
    end

  17. By chawei on Dec 23, 2007 | Reply

    When I tried to add an item, I got this error:

    ActionView::TemplateError (You have a nil object when you didn’t expect it!
    You might have expected an instance of Array.
    The error occurred while evaluating nil.include?) on line #1 of cms/index.html.erb:
    1: <%= render :simpleCMS => "YourLabel", :admin => true %>

    I found out this was a bug of "acts_as_versioned", and this can be fixed according to this issue: http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/125555dab7852bb2

  18. By Charlie on Dec 23, 2007 | Reply

    @chawei - thanks for the information. I assume it is all working now?

  19. By Avram on Dec 23, 2007 | Reply

    Hey Guys,

    I’ve run into a bug in SimpleCMS, and I’ve developed a fix. I believe the bug would only trigger when changing rails versions; the issues is that when SimpleCMS generates the value for the params field of an item, the conversion to yaml results in a hash’s element order becoming significant. Hash element order isn’t guaranteed, and I ran into a case where a minor rails version change caused all of my simple_cms_items to fail to be found b/c the underlying rails implementation happened to flip the order of the {:label => …, :domain => …} params hash.

    If you haven’t run into this yet, email me offline, I have a fix for you ready-to-go.

    -Avram

  20. By charlie on Dec 23, 2007 | Reply

    Avram - great, I would like to see the fix. You could always throw it up on a github fork and have us pull it.
    If you don’t want to do that, no big deal, I will send you an email shortly and you can respond there.

  21. By Richard on Dec 23, 2007 | Reply

    Hi there

    I’ve got SimpleCMS working OK except I can’t get my head around the admin and user options. At this stage I can either have the whole world edit a section or noone.

    How do I restrict which users can edit a page?

  22. By charlie on Dec 23, 2007 | Reply

    @Richard - Are you tracking the logged in user? With most user auth plugins this will be "current_user."

    :admin accepts true or false and does not have to be hardset, thus can be derived - so for :admin, you could use:
    :admin => current_user.is_admin?

    For :user, you could use
    :user => current_user.username

    The is_admin? method would be an instance method for the user model and it could look something like this (all depends on your setup):<filter:code attributes=lang="ruby">class User < ActiveRecord::Base

    def is_admin?
    return true if roles.include?(admin_role))
    return true if ["pullmonkey", "admin"].include?(username)
    return false
    end
    end</filter:code>

    Make sense?

  23. By Richard on Dec 23, 2007 | Reply

    Thanks charlie for your help

    I’m using acts_as_authenticated and that all seems fine.

    However I think I’m running into some session issues as everything works fine on my development machine but I notice that content will appear or disappear depending on whether I access http://www.domain.com or just domain.com in production.

  24. By charlie on Dec 23, 2007 | Reply

    @Richard - I’ve just fixed this by letting the user specify :domain. If it is not specified it will be the domain from the web server (like normal).

    Checkout the latest (from svn.pullmonkey.com) and you should be able to say:
    :domain => "idontcare" #— for example :)
    So it was not a problem with your sessions or anything (but thanks for not just assuming it was us :) )

    Let me know how it goes.

  25. By Richard on Dec 23, 2007 | Reply

    Ah, excellent. Many thanks for that. It’s now working fine. Greatly appreciated.

  26. By Loris on Dec 23, 2007 | Reply

    "ActionView::TemplateError (You have a nil object when you didn’t expect it!
    You might have expected an instance of Array."

    … occurs under Passenger (Mongrel/Webricks works fine) and Rails 2.3.2

    I had to change:
    in render.rb

    request_path = controller.request.env["REQUEST_PATH"]
    request_path = controller.request.env["REQUEST_URI"] if request_path.empty?
    request_path = controller.request.env["SCRIPT_NAME"] if request_path.empty?

    to..

    request_path = request.env["REQUEST_PATH"]
    request_path = request.env["REQUEST_URI"] if request_path.empty?
    request_path = request.env["SCRIPT_NAME"] if request_path.empty?

    don’t know why but now it works….

  27. By Stef on Dec 23, 2007 | Reply

    I had the same issue but had to change those lines to:

    request_path = request.env["REQUEST_PATH"]
    request_path = request.env["REQUEST_URI"] if request_path.blank?
    request_path = request.env["SCRIPT_NAME"] if request_path.blank?

  28. By Luke on Dec 23, 2007 | Reply

    Hi All, am having no problems displaying content via the CMS but when I try to edit an item it always returns

    Failed to load source for: http://localhost:3000/simple_cms_items/edit/5
    (If trying to edit item 5 for instance)

    I have set everything up as specified above, using Rails 2.3.3, not sure what the problem could be
    Thanks
    Luke

  29. By Chris K on Nov 13, 2009 | Reply

    Wow…. This is PLAIN AMAZING! My jaw just dropped. You guys are extra-awesome, no words to describe it. Just saved me a TON of work (or embarrassment!)

    Thank you lots!

  30. By Chris K on Nov 13, 2009 | Reply

    This is truly great! Just one question, though, the domain fix 5 posts above is not working for me (at least in 0.0.0.0:3000 dev mode). I use rails 2.3.4, is this a problem? It keeps stubbornly appending the full 0.0… URL to my images (Ideally I’d like to use :domain => “/”)

  31. By slaive on Nov 16, 2009 | Reply

    So what I am getting is that you want the images you upload inside simple_cms to use relative URLs correct?

    If that is so then the easiest way to fix that is to edit the public/javascripts/tiny_mce_init.js file. In there is all of the configuration options for tiny_mce. Unless you have made any changes to this file already then on line 25 you will see:
    relative_urls : false,
    This will need to be changed to
    relative_urls : true,
    and you should have the functionality that you are looking for.

    –slaive

Sorry, comments for this entry are closed at this time.