Sidebar beta

Published 2008-09-14 by Robert Burén
Tags: blog.rb, comments, feature, sidebar, tags
8

I’ve finally crossed off one more feature on the list: a configurable sidebar. I’ve created three types of items to include in the sidebar:

  1. Any static HTML
  2. Most used tags
  3. Latest comments

However, it’s all very much in a beta stage at the moment… The only way to add items is using the Rails Console, which may not be considered a “best practice”. Also, both the “Most used tags” and the “latest comments” component displays only unlinked text. Obviously some more work is needed here as well.

Oh, as for the image in this entry: it’s supposedly a “side bar”…

 

IE layout fixed. I hope...

Published 2008-09-11 by Robert Burén
Tags: blog.rb, layout
7

I think I’ve fixed the Internet Explorer layout issues for now. At least it looks ok for me. How this site looks like in IE won’t be the highest priority for me, but I still definitely appreciate any comments on issues that you might see.

I’m not dissing IE, it’s just that I have now finally converted all my main computers on to Ubuntu, so that’s all I see on a daily basis. This screenshot was taken on IE6 on Ubuntu, by the way…

 

IE is not my friend

Published 2008-09-02 by Robert Burén
Tags: blog.rb, layout
6

It has come to my attention (with the help of the brilliantly useful service provided by Browsershots.org) that this blog layout doesn’t look good in Internet Explorer (version 7 on Windows).

I’ve also been led to believe that there are people out there that actually use IE as their main browser. Strange as that may seem, I will try to fix the appearance issues for IE users as soon as possible!

(Oh, and any help or pointer to what the root source of the problem actually is will be much appreciated!)

 

Ubuntu vs Rails

Published 2008-08-21 by Robert Burén
Tags: mod_rails, passenger, rails, ruby, ubuntu
4

I don’t know what happened! I had a perfect little setup on my VPS, with a super simple script to install all the little packages I wanted, including ruby, rubygems, git and Passenger. It goes something like this:

# Some non-ruby installs first...

# Ruby
apt-get -qq -y install ruby-full libmysql-ruby rubygems
gem update --system

# Version control
apt-get -qq -y install git-core subversion cvs

# Passenger (aka mod_rails). This will also include apache2
# Need to add the brightbox gpg key before installing
echo "deb http://apt.brightbox.net hardy main" >> /etc/apt/sources.list
wget http://apt.brightbox.net/release.asc -O - | apt-key add -
apt-get -qq update
apt-get -qq -y install libapache2-mod-passenger

The wget and apt-key parts is to get the gpg key from brightbox. If you don’t, you’ll end up with annoying warnings everytime you do an “apt-get whatever”.

Anyway — that setup worked perfectly! Until about a week ago, that is…

Now, when I check what there is to update, with the usual commands…

apt-get update
apt-get -s dist-upgrade

…I get into problems. For some reason, apt-get wants to remove passenger. Now, why is that?

The printout reads as follows:

The following packages will be REMOVED:
  libapache2-mod-passenger libgems-ruby1.8
The following NEW packages will be installed:
  rubygems1.8
The following packages will be upgraded:
  initramfs-tools iproute irb libdbm-ruby libgdbm-ruby libopenssl-ruby libreadline-ruby pciutils rdoc ri ruby ruby-full rubygems tzdata

Someone please tell me how to get back on track again! Or back on the Rails, as it were…

 

Back to the Future

Published 2008-08-03 by Robert Burén
Tags: blog.rb, roadmap
3

(Yeah I know — the title of this post is embarrassing!)

Yesterday I posted a kind of status report, so I guess now is a good time to follow up with a sketchy roadmap for the next few weeks (or maybe, months).

Features I want to add next to blog.rb are (in no particular order):

  • A sidebar… Of course, this is just a layout element, but I want to make a modular sidebar that I can configure the contents of
  • Static pages. Even a blog needs a few static pages: a blog author profile maybe, and stuff like that. These should really be handled the same way as ordinary posts, but probably have a different URL and not show up among the other posts.
  • Full text search. Ideally, the same search will look in posts, tags, and static pages.
  • Automatic blog ping via XML-RPC
  • Category list in sidebar. This is probably just a tag cloud like feature, but since I think I really dislike tag clouds it’ll probably look more list-like.
  • A link to blog.rb’s home on GitHub. I feel like I need to take some time cleaning up docs in the project before I publish the link. The link is there for anyone to find anyway, but it’s more official if I link to it from here…

