The circuit shown below is the programmer I use - the top circuit is basically a pair of voltage regulators, which I run off a 13.8v DC bench power supply. It produces a high 12v (+v1) to power up the MCLR line on the PIC during programming, and 5v (+v2) to power the PIC up and drive the data / clock lines. SK2 is the 25-way D-type parallel port on the back of your PC.
Obviously it's a really stupid idea to solder the PIC your programming into the programmer, so I've used a ZIF socket to plug the PIC into - trust me, you'll be swapping the PIC in and out of that socket a lot, don't just buy a standard, cheap and nasty IC socket!
I crimped myself an IDC DIL header that can be inserted into the ZIF socket. On all my circuits I put a header on the board wired up for in-circuit programming. That way, instead of swapping the chip around all the time, you clamp the DIL header into the ZIF socket and plug the other end of the cable into your in-circuit programming header on your board - just make sure you unplug the programmer from the programming header before powering up the circuit (and make sure you get your in-circuit programming components right so you don't end up pumping 12v into the rest of your circuit. A diode in the right place on the MCLR line does the trick).
Once you've got the programmer built, try it out by writing some simple code to make some LEDs flash and try programming a PIC. I use gpasm to assemble my code, and a hacked around version of Brian Lane's picprg to actually do the programming.
You can set up picprg really easilly from it's menu-driven interface, but so you can check you've got it roughly right, my ~/.picprgrc file looks like:
# Linux PIC programmer configuration v2.0 port=1 vpp=-5 vdd=-4 clock=-3 datao=-2 datai=-10 idaddr=2000 eeaddr=2100 cfaddr=2007 colors=1
Note: picprg 2.3 doesn't work for me - use picprg 2.2 instead.