Develop Multiple Websites by Adding Hosts File Entries

Background

I work on multiple websites. My workflow goes like this:

  1. Pull latest changes into my local repository (I use Git)
  2. Make changes
  3. Test changes on locally running web server
  4. Push changes to remote repository
  5. Pull changes into live site

The Problem

Webpages are complex. They source external scripts and stylesheets. What if a script is linked relative to the site root? If I put the site in a directory and access it at http://localhost/worksite, the link will break. The fix is obvious: put the site in the root, http://localhost/. But, as I said, I work on multiple sites. I guess I could run each site on a different port, but that’s gross.

My Solution

Used named virtualhosts and add hosts file records for them. So add a record like

127.0.0.1 worksite

to /etc/hosts (%SystemRoot%\system32\drivers\etc\hosts in Windows). Then add a virtualhost to your web server. In nginx, create a new site that looks like this:

server {
  listen worksite:80;
  server_name worksite;
  location / {
    root /home/force/web/worksite;
    index index.html;
  }
}

In Apache, your new site looks something like

<VirtualHost *:80>
  ServerName worksite
  DocumentRoot /home/force/web/worksite
</VirtualHost>

Restart your server, and you can access your site by going to http://worksite/. Simple and clean.

Posted in workflows | Tagged , , , , , , | Leave a comment

Vim up your Bash

Are you a CLI ninja? I write a lot of single-use, throwaway scripts in Bash. Usually, it’s an iterative process. But editing a long one-liner in Bash can be cumbersome if you’re also a Vim or Emacs ninja. So here’s a trick to pop that command that you’re working on into your default editor (Vim, in my case).

vi-style invocation

  1. If you haven’t already, add set -o vi to your .bashrc file so that every Bash instance uses vi-style editing.
  2. With the command you want to edit displayed, press ESC CTRL-\ v (lowercase v; press in order, not simultaneously).
  3. (Optional): As suggested by Jeet Sukumaran, you may want to add a keyboard shortcut for this. Append the following to your .bashrc to bind this behavior to CTRL-V:
# Ctrl-v: (insert mode) switch to command mode and edit in vi
bind '"\C-v": "\ev"'

Emacs-style invocation (Bash default)

  1. With the command you want to edit displayed, press CTRL-X CTRL-E (in order, not simultaneously).

Run the command (or don’t)

Either way, when you quit your editor, the modified command will be run by Bash. If you don’t want to run the command, quit without saving (:cq in Vim, CTRL-X CTRL-C in Emacs).

Posted in CLI | Tagged , , , , , | Leave a comment

Vendor-Specific CSS Attributes Are a Good Thing

A friend of mine and I just had a pretty heated discussion about whether it’s OK for browser vendors to implement technologies that are not yet finalized standards. I criticized Opera for pushing for standards compliance while following IE in some places where it diverges from standards; he criticized Firefox and Chrome for implementing technologies that are not yet standard like the <canvas> tag and border-radius:. He further claimed that Opera was not guilty of half-ass implementation of not-yet-ready standards.

Today, he emailed me the following:

This is where opera snapshots and changelogs are announced.

But before I continue, I just have a quick note regarding the addition of object-fit and object-position from the CSS3 Paged Media Module properties in the previous 10.70 snapshot: These are currently only supported with the -o- prefix, but we recommend that you also add them without the prefix as well if you choose to use them on a page.

Those fuckers, they made us both wrong (wronger in my case)!

I Googled, and it looks like the aforementioned attributes are for breaking media over pages, like in printing, iPad viewing, or arc90′s Readability project which made it into desktop Safari. In Opera, you have to invoke these new rules with -o-.

But it’s OK! The -vendor-attribute: value; syntax is how browser vendors posit implementations of proposed or incomplete standards. See also gradient fills:

background: #999; /* for non-css3 browsers */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#000000'); /* for IE */
background: -webkit-gradient(linear, left top, left bottom, from(#ccc), to(#000)); /* for webkit browsers */
background: -moz-linear-gradient(top, #ccc, #000); /* for firefox 3.6+ */

These things are standards, but the implementation has been left up to the browser vendors to find and agree on the best syntax. When the best method is found, they’ll collapse their implementations into a single syntax, like text-shadow:, border-radius:, and : rgba(). So in CSS3, you should be able to make rounded-corner boxes with gradient fills that use alpha transparency.

I know that this stuff sounds gross and unappealing to some of us (like my friend), but I also know that most of us are grateful for these upcoming changes. :)

Posted in editorials, standards | Tagged , , , , | Leave a comment

Keep Page Elements the Same Height with jQuery

Many times I have wanted to keep multiple elements on a page the same height. You can use CSS’s display:table and its friends for this, but it doesn’t work very well in IE. You can add conditional tags for IE, but then your markup starts to look awfully dirty. If the effect that you’re striving for is purely an aesthetic enhancement, you can just use JavaScript to take care of it simply and cleanly. It won’t work if your clients have turned of JavaScript, but if they’re using IE, they probably don’t tinker much under the hood. :)

Here, I’ve implemented a small jQuery extension to allow you to specify that a set of page elements should remain the same height, even as the page is resized.

Note that this only resizes page elements when the window resizes. So if you’re loading content dynamically, you should call $(window).resize() afterwards to re-fit everything.

Implementation

/*
* jquery.sameheight.js v1.1
* http://github.com/justinforce/jquery-sameheight
*
* Copyright 2011, Justin Force
* Licensed under the MIT license
*
* Set selected elements to the same height as the tallest element in the
* selection. Automatically adjust on $(window).resize()
*/


/*jslint browser: true, white: true */
/*global jQuery */

(function($) {

'use strict';

// add Array.indexOf if it isn't defined
if (!Array.indexOf) {
  Array.prototype.indexOf = function(obj) {
    var i, len = this.length; // for loop vars

    for (i = 0; i < len; i += 1) {
      if (obj === this[i]) {
        return i;
      }
    }
    return -1;
  };
}


// Set all selected elements to the same height
$.fn.sameHeight = function() {

  var these = this; // for use in nested function

  // Set the resize listener, then trigger resize to set height immediately.
  // First set all heights to auto or they will grow when the window resizes.
  // Find the max height by comparing all of the elements, then set the height
  // of the selection
  $(window).resize(function() {
    var max = 0;
    these.height('auto').each(function() {
      max = Math.max(max, $(this).height());
    }).height(max);
  }).resize();

  return this;
};


// Set everything with class="sameheight sh_something" to the same height
$.sameHeight = function() {

  $('.sameheight').each(function() {
    var selectors = [], // array of the "sh_X" class names
    match;              // all elements with className sh_[something]

    match = $(this).attr('class').match(/(sh_\S+)/);
    if (match && match[1] && selectors.indexOf(match[1]) < 0) {
      selectors.push(match[1]);
    }

    $.each(selectors, function() {
      $('.' + this).sameHeight();
    });
  });
};

}(jQuery));

Example Usage

So now, as before, simply add the appropriate classes to your elements. For example, say I have 3 columns that I want to be the same height, and 2 other elements that I want to be a different height. You have to add the sameheight class to each of these elements, and then a grouping class beginning with sh_ to the others. For example, you could call your 3 columns sh_nav and your 2 columns sh_content. The resulting code would look something like

<!DOCTYPE html>
<title>jquery.sameheight demo</title>

<style>
 
  div, p {
    overflow: auto;
    margin:2px;
    padding:2px;
  }

  #nav, #content, #someParagraphs {
    width:500px;
    clear:both;
  }

  .sh_nav {
    float:left;
    width:30%;
    border:1px solid #00c;
    border-radius:7px;
  }

  .sh_content {
    float:left;
    width:45%;
    border:1px solid #c00;
    border-radius:10px;
  }

  #someParagraphs p {
    float:left;
    width: 20%;
    border:1px solid #0c0;
  }
</style>

<div id="nav">
  <div class="sameheight sh_nav">Some content</div>

  <div class="sameheight sh_nav">
    Some more content
    Some more content
    Some more content
    Some more content
    Some more content
    Some more content
  </div>

  <div class="sameheight sh_nav">Some similar content</div>
</div>

<div id="content">
  <div class="sameheight sh_content">
    Other content
    Other content
    Other content
    Other content
  </div>

  <div class="sameheight sh_content">Other content</div>
</div>

<div id="someParagraphs">
  <p>A paragraph
  <p>
    A much, much longer paragraph that goes on and on and on and on and on and
    on and on and on and on and on and on and on and on and on and on and on...
  <p>A short paragraph again
  <p>
    Some kind of unexpected medium-sized paragraph that doesn't go on so long
    as the second one.
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jquery.sameheight.js"></script>
<script>
$(function() {

  $.sameHeight();

  // I'll set them to the same height, then turn them blue to show that jQuery chaining still works.
  $('#someParagraphs p').sameHeight().css({color: 'blue'});

});
</script>

This will produce 3 columns of the same height, then, below them, 2 columns of the same height, then 4 paragraphs of the same height, as in the image below.

divs and paragraphs being adjusted with jquery.sameheight.js

It’s not the prettiest application, but you get the idea.