After all of the above: who knows? Maybe it’s time I put some energy in a real project instead of this toy… We’ll see.

 

It's that status time again

Published 2008-08-02 by Robert Burén
Tags: blog.rb, feature, status
2

So, where are we?

Three weeks ago, and just after starting this blog, I posted a status report. Later the same day, I posted a roadmap for the near future. I think it’s fair to say that I can now check all the items on that list. I think I have commented on most (all?) of them on previous posts, but let’s not let that keep us from going through the list again:

Stay tuned to see what comes next, this time…

 

Attached images

Published 2008-08-02 by Robert Burén
Tags: attachments, attachment_fu, blog.rb, feature, images, plugin
1

Dear Diary,

Today I added an image upload plugin called attachment_fu. It worked great! The only thing that wasn’t provided for me out-of-the-box was the ability to show an image stored in the database.

The remedy for this was a new controller (actually, another sub-resource to posts), with the following method:

  def show
    @content_image = @post.content_images.find(params[:id])
    headers['Content-Length'] = @content_image.size
    send_data @content_image.db_file.data, 
      :type => @content_image.content_type, 
      :disposition => 'inline', 
      :filename => @content_image.filename
  end

I’d like to point out one gotcha to be picked up by search engines: the README for attachment_fu simply says that you should create a migration for a model called DbFile with a field :data of type :binary. The problem is that the default for MySQL is to use the BLOB type, which has a limit of 64k. You need to use a larger database type, such as MEDIUMBLOB or LONGBLOB. This is accomplished by adding a :limit parameter to the migration:

    create_table :db_files do |t|
      t.binary :data, :limit => 10.megabytes # here it is
      t.timestamps
    end

Setting a larger :limit like that will cause a larger database type to be used.

Now, the current implementation of attaching an image to a post is really limited. If there is an image, it is shown at the top of the post, right-aligned. That’s it. No checking for dimensions, alt texts or anything like that. Also no way to tag where in the post the image should be displayed. This will (probably…?) be fixed in future versions!

 

Tags introduced

Published 2008-07-28 by Robert Burén
Tags: acts_as_taggable_on, ajax, blog.rb, feature, plugin, tags

Next feature to cross off the TODO-list for blog.rb: tags. It’s now possible to tag posts in the conventional Web 2.0 way. Tags are displayed on top of each post, as links. Click on a tag and You’ll see a list (fetched with Ajax, no less) of posts using that tag.

To get that tag goodness, I’m using the acts_as_taggable_on plugin, which I really recommend! Integrating the plugin in blog.rb was as easy as 1-2-3:

1. Run ./script/generate acts_as_taggable_on_migration to create a migration with the tags and taggings tables. Run the migration (rake db:migrate as usual).

2. Add this line to the Post class:

  acts_as_taggable_on :tags

The “:tags” parameter is the name of the tag field in the model. We could have chosen to call it something else, ie “categories”, “keywords”, “topics”, etc, but I’m sticking with “tags” for now.

3. Next we add a field for the tags in the “create post” form:

  <p>
    <%= f.label :tag_list, "Tags" %><br />
    <%= f.text_field :tag_list %>
  </p>

That’s it for adding it to the model. Of course, we also want to show the tags in a nice way, and make them useful to readers. This is where The Ajax comes in.

If a post has tags, I display them comma-separated below the title of the post. Each tag in that line is rendered like this:

  link_to_remote tag.name,
    :url => {:controller => :tags, :action => :show, :id => tag, :blog_id => post.blog, :post_id => post, :show_title => true},
    :method => :get,
    :update => "post_#{ post.id }_taginfo",
    :loading => update_page {|page| page.visual_effect(:fade, "post_#{ post.id }_taginfo", :duration => 0.2)},
    :complete => update_page {|page| page.visual_effect(:appear, "post_#{ post.id }_taginfo", :duration => 0.2)}

In the code above, I’m making an ajax call to the standard /tags/{id} REST url. I’m not sure if that’s really kosher, but hey — it’s my app! The result will render a list of linked posts that have that particular tag. Try it out!

