Bloggity – Rails Blog Plugin Made Stupid Simple

Last updated June 8th 2009: Bloggity version 1.0 has landed! This blog has been completely revised for the occasion.

With a spec (and funding) courtesy of Goldstar, I finally made time to incorporate many of the features I’d been hoping to add for the last year. Here is the current featureset:

  • Rails 2.3 compatible (also should be compatible with Rails 2.0-2.2, if you use the Engines plugin and copy the routes into your routes file)
  • Drop-in installation, including rake tasks to automate creating the necessary database tables, and moving the necessary assets into your existing project.
  • WYSIWYG editor for writing blogs
  • Support for AJAX uploading of images and/or assets of any kind with your blog post
  • URLs formatted using blog titles for good SEO (e.g., http://mysite.com/blog/founder/welcome_to_my_blog)
  • Create and maintain one or more blogs in a Rails app (e.g., a main blog, CEO blog, and user blogs)
  • User commenting, built in support for gravatars
  • Separate, configurable persmissions for writing, commenting on, and moderating comments for blogs
  • RSS 2.0 feeds (with built in customizability for Feedburner)
  • Ability to use custom stylesheets on a per-blog basis (i.e., the Founder’s blog can use different styling than the user blogs)
  • Ability to tag blog posts, and filter by tag
  • Ability to categorize blog posts
  • Blogs can be saved in draft mode before publishing
  • Model & controller test suite
  • Docs and an active git project!

Requirements, Dependencies

Bloggity 1.0 has been tested with Rails 2.3. In Rails 2.3, it shouldn’t need any plugins besides will_paginate. It should also work in Rails 2.0-2.2, but you’ll need to copy the routes into your routes file, since routes were extracted from plugins in 2.3. Other monkeying around might also be needed, if you have issues installing on pre-2.3 Rails, please drop a line in the comments.

FCKEditor is used for the WYSIWYG editor. This is included with the plugin, and shouldn’t affect your existing Rails install (plugin puts its assets in a separate directory). For the image uploading, jQuery is used (since it works via AJAX). This is also included with the plugin, and doesn’t need to be used elsewhere on your site.

Installation Instructions

  1. Run “script/plugin install git@github.com:wbharding/bloggity.git” to grab Bloggity and put it in vendor/plugins/bloggity
  2. Run “rake bloggity:bootstrap_db” from your application’s base directory
  3. Run “rake bloggity:bootstrap_bloggity_assets” to copy the images and stylesheets used with bloggity into your apps /public/stylesheets/bloggity and /public/images/bloggity directories.
  4. Run “rake bloggity:bootstrap_third_party_assets” to copy FCKEditor and jQuery into your “/public/javascripts/bloggity” directory. This is not required, but the WYSIWYG editor and asset uploading won’t work without it.
  5. Take a gander at bloggity/lib/bloggity/user_init.rb. This shows the methods that bloggity will use to interface with your user model (for blog permissions and such). Implement these in a sensible way in your user model. Don’t forget to copy the blog associations into your user. (If you prefer, you could also copy the UserInit into a lib directory of yours, fill in the methods, and include it in your User model directly)
  6. There are two methods in bloggity/lib/bloggity/bloggity_application.rb: current_user and login_required. Implement these in your application_controller.rb if you haven’t already.

And you’re done!

In the Wild

An earlier version of Bloggity can be seen in the wild at the Bonanzle blog. Bloggity 1.0, with its support for tagging, categorization, and gravatars, actually exceeds the features you’ll see at Bonanzle.

Screenshotsbloggity_1

Here are a couple shots of Bloggity in action with its default styles.

Looking at the main blog.

Writing a blog.

Uploading assets for a blog.

Miscellaneous

I haven’t built in support yet for upgrading from pre-1.0 versions of Bloggity, because, well, just about everything changed with the release of 1.0, not the least of which is the names for several models. However, when Bonanzle moves from Bloggity 0.5 to 1.0, I’ll post how we went about it here.

Please add your bug reports to the comments section and I’ll commit changes as you find them.

34 thoughts on “Bloggity – Rails Blog Plugin Made Stupid Simple

  1. Pingback: » Savage Blog - An Idea for a Rails Blog Plugin :: Relentless Simplicity :: The Bonanzle Tech Blog

  2. OK… figured it out… yikes…

    the current_user definition was being used by another plugin, thus was interfering. I renamed it blog_user in the bloggity app, and that fixed it…

    Nice :-)

    Thanks.

    Mike

  3. Any chance of packaging that puppy up as a gem ?

    Will make it a lot easier to deal with it in the code (IMHO).

    Look good, about to try integrating it into a project in about an hour and migrating the manual pages over to the blog.

    Nice !

  4. Step 5 : Could you not just add “include Bloggity::UserInit” to the user model ?

    Step 6 : The reference to method “require_login” should be “login_required” . Also there are alot more than two methods. On behalf of the struggling newbies out there can you update this to make that clear.

    As previously mentioned by Mike, you need to update the routes.rb in your app to include “map.from_plugin :bloggity”.

    The level of my questions is admittedly very low but us newbies, we are out there.

    Thanks for what seems to be a great plugin / Colm

  5. Daryl: Packaging it as a gem may be a good idea. I’ll see if I can find some time to look into how to do that at some future point. Not sure if that affects how Rails would be able to load its models and routes, though?

    Colm: Yes, you could include Bloggity::UserInit, but ultimately almost all of the methods in UserInit need to be overridden, so I’m not sure that there’s a huge win to that. Except for testing purposes.

    You’re also right about login_required. I’ve edited the instructions to fix that.

    Re: Adding the routes line, I presume you must be on Rails 2.0-2.2? In my testing environment (Rails 2.3) I didn’t need to add this line, Rails just figured it out.

    Will be curious to hear if you get it successfully integrated in a Rails earlier than 2.3…

  6. When I try and run the first rake task, I get:

    uninitialized constant CreateBlogTables::Blog

    which would seem to indicate it isn’t picking up the app directory from the plugin. I’m running rails 2.3.2. Any advice would be appreciated.

  7. Looks like a great plug-in, I’m trying to install it in an existing 2.0.2 Rails website and running into a problem with the first rake task:

    rake aborted!
    uninitialized constant ActiveSupport::Dependencies

    Trace:
    bio4046471:/usr/local/src/rebath teeverso$ rake bloggity:bootstrap_db –trace
    (in /usr/local/src/rebath)
    ** Invoke bloggity:bootstrap_db (first_time)
    ** Invoke environment (first_time)
    ** Execute environment
    rake aborted!
    uninitialized constant ActiveSupport::Dependencies
    /usr/local/src/rebath/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:266:in `load_missing_constant’
    /usr/local/src/rebath/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:453:in `const_missing’
    /usr/local/src/rebath/vendor/plugins/bloggity/init.rb:7:in `evaluate_init_rb’
    /usr/local/src/rebath/vendor/plugins/bloggity/init.rb:6:in `each’
    /usr/local/src/rebath/vendor/plugins/bloggity/init.rb:6:in `evaluate_init_rb’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/rails/plugin.rb:79:in `evaluate_init_rb’
    /usr/local/src/rebath/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/core_ext/kernel/reporting.rb:11:in `silence_warnings’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/rails/plugin.rb:75:in `evaluate_init_rb’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/rails/plugin.rb:39:in `load’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/rails/plugin/loader.rb:33:in `load_plugins’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/rails/plugin/loader.rb:32:in `each’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/rails/plugin/loader.rb:32:in `load_plugins’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/initializer.rb:189:in `load_plugins’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/initializer.rb:105:in `process’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/initializer.rb:49:in `send’
    /usr/local/src/rebath/config/../vendor/rails/railties/lib/initializer.rb:49:in `run’
    /usr/local/src/rebath/config/environment.rb:15
    /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require’
    /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require’
    /usr/local/src/rebath/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:496:in `require’
    /usr/local/src/rebath/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:342:in `new_constants_in’
    /usr/local/src/rebath/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:496:in `require’
    /usr/local/src/rebath/vendor/rails/railties/lib/tasks/misc.rake:3
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:617:in `call’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:617:in `execute’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:612:in `each’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:612:in `execute’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:578:in `invoke_with_call_chain’
    /usr/local/lib/ruby/1.8/monitor.rb:238:in `synchronize’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:571:in `invoke_with_call_chain’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:588:in `invoke_prerequisites’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:585:in `each’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:585:in `invoke_prerequisites’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:577:in `invoke_with_call_chain’
    /usr/local/lib/ruby/1.8/monitor.rb:238:in `synchronize’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:571:in `invoke_with_call_chain’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:564:in `invoke’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:2019:in `invoke_task’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:in `top_level’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:in `each’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:in `top_level’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:2036:in `standard_exception_handling’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1991:in `top_level’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1970:in `run’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:2036:in `standard_exception_handling’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1967:in `run’
    /usr/local/lib/ruby/gems/1.8/gems/rake-0.8.3/bin/rake:31
    /usr/local/bin/rake:19:in `load’
    /usr/local/bin/rake:19

    Any ideas what I’m missing?I realize this may be only directly compatible with Rails 2.3, but this is a large functioning CMS I’m trying to add it to and I think trying to upgrade would cause alot more problems than adapting the plug-in. Advice greatly appreciated.

  8. Hey Tim,

    I believe the Rails 2.0 equivalent of:

    ActiveSupport::Dependencies.load_once_paths.delete(path)

    Is:

    Dependencies.load_once_paths.delete(path)

    Replace the first line with the second and your problem should resolve itself.

  9. I can’t seem to get it to work. I am running RAILS 2.3.2. When I go to ‘/blogs/1/blog_posts/new’ I receive the following error:

    undefined method `get_bloggity_page_name’ for #

    Not sure why it can’t see bloggity_application where get_bloggity_page_name is defined.

    Any ideas?

  10. @dungtqa: Are you using Rails 2.0-2.2 with Engines? If so, chances are you’ll need to copy the routes that are in /vendor/bloggity/config/routes.rb into your main routes file.

    @YSBS: Hmm.. normally the Bloggity::BloggityApplication is included in your application_helper by virtue of the /bloggity/init.rb file, which includes said module in your application via send calls.

    Maybe you could try to manually include it, by adding “include Bloggity::BloggityApplication” in your application_controller.rb and/or application_helper.rb? Though I find it quite odd that the send lines at the top of init.rb aren’t doing this for you. Particularly since they have been working fine on my Rails 2.3 install.

  11. @Bill
    Thanks for your help.

    I went looking for /bloggity/init.rb and to my surprise it was missing (along with some other files when compared to the trunk). I am developing on windows XP and it appears that the built in zip program wasn’t properly extracting all the files. When I re-extracting using a different program everything worked fine.

    Thanks again for the plug-in!

  12. Many thanks for the plugin.

    A couple of minor problems…

    1. attachment_fu plugin was required to prevent undefined method `has_attachment’ in blog_posts/edit.html.erb (I didn’t try any other views).

    2. The bloggity:bootstrap_bloggity_assets task created files named “bloggity” instead of directories into which to copy the assets. To fix, remove the ‘*’ to get Dir[File.join(BLOGGITY_BASE_DIR, 'public', asset)].each{|f| …

    bloggity e1da9532fe1a266b04c12ce4f68b1cd52ed82339
    ruby 1.8.6, rake 0.8.4, rails 2.3.2

  13. A few more I’m afraid…

    3. ActiveRecord::RecordNotFound in BlogPostsController#edit “Couldn’t find BlogPost without an ID” when attempting to create a new post. Fixed by specifying user id in new action: @blog_post = BlogPost.new(:posted_by_id => current_user.id, …

    4. BlogPostsController doesn’t create @blog_posts. Did you mean to test for assigns(:recent_posts) in test_blog_show_normal? (tests pass when doing so).

    5. When using sqlite for tests, I got the following in a couple of tests in BlogPostsControllerTests:

    ActionView::TemplateError: SQLite3::SQLException: no such column: true: SELECT count(*) AS count_all FROM “blog_comments” WHERE (“blog_comments”.blog_post_id = 1 AND (approved = true))

    Fixed by making conditions use 1 instead of true in BlogPost… has_many :approved_comments, :conditions => %{approved = 1}, :class_name => ‘BlogComment’

    sqlite3 3.6.13

  14. Got another one for you :-P

    6. Because a new post is created automatically before forwarding to its edit page, the is_complete field of the blog_posts table should have :default => false otherwise new posts that were not updated will not show in the list of pending posts (due to SQL requiring IS NULL for querying NULL).

  15. Quick question…

    I’d like to implement bloggity for my project, but I want only one person – admin – post blogs while other users can leave comments. How can I set up the model to achieve what I am trying to do?

    Thank you so much in advance….

  16. Yang: check the methods availabie in the user_init.rb. You can implement permissions however you want in your own user model (you can actually get more granular than just post comment vs. post blog)

  17. Still getting:

    uninitialized constant CreateBlogTables::Blog

    at the very end of the first rake task when it tries to create the first blog. Skipped this test and tried to execute the same Blog.create in the console and I get the same error:

    uninitialized constant Blog

    Thoughts on why it’s not picking the app up? I’m on Rails2.0.1 :)

  18. Pingback: PullMonkey Blog » Blog Archive » Blog plugin tutorial for Ruby on Rails

  19. Bill – this works fantastically well. Had it up and running in about half an hour and I’m a relative noob on Rails. The excellent documentation is a great help.

  20. Hey Bill, thanks for contributing what looks like a great plugin so far. One issue with configuring user_init, there’s a logged_in? method that needs defining. A lot of authentication plugins (I’m using ‘devise’, but previously used restful_authn) don’t define logged_in? within the user, and models don’t have access to session state (can be changed, but I’m hoping to stay MVC), so how should such a method be defined? I looked through bloggity to see if it’s getting used, and it doesn’t appear to be, but I wanted to check.

  21. I can’t seem to figure out how to get the RSS feed to work. Has anyone managed to get this working? I’m also having some problems with the pagination on my blog … the link to page 2 just loads the same page.

  22. The problem on the pagination is that this call:

    will_paginate(@blog_posts, {:form_name => :blog_show_params, :param_name => :page} )

    doesn’t seem to pass a form_name and so the controller can’t extract the page number. I just modified the controller to pull the page number from the parameters.

    I’m using will_paginate version 2.3.11 and Rails 2.3.4

  23. On the problem with the RSS feed. I have a blog called ‘main’ with id=1

    When I get the URL

    /blogs/1/feed

    I see a valid XML page. However, the URL

    /blogs/main/feed

    doesn’t seem to get properly routed to the feed action in the Blogs controller. On localhost I see the following:

    Processing BlogsController#feed (for 127.0.0.1 at 2010-01-10 18:05:47) [GET]
    Parameters: {“action”=>”feed”, “id”=>”main”, “controller”=>”blogs”}
    Blog Columns (0.6ms) SHOW FIELDS FROM `blogs`
    Blog Load (0.0ms) SELECT * FROM `blogs` WHERE (`blogs`.`id` = 0)
    Rendering /home/avitus/projects//public/404.html (404)

    So it’s looking for a blog with the wrong ID. (Which is odd because I wouldn’t expect that from the code I see in the ‘feed’ method in the Blogs controller.

    I’ve currently hacked it to get the feed from the URL with the blog ID but that’s not very SEO-friendly.

  24. cool plugin !
    had quick blog requirement.
    bloggity made it easy.
    faced some hiccups related with user model as we had different users like
    User,JobSeeker,RecruiterDirect,RecruiterAgent.
    I was getting error: “cannot find recruiter_direct_path” method.

    Solved using routes.
    map.resources “users”
    map.resources “recruiter_direct”
    map.resources “recruiter_agent” etc.

    Thanks Hardy !

  25. @Liam did you ever get the logged_in? method to work inside the user model? I’m just leaving it as true for the time being, but it would be nice to have it actually reflect a user being logged in.

  26. I think I am missing a few steps, likely because of my inexperience with Rails. I am trying to integrate Bloggity into a project of mine. I am getting routing errors. I have followed steps 1-4, and am having difficulty understanding the specifics of Step 5. Would someone have an example file that they could post.

    Also, what do I set the route up to?

    I am trying:

    map.blog ‘/blog’, :controller => ‘blogs’, :action => ‘show’

    but am getting the following error:

    “uninitialized constant BlogsController”

    Ideally, I would like to implement the blog as a read only feature that an admin can write to. No comments, etc. Any guidance you can offer would be greatly appreciated.

    Thanks.

  27. @Pavneet

    BTW, I am running Rails 2.3.5, and I did read the comment that on Rails 2.3.* you shouldn’t need to do any routing.

  28. Hey!!

    I have implemented Bloggity nicely, running rails 2.3.5.

    I am able to add a category, but after filling in the new post form along with an asset, i get the following error:

    undefined method `user_path’ for #

    Please suggest.

    Thanks
    Priya Saini

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">