Posted in jquery, scripts | Tagged , , , | Leave a comment

Print Special Characters in Ubuntu

I was recently trying to send an email with the word résumé in it, but I couldn’t get my keyboard to input the characters I wanted without bringing up a character map. Here’s how you get your keyboard to print these characters for you.

Open System → Preferences → Keyboard (or run gnome-keyboard-properties) and click the Layouts tab, then click Options…. Under Compose key position, select an appropriate key. Right Alt works for me. Click Close then Close.

Now you can insert accented characters by holding Right-Alt and pressing a key, then a modifier, such as Right-Alt + u, then (single quote) to get ú or Right-Alt + n, then ~ (tilde) to get ñ.

¿Nət, rīt?

Posted in input, ubuntu | Tagged , , , , | Leave a comment

Easily Back Up Windows with Ubuntu Live

On the job over the past couple years, I’ve developed a really solid workflow for backing up Windows computers quickly and reliably. It’s so fast and easy that we make full system backups before we attempt any potentially destructive job such as malware removal or a Windows Repair Install.

(Note: In some cases, it is helpful to defragment your filesystems before you begin. See the bit below on ntfsresize to find out whether this applies to you.)

First, you need a bootable Ubuntu Live distribution. I recommend using a USB flash drive if you can, as it boots and loads programs sooo much faster. But a CD works just as well (and more universally). Download an Ubuntu ISO. Don’t try to get fancy. The most universally compatible and useful version is the 32-bit Desktop edition. Now either burn the ISO to a CD or set up a USB flash drive. If you can, use Ubuntu’s own USB Creator for this. If you’re not running Ubuntu, use Unetbootin.

Boot

Boot from the CD or USB media that you made. You’re probably going to need to install something, so ensure that you have a network connection and

sudo apt-get update

Set Up a Backup Destination

You need a destination for your backup. You can use another hard drive, some USB-attached storage, or a network location. If you don’t know what backup media to use or how to format and mount it, try Googling it. This page may also help. (Tip: Use cfdisk, not parted, fdisk, sfdisk, etc. Partition type 07 for NTFS, 82 for ext. Don’t use FAT32.)

If you’re going to use Samba (Windows share), the command looks something like this:

sudo apt-get install -y smbfs
sudo mount //server/share /mnt -ousername=yourname

If you’re going to use NFS, the mount command looks something like this:

sudo apt-get install -y nfs-common
mount server:/path/to/export /mnt

Now I’m going to assume you got through all of that, and your backup target is mounted on /mnt.

Get ntfsprogs

In Ubuntu 9.10, ntfsprogs is present on the Live distribution. If you don’t have it, you need to

sudo apt-get install -y ntfsprogs

Backup

For all of the following, I’m assuming that you’ve mounted your backup target to /mnt and your backup source is /dev/sda. If this isn’t true, adjust accordingly. If it is, you can mostly copy and paste these commands.

cd /mnt

Back up your partition table (-l lists the partitions and -d writes a format that can be piped directly back into sfdisk. Super convenient.)

sfdisk -ld /dev/sda > sda.sfdisk

At this point, you can choose to shrink your NTFS filesystems before you back them up. They won’t occupy any less disk space–ntfsclone does a filesystem-aware block copy that doesn’t use space for unused blocks. The benefit of doing this is that it does enable you to restore the filesystem to a smaller partition in the future.

Resize the Filesystem (optional)

First, get an estimate of the space you can save

sudo ntfsresize -i /dev/sda1

Look for a line resembling this:

You might resize at 42704896000 bytes or 42705 MB (freeing 3965 MB).

ntfsresize can handle a finite (and kind of small) amount of extents, or file fragments. If your filesystem is fragmented, you can’t reclaim as much space. You may want to defrag (from within Windows) before you get started.

So make several dry runs until you find a resize that works. Try

sudo ntfsresize -n -s 42706M /dev/sda1

If you get something like

ERROR: Extended record needed (3696 > 1024), not yet supported!

Run it again. Just bump the size up by 100M or so at a time until it says

The read-only test run ended successfully.

Then run it again without the -n, like

sudo ntfsresize -s 43706M /dev/sda1

Back to the Backup

Finally, back up your NTFS partition(s):

sudo ntfsclone -s -o sda1.ntfsclone /dev/sda1

Repeat, substituting 1 with the number of the partition for each NTFS partition.

That’s it!

Restoring

If you were to now start from scratch with a similar disk, you would cd into your backup directory and run

sudo sfdisk /dev/sda < sda.sfdisk
sudo ntfsclone -r -O /dev/sda1 sda1.ntfsclone
sudo ntfsresize /dev/sda1 --force

