multiple robots.txt file for multiple domains in nginx 03 Jul 2010
Tags: nginx, robots, multiple domains

If you're using nginx and need to use different robots.txt file for different domains, then just follow the following examples.

plain
server {
  listen 80;
  server_name example.com www.example.com;
  root /var/www/example.com/public;
  passenger_enabled on;
  rails_env production;

  #this one uses robots.txt so we don't need to add an alias
}

server {
  listen 80;
  server_name sample.com www.sample.com;
  root /var/www/example.com/public;
  passenger_enabled on;
  rails_env production;

  location /robots.txt {
    alias /var/www/example.com/public/sample_robots.txt;
  }
}

multiple image upload with preview using ajax and jquery 04 Jul 2010
Tags: paperclip, preview, ajax, jquery, multiple image upload

In this tutorial, we will use jquery to upload multiple images using ajax and show a preview of the images. We'll also use the paperclip gem to store the files. You can look at how to add paperclip to your project .

First we generate the image model and set it to use paperclip. We'll also create a photo controller

plain
>> script/generate model photo
>> script/generate paperclip photo photo
>> rake db:migrate
>> script/generate controller photos
ruby
# app/models/photo.rb
class Photo < ActiveRecord::Base
  has_attached_file :photo
end

Next, we setup the view and javascript for ajaxupload.

Again, I'm using haml instead of erb templates, and builder for creating DOM elements.

And since we're using prototype and jquery in the same page, we need to make sure that there's no conflict between the two libraries. Add the following code in the head tag of your page.

ruby
= javascript_include_tag :defaults
= javascript_include_tag 'builder', 'jquery-1.4.2.min', 'ajaxupload'

:javascript
  var $j = jQuery.noConflict();

And here's the view

ruby
# app/views/photos/new.html.haml
- form_tag photos_path, :method => :post do
  #photos
  #file_upload
    %label Add a Photo
    = file_field_tag :photo, '', :id => 'file_tag'
    = image_tag '/images/spinner.gif', :id => 'spinner', :style => 'display:none'
    = submit_tag 'Save Photos'

:javascript
  $j(document).ready(function(){
    new AjaxUpload('file_tag', {
      action: '/photo_preview?authenticity_token=' + encodeURIComponent(#{form_authenticity_token.inspect}),
      name: 'image',
      onSubmit: function(file, extension) {
        $('spinner').show();
      },
      onComplete: function(file, response) {
        $('spinner').hide();
        show_preview(response);
      }
    });
  });

  function show_preview(path) {
    var parent = Builder.node('div', {class:'preview'});
    var image = Builder.node('img', {src:path, width:'80px'});
    var hidden = Builder.node('input', {type:'hidden', value:path, name:'photo[]'});

    parent.appendChild(image);
    parent.appendChild(hidden);
    $('photos').appendChild(parent);
  }

Now we need to create the photo_preview and create action in photos controller

ruby
# app/controllers/photos_controller.rb
# of course, this code won't work if the user uploads different photos with the same filename
def create
  photos = params[:paths].collect {|p| {:photo => File.new('public' + p)}}
  @photos = Photo.create(photos)
  # now do whatever you wish with @photos
end

def photo_preview
  if params[:image]
    filename = params[:image].original_filename
    path = '/images/' + filename
    f = File.new('public' + path, 'w') {|f| f.write params[:image].read}
    render :text => path
  end
end

tag cloud using wp-cumulus 06 Jul 2010
Tags: tag cloud, wp-cumulus, swf, wordpress

This tutorial is derived from the wp-cumulus plugin of wordpress. You can see the implementation on the sidebar.

First, download the wp-cumulus archive at wordpress.

Copy the tagcloud.swf to the public directory

Also, be sure to include the swfobject javascript file on the head tag.

Then for every page that you want to place your tag cloud, add the following code. Be sure to have a div with an id 'flashcontent' or change the parameter of the last line in the script below to whatever id you want.

haml
:javascript
  var so = new SWFObject("/tagcloud.swf", "tagcloud", "180", "180", "7", "#336699");
  so.addParam("wmode", "transparent");
  so.addVariable("mode", "tags");
  so.addVariable("distr", "true");
  so.addVariable("tcolor", "0xd2691d");
  so.addVariable("tcolor2", "0x555555");
  so.addVariable("hicolor", "0xffffff");
  so.addVariable("tagcloud", "#{Tag.counts.collect {|tag| "<a href="#{tag_url(tag.name)}">#{tag.name}</a>"}.join}");
  so.write("flashcontent");

As you can see, the second-to-the-last line of the script is where we create the tag links. I'm using acts_as_taggable_on_steroids plugin to manage my tags. But as long as you can create a method that returns a concatenated array of tags, that should be fine.

Google Chrome extensions for Webmasters 07 Jul 2010
Tags: google chrome

I've found an interesting article for web developers using google chrome :D

301 redirect with nginx 03 Jul 2010
Tags: nginx, 301 redirect, www domain

If you need to redirect your urls to use the www domain, then it's easy to do a 301 redirect if you're using nginx

plain
server {
  listen 80;
  server_name example.com www.example.com;
  root /var/www/example.com/public;
  passenger_enabled on;
  rails_env production;

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

One of the important reasons why you need to do this is analytics. Google, for example, sees www.example.com and example.com as two different sites. So to have a more accurate report on your site traffic, use a 301 redirect.

EDIT:

Apparently, this is not the best way to write a 301 redirect in nginx. Have a look at this page to see how to do this elegantly.