Now I’m going to go back and tag all my previous posts! Fun, fun, fun!

 

Comments: One

Published 2008-07-22 by Robert Burén
Tags: ajax, blog.rb, captcha, comments, feature, resources, rjs

We have comments!

Well, I have one comment, which is the one I just added myself, to test the new comment feature on blog.rb. It is actually working, including reCAPTCHA integration. Very nice.

There are definitely more work to do on comments, so feel free to restrain yourself from actually using that feature for the time being…

Let’s look at some code, instead. That’s where the fun is, after all!

Nested resources is a new thing for me. I have been aware of the concept since Rails went the REST way, but I haven’t actually tried it. Turns out, it was really easy…

I wanted to nest the Comment resource as a sub resource to Post. This makes the URLs look like “/posts/7/comments/14”, which is referring to the comment with id 14 belonging to the post with id 7. Fairly intuitive. (Not that it matters in the slightest — I don’t even expect to show the URL for individual comments anywhere, but there you go…)

First step is to define the routing. This was as easy as adding a parameter to the existing route for posts:

  map.resources :posts, :has_many => :comments

Next, I want to use the fact that the Post is known for all actions in the controller (since it is implied in the URL). Therefore, I add a “before filter” that gets the Post instance and saves it in an instance variable (@post) for later use in the action methods:

class CommentsController < ApplicationController
  before_filter :load_post

  # all the action methods here...

  protected
  def load_post
    @post = Post.find(params[:post_id])
  end
end

Finally, we must remember to specify the post as well as the comment for all helper methods for comment. For example, instead of a method comment_path(@comment) like we would have for a non-nested resource, we use: post_comment_path(@post, @comment).

One other thing: I wanted to have the whole comments thing ajax based. This is almost trivial in Rails. Form handling consists of using the helper remote_form_for() instead of the conventional form_for()

Handling the ajax response is more fun! I decided to try RJS since that was another piece of technology I hadn’t used yet. RJS means that we can write simple Javascript code in pure Ruby. I.e. we write Ruby and Javascript is generated.

RJS can be used both on the client side (in views) and on the server (in controllers). When using it in controllers, Javascript is generated as response to a request (most likely an ajax request) and then run on the client.

  def create
    @comment = Comment.new(params[:comment])
    @comment.post = @post
    
    if validate_recap(params, @comment.errors) && @comment.save
      render :update do |page|
        page[:comment_form].visual_effect :fade, :duration => 0.3
        page.insert_html :bottom, "comments", :partial => "comment", :locals => {:comment => @comment}
        page.replace_html "comments_count_info", :partial => "posts/comments_count_info", :locals => {:comments => @post.comments}
        page[:comments_count_info].visual_effect :highlight, :duration => 4.0
        page["comment_#{@comment.id}".to_sym].scroll_to
        page["comment_#{@comment.id}".to_sym].visual_effect :highlight, :duration => 4.0
        page[:form_hide_link].hide
        page[:form_show_link].show
      end
    else
      @comment.errors.add_to_base "Unable to save comment. Please try again later."
      render :update do |page|
        page.replace_html "form_errors", @comment.errors.full_messages.join("<br/>")
      end
    end
  end

What’s interesting with this technique is that I can update several elements on the page just with a few lines of Ruby code on the server. What I’m not totally convinced about yet is that if it’s a good thing to be able to do or not… It very tempting to trigger visual effects and similar things that feels wrong to do on the server. Not for the MVC purists, so to speak. (As you see in the code above, I’m not a purist. Also, this was my first foray to the RJS world and hopefully it’s more obvious to me how it should be used optimally in the future.)

 

Paginating

Published 2008-07-19 by Robert Burén
Tags: blog.rb, feature, pagination, plugin, will_paginate

Ok, Pagination has been in place a few days now, but since I have it set to display ten posts per page, it’ll be a while before it is apparent on this page.

Adding it was simple: installing the will_paginate gem and adding this line of code in Blog#show:

    @posts = @blog.published_posts.paginate :page => params[:page], 
    :per_page => 10

Finally, one line in the view adds the actual pagination UI, if needed:

<%= will_paginate @posts %>