And you’re fully restored. Neat, huh?

You can do something similar with other filesystems using tools like partimage, and you can rescue data from damaged filesystems and disks using GNU ddrescue. Google it.

Posted in tutorials | Tagged , , , , , , , , , | Leave a comment

DIY USB Wii Sensor Bar

I recently connected a PC to my TV and decided that it would be cool if I could use my Wii remotes with it. I’ll spare you the details of getting my Wii remote to act as an input device (mouse) with my Ubuntu computer. Let’s get right to the part where I used solder and duct tape to make a Wii sensor bar that does not require my Nintendo Wii to be turned on!

Well, I already knew that the Wii Sensor Bar is really just two points of infrared light which the camera in the Wii remote reads to determine its position in space. So all I really needed for this hack was 2 points of infrared light and a power source! For my purposes, USB was ideal. No changing batteries, no power switches, no wall warts. When my HTPC is on, this sensor bar is plugged in and ready to go! So I started with the math/science.

My power source is 5 V DC. My multimeter told me that my donor IR LEDs (taken from 2 spare remote controls) drew 1.5 V at 2 mA. I see a 3 V draw with a 5 V power supply, so we need a resistor. So, we invoke Ohm’s Law.

V = IR

So, resistance is voltage over current. So,

5V - ((1.5V per LED) × (2 LEDs)) = (20mA max current) × R

So,

2V = 20mA × R

So,

R = 2V / 20mA = 100Ω

So I found a 100Ω resistor (help with color codes), and I was ready to wire my circuit. The diagram looks like this:

DIY Wii sensor bar wiring diagram

DIY Wii sensor bar wiring diagram

Remember that the flat side of the LED is your anode (+) and the round side is your cathode (-).

So from here, I took a donor USB cable and soldered the red (+5 V) wire to the anode leg of my first LED, then soldered the cathode leg of the first LED to a wire to the anode leg of my second LED, then soldered the cathode leg of my second LED to my 100Ω resistor, then soldered the other leg of my resistor to a wire, then soldered the end of the wire to the black (GND) wire of my USB cable. I just taped off the additional 2 wires of the USB cable to prevent any shorts. Then I stuck the LEDs through a scrap of cardboard at approximately the same distance apart as the LEDs on the original Wii censor bar, and taped the whole thing shut. It looked like this (components and solder joints highlighted in red).

Inside of DIY Wii sensor bar showing wiring

Inside of DIY Wii sensor bar showing wiring

And here it is all closed up and ready for action under my TV.

DIY Wii Sensor Bar

DIY Wii Sensor Bar

And here it is in the same position with the lights off, my infrared-sensitive camera showing the points of light which the Wii remote can see, but I cannot.

DIY Wii sensor bar in the dark

DIY Wii sensor bar in the dark

And that’s it! I plugged it all in, and it works great! My USB Wii sensor bar works well with my Nintendo Wii and as a wireless pointing device for my HTPC.

So, to summarize, my list of parts:

  • Any USB cable with a standard “USB-A” plug
  • 2 IR LEDs. I took mine from disused remotes for a PlayStation 2 and a TV, but you can find them in all kinds of old remote controls or buy them online. They typically consume 1.5 V and tolerate 20 mA.
  • A 100Ω resistor. I had one lying around. You may want to buy this online. Remember that your resistor value will vary depending on your power source and the number of LEDs you use! LED center has a calculator and will even draw you a diagram.
  • Some wire. I pulled mine from a dismantled 40-pin IDE cable, but almost any wire will work.
  • Soldering tools
  • A scrap of cardboard.
  • Some duct tape.

Happy hacking!

Posted in hacks, input, wii | Tagged , , , | Leave a comment

A Day with HTML 5 -or- I Can’t Believe It Validates!

I just spent some time with HTML5. To be more specific, I just rewrote my favorite Rails app in HTML5. It was like a dream! It took me back to a simpler time… When you can reduce this:

<div id="footer">
  <table id="summary">
    <tbody>
      <tr>
        <th>Row1</th>
        <td>Fun stuff</td>
      </tr>
      <tr>
        <th>Row2</th>
        <td>More stuff</td>
      </tr>
    </tbody>
  </table>
</div>

to this:

<footer>
  <table id=summary>
    <tr><th>Row1<td>Fun stuff
    <tr><th>Row2<td>More stuff
  </table>

you just feel lighter. I’ve been working in XHTML since it became the next big thing. Getting used to all those <br />s took some time, but I eventually got used to it. Getting used to a <tbody> for every <table> and a <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> for every <head> was tough, but I persevered. I didn’t just survive; I thrived! Yes! More rules! More structure! See how Vim indents this automatically? That’s how you know it’s right! All is right with The Web.

