articles tagged with subdomains

Configuring subdomains in development with lvh.me

3 comments

I do a lot of work with subdomains, managing them locally on my development and test machines has always been a bit of a pain. Going way back, I can remember manually editing the hosts file in system32\drivers\etc\ on Windows! On the Unix we have /etc/hosts.

Unfortunately /etc/hosts doesn’t allow wildcard definitions for subdomains, so you have to manually specify each one. For a while I used this simple bash script to append a new domain (or subdomain) to the /etc/hosts file;

#!/bin/bash

SUBDOMAIN=$1
TLD=$2

if [ $# -lt 1 ]
then
  echo "which subdomain?"
  read SUBDOMAIN
  if [ -n "$SUBDOMAIN" ]
  then
    SUBDOMAIN="$SUBDOMAIN."
  fi
fi

if [ $# -lt 2 ]
then
  echo "which tld?"
  read TLD
fi

echo "127.0.0.1 $SUBDOMAIN$TLD" >> /etc/hosts
echo "OK, added 127.0.0.1 $SUBDOMAIN$TLD to /etc/hosts"

Save this script as executable somewhere in your PATH, call it something like addhost then run it from anywhere like so;

> addhost # will prompt for subdomain, tld (leave blank for no subdomain)
> addhost www test.com

This soon became tiresome, with some apps requiring 10’s or 100’s of subdomains to be tested and available locally. So I took to writing a simple rake task that would automatically pull subdomain names from an applications database and append them to my local /etc/hosts file (here’s that script).

Time passed and my script worked well, but had a some disadvantages. I had to re-run it every-time my subdomain data changed, and across apps it required modified since I had different ways and means of defining subdomain sites.

Enter the most excellent suggestion from Tim Pope. Using DNS to solve this problem means no more hassle! He set up a localhost wildcard, pointing *.smackaho.st at 127.0.0.1. Essentially this means that [anything].smackaho.st will point to your local machine. Not happy with smackaho.st? lvh.me does the same thing (lvh, as in local virtual host). Or since most developers have a couple of old domains lying dormant, why not use one for this? I learned of Tim’s technique through the Subdomains in Rails 3 screen-cast from Ryan Bates.

So I think that wraps up all my posts on subdomains, whats that? four now!? Here are the other three.

January 10, 2011 17:54 by

Suggest subdomain names

no comments yet, post one now

Following on with subdomains, say you want one field to auto-suggest into another. For example, when a user enters their company name (or username, last name etc.) this same value could be used to suggest a valid subdomain. Here’s the javascript and html (the function uses prototype for the element lookup).

The suggestion is based on the facts that valid subdomains should be alphanumeric, with dashes, less than 63 chars and not start or end with a dash.

<label for="username">Username</label>
<input id="username" onkeyup="suggestSubdomain(value, 'subdomain');" type="text" name="username" /><br/>
<label for="subdomain">Subdomain</label>
<input id="subdomain" type="text" name="subdomain" />

<script type="text/javascript">
  function suggestSubdomain(value, element) {
    var subdomain = value.gsub(/\s+/, '-');
    subdomain = subdomain.gsub(/[^a-z0-9\-]/i, '');
    if(subdomain[0] == '-')
      subdomain = subdomain.substr(1, subdomain.length)
    if(subdomain[subdomain.length-1] == '-')
      subdomain = subdomain.substr(0, subdomain.length-1)

    $(element).value = subdomain.substr(0, 63).toLowerCase();
  }
</script>
November 07, 2010 21:42 by

Rails 3 subdomain validation (ActiveModel::EachValidator)

4 comments

# subdomain_validator.rb (place in your lib/ or extra/ load path)
class SubdomainValidator < ActiveModel::EachValidator
  
  def validate_each(object, attribute, value)
    return unless value.present?
    reserved_names = %w(www ftp mail pop smtp admin ssl sftp)
    reserved_names = options[:reserved] if options[:reserved]
    if reserved_names.include?(value)
      object.errors[attribute] << 'cannot be a reserved name'
    end                                              
    
    object.errors[attribute] << 'must have between 3 and 63 letters' unless (3..63) === value.length
    object.errors[attribute] << 'cannot start or end with a hyphen' unless value =~ /^[^-].*[^-]$/i                                                                                                    
    object.errors[attribute] << 'must be alphanumeric; A-Z, 0-9 or hyphen' unless value =~ /^[a-z0-9\-]*$/i
  end
end

# And in your model
validates  :subdomain, :presence   => true,
                       :uniqueness => true,
                       :subdomain  => true

# Or with your own reserved names
validates  :subdomain, :presence   => true,
                       :uniqueness => true,
                       :subdomain  => { :reserved => %w(foo bar) }

For more on creating custom Rails 3 validators, check our Ryan Bates’s screencast on the topic.

← (k) prev | next (j) →