301 redirect with more than 1 alias in nginx 11 Jul 2011
Tags: nginx, config

Usually, companies acquire multiple domains and point them to one application. In these cases, the company would want to use a 301 redirect to change the url to the one they want indexed by search engines.

In nginx, you can do a 301 redirect by following my other post. It would've been easy if "if" blocks in nginx support conditional operators like || or && (in most programming languages).

To get around this, we use the set command to set a value to a variable, and set that variable's value if the host matches one of the alias. To better illustrate, suppose we're given 4 domains:

plain
www.example.com
example.com
www.example.org
example.org

If the domain we want indexed by search engines is www.example.com, then our config file should look like

plain
server {
  listen 80; 
  server_name www.example.com example.com www.example.org example.org;

  set $my_var 0;
  if ($host = 'example.com') {set $my_var 1;} 
  if ($host = 'example.org') {set $my_var 1;}
  if ($host = 'www.example.org') {set $my_var 1;} 

  if ($my_var = 1) {
    rewrite ^/(.*)$ http://www.example.com/$1 permanent;
  }
}

haml adds spaces to pre tag text elements 11 Jul 2011
Tags: haml, pre, syntax highlighter

While migrating this blog to rails3, I've decided to add syntax highlighting to the codes included in the blog. I've followed Ryan Bates' screencast but used Coderay to manage the syntax highlighting (mainly because I like the default colors) instead of Albino. But I've had problems with the html returned by Coderay or Albino. The html makes the succeeding lines of a multiline code tabbed by around 8 spaces, like the following

ruby
Class Foo
          def method_one
          # do
          # something
          # here
          end
        end

I debugged for hours on why this is happening but I can't figure it out. So I downloaded the source code of the screencast and tried to run it. It, of course, works. So I started editing the source code.

Since I'm a big fan of haml, I converted the application layout to haml. That's when the spaces appeared. And then I knew that the cause of the formatting issue was haml.

Looking at the haml docs, I found out that I should use the ~ operator to preserve whitespace. And that's what I did. Before the code looks like

haml
%div= post.body

The code after should be

haml
%div~ post.body

loading image in a dialog box using jquery ui via ajax 15 Jul 2011
Tags: ajax, jquery, jquery ui

In the current app I'm working on, users can upload images. These images should be previewed in a dialog box. Since we're using jquery ui, I had to use the dialog widget to show the image.

In a single page, there can be unlimited number of images. So instead of creating a dialog for each image, I created a single dialog and just load the images via ajax.

This should be pretty straightforward but the user experience isn't good specially when it takes so much time loading the image via ajax. So to make the user experience better, follow the steps below.

Assuming we used paperclip to upload the images, we can have an Image class declared as follows (we'll go with the least options).

ruby
class Image < ActiveRecord::Base
  has_attached_file :data, :storage => :filesystem
end

Then in the view template, create the div that will hold the image and the links to the images. We'll also add a loading image beside the link to show the users while we load the image.

haml
#attached-image-dialog
  %img{:src => ''}

= link_to image.data_file_name, image.data.url, :rel => 'dialog'
= image_tag '/images/spinner.gif', :style => 'display:none;'

Then add this script

javascript
$('a[rel="dialog"]').live('click', function() {
  var link = $(this),
      spin = link.next(),
       url = link.attr('href'),
     field = $('#attached-image-dialog'),
       img = new Image();

  spin.show();
  img.src = url;
  img.onload = function() {
    spin.hide();
    field.children('img').attr('src', url);
    field.dialog('option', 'title', link.text()).dialog('open');
  }   
  return false;
});

$('#attached-image-dialog').dialog({
  autoOpen: false,
  modal: true,
  draggable: false,
  resizable: false,
  width: 'auto',
  height: 'auto',
  show: 'fold',
  hide: 'fold',
  buttons: {"Close": function() {$(this).dialog('close');}}
}

What the script does is load the image in a variable. After loading the image, we fire up the dialog and change the img tag's src attribute to point to the image's url. We also update the dialog's title with the link's text which is the image's filename.