Or so I thought…

Enter HTML5. I don’t need a / for that <img>? Cool. I don’t need a </p> for that <p>? I don’t need quotes around my attributes? Now I know you’re messing with me. What? I don’t even need </div>? </body>? </html>?! We’ll just see about this!

So, being a devout and dutiful developer, I paste it into the W3C Validator, and to my astonishment, it validates! It validates! I know! I was shocked, too! It doesn’t just look good in the browser because the browser is making its best guess in quirks mode. It looks good because I have written valid, well-formed code! And it’s not just well-formed; it’s sexy.

Then why did I ever move to XHTML? If I wanted to write web pages the free and easy way, I could have been writing web pages in HTML 4 all this time, right?

I guess so.

The aspects of XHTML that most appealed to me was that its rigid structure required that documents be well-formed, and that the removal of presentation elements like <center> and <font> encouraged writing semantic pages. Then there’s serialization and mashability. If the document is XHTML, it’s XML, and you can import it with Ajax and parse the DOM tree programmatically.

But now I realize that XHTML is not necessary to achieve these things. HTML5 does a better job of encouraging semantic web development with elements like <nav>, <article>, and <aside>. You can still use DOM rules to parse HTML5. Most of all, while XHTML ensures well-formed documents, there’s no reason that you can’t just hold yourself to a higher standard and write good HTML!

So I’m making the switch. And it’s easy! Most of my XHTML 1.0 Strict is valid HTML5. All I really had to do to convert my Rails app was change the DOCTYPE from

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

to

<!DOCTYPE html>

The Rails generated code is still XHTML compliant, but it is also valid HTML5! So while the <br />s and </p>s aren’t necessary, they’re still legal.

Now with my DOCTYPE changed, I’m able to do lots of fun things, like remove superfluous closing tags and attribute quotes and change my div#header and div#footer tags to <header> and <footer> tags.

I’m excited to explore HTML5 more in the months to come as I address other projects. To learn more about HTML5, see some of these links. * Yes, You Can Use HTML 5 via Jens Meiert’s blog * HTML 5 differences from HTML 4 via W3C * How to Learn HTML5 via Kroc Camen

Posted in editorials, html5 | Tagged , , , , | Leave a comment

Swap 2-Finger and 3-Finger Tap in Linux

When I upgraded my netbook from Ubuntu 9.04 to 9.10, I quickly noticed that they had flipped the functionality of 2-finger and 3-finger tapping. I need middle-click (3rd mouse button) functionality far more often than I need right-click, and by default GNOME uses Alt+Middle-Click as a shortcut to resize windows. Doing this with 3 fingers, as well as manipulating links and tabs and dragging objects in my panel is just cumbersome, so I embarked on a Google journey to find out how to swap 2- and 3-finger tap functionality. I found the solution on the Ubuntu Forums.

Just create a script like this:

#!/bin/sh

synclient TapButton2=2
synclient TapButton3=3

You can put this anywhere. I called mine ~/bin/swaptaps. Remember to chmod +x swaptaps. For the best effect, add it as a Startup Application (GNOME menu → System → Preferences → Startup Applications).

My testing shows that this works after rebooting as well as after logging in and out. I haven’t tested this with multiple users on the same machine, so if anybody does, please comment and share your results.

Update: Using this as a login script no longer works reliably. I frequently have to run it manually. I’ve tried adding a delay of a few seconds, and it doesn’t seem to help. It’s possible that the default behavior switched back, and my login script is switching it back. I haven’t tested this theory yet. I’ll update if I do.

Posted in input, ubuntu | Tagged , , , , , , , , , , , , | Leave a comment

Shift + Scroll = Horizontal Scroll in Linux

Firefox kept going back and forward when I used my favorite Shift + mouse wheel scroll combo to try to scroll horizontally. It was driving me mad. After some rigorous googling, I found a Stack Overflow question, which suggested that I install xbindkeys and xautomation, then run xbindkeys at login. I was already doing most of that, so I just installed xautomation and created a ~/.xbindkeysrc.scm file that looks like this:

; bind shift + vertical scroll to horizontal scroll events
(xbindkey '(shift "b:4") "xte 'mouseclick 6'")
(xbindkey '(shift "b:5") "xte 'mouseclick 7'")

Then I restarted xbindkeys and it works! Hooray! Thank you, gfxmonk for the fix!

Posted in input, ubuntu | Tagged , , , , , , , , , , , , , , | 1 Comment