Setting up apache on osx lion

For general website/ PHP development, I like to have multiple local sites running from my Sites folder using virtualhosts. Up until now i’ve usually done this with Xampp, but after hearing that the version of apache shipped with OSX 10.7 is fairly useable out of the box I thought i’d run with it.

First of all I uncommented a couple of lines from /etc/apache2/httpd.conf.

To enable PHP5:-


LoadModule php5_module libexec/apache2/libphp5.so


To enable the use of virtualhosts:-


Include /private/etc/apache2/extra/httpd-vhosts.conf


I can then create virtualhosts in /private/etc/apache2/extra/httpd-vhosts.conf like so:-


<VirtualHost *:80>
DocumentRoot "/Users/rickhurst/Sites/sandbox"
ServerName sandbox.macbook.local
</VirtualHost>


Then to serve a local site from http://sandbox.macbook.local add a line to /etc/hosts:-


127.0.0.1 sandbox.macbook.local


One issue that took me a while to figure out was that I was getting a 403 error when I tried to use AllowOverride All, which lets me use .htaccess

I found the answer here. Basically, the options line needs to be set to “Options All”:-


<Directory "/Users/rickhurst/Sites/">
Options All
AllowOverride All
Order allow,deny
Allow from all
</Directory>


(The above rules are added to a file /private/etc/apache2/users/yourusername.conf). Remember to restart apache after making these changes!

mysql_config not found osx

This always gets me when I try to install mysql-python on osx using pip:-


$pip install mysql-python

(ugly traceback, ending in:-)

EnvironmentError: mysql_config not found


Googling round finds that most people suggest editing a line in MySQL-python/site.cfg (wherever that is..), but my preferred solution is add the following line to my .profile:-


export PATH=$PATH:/usr/local/mysql/bin


This works for me – for a mysql installed from a package on mysql.com

Running Google App Engine SDK on OSX lion

OSX Lion comes with python 2.7 as default. Although App Engine will run on 2.7, it is safer to develop on the version of python that your live app engine instances are running on, which in my case is python 2.5 currently.

From a fresh install of Lion, I did the following:-

Installed xcode via app store

Installed Google App Engine SDK for Python, by installing google app engine launcher (This contains the SDK and a launcher app).

Installed mac ports

In a terminal:-


sudo port -v selfupdate
sudo port install python25
sudo port install py25-pil


This means I can start my django server on python 2.5 using:-


python2.5 manage.py runserver


However if you want to run dev_appserver.py it will still try to use python 2.7 (which, unless you’ve installed it into your default python, will be without PIL)

you can use macports to set the default version of python:-


sudo port select python python25


Finally, you might want to set Python Path to /opt/local/bin/python2.5 in your Google App Engine Launcher preferences

refs:-

http://stackoverflow.com/questions/4868185/how-to-install-pil-on-mac-osx-10-5-8-for-google-app-engine

http://stackoverflow.com/questions/6152765/macports-didnt-place-python-select-in-opt-local-bin

Update: after upgrading google app engine SDK to version 1.6, I was getting an import error “No module named _ctypes”. I have now upgraded to python2.6 and this fixed the issue.

Left the circus, going to work in the Potato field

Potato sign

I’ve mused a few times on this blog about the relative merits of full-time and freelance and what would convince me to go back into a full-time job, but it’s happened. I’m delighted to say that as of December 1st I am a full-time Django Developer, working for Potato, as part of the small (but growing) Bristol team. I’ve been freelancing full-time for Potato since October and have really been enjoying being part of a specialist team, working on interesting projects for interesting clients, using interesting technologies. I’ve learned so much in a short space of time working with talented and supportive colleagues, it’s been extremely enjoyable and satisfying. So when I was offered a permanent contract I was happy to accept – yesterday I went to London to meet my London-based colleagues and founders, and while I was there I signed a contract.

So other than a few existing freelance odds and ends that need handing over, I’m no longer a freelancer and not taking on any new clients or freelance work with immediate effect. My five years of freelance have been one hell of a ride, with lots of ups and downs, but i’m glad I did it, and proud that I made a success of it. Right now i’m looking forward to seeing what lies ahead in the world of potato!

Lost network interfaces in virtual machine

I was having a confusing issue where after moving an ubuntu virtualbox virtual machine I was losing the virtual network adapters (i’m running one on NAT so the machine can access the internet via the host and one host-only so I can network between host and guest). After a bit of head scratching, I realised this was because the way I was “moving” a machine was by copying the hard disk image and creating a new machine. This means that the MAC addresses were getting reset. If I went into the virtualbox machine settings and changed these to the same mac addresses as were being used on the vm before it was moved, the network interfaces reappeared. I guess that’s why I should be moving the machines with the config file too..

Get a list of attributes for a django object

For a queryset:

myobj.objects.filter(foo=bar)
myobj.values()[0].keys()


For a single object instance:-

for field in speaker._meta.fields:
print field.name


Also for a single object instance – returns fields and values as a dict

speaker.__dict__


Iterate through the dict like above:

for k,v in speaker.__dict__.iteritems():
print k,v

Tell us about the browser wars grandpa!

After recently reading this blog post, I was reminiscing about the circuitous route that got me into web development. I’ve given a brief account of this before, but I thought it was worth recounting in detail, as it may be of interest to those looking to get into the field. I also just like to waffle about the olden days…

In 1997 I was newly arrived in Bristol, a recent-ish graduate in Environmental Science, with the compulsory couple of years post-uni experience travelling and doing random jobs, starting life in a new city and wondering what life had in store for me. I started by trying to forge a career in conservation, by juggling voluntary work at a small environmental organisation with a painful part-time job in a call centre to (barely) pay the bills. My job applications were getting me nowhere – although I had a degree, I had very little relevant work experience and I was lucky to receive a rejection letter, let alone an interview. The salt in the wound was getting turned down for a part-time minimum wage admin job at the organisation where I was volunteering (ironically the reason given was “lack of experience with databases”!).

At the time I hadn’t used the internet, I had seen people using it a couple of years previously in the computer lab when I was at university – a classmate showed me a terminal screen displaying a text web page with some jokes on it, and I was severely underwhelmed. So several years had passed with no inclination to use the internet, until someone (I wish I could remember who – I owe them a pint!), suggested to me that if I saved my CV out of MS word as HTML I could upload it to the internet and people might find it and offer me a job. Willing to try anything, after a bit of research (talking to people – remember i’d never been on the internet at this point) I took a trip to PC world and bought a dial-up modem, and picked up a freeserve CD-ROM. That evening I uploaded my HTML CV as the index page of my free webspace, and then surfed the internet for the first time.

Disappointed at the lack of job offers the next day, I bought a graphic design magazine design which came with a CD-ROM containing some HTML website templates. I hacked around with some of them using notepad, though it was all a bit confusing – framesets, javascript rollover images etc. but I was pleased that I was able to work out how to customise the pages and add my own content without needing any specialist software, so I proceeded to create a website for the environmental organisation I was volunteering for, along with a few other personal project sites. I bought a copy of “HTML for dummies” and learned how to create web sites from scratch. I also obsessively studied the HTML source of any site I came across – I wasn’t happy until I understood how it worked.

An interesting thing that happened a few weeks later is that one of my first emails was a complaint from a design agency. When they typed into Altavista the name of the environmental organisation they had just built a website for, the fugly site that I had built came up as number one, but their site didn’t show up at all. I took a look at their version, and when it (eventually) loaded, saw that they had created a “website” that consisted of a single jpeg. I hadn’t submitted my version to any search engines, but I had taken time to contact other environmental organisations who had websites and ask if they would add a link to my site. I did this purely because at the time I assumed you had to pay to get listed on a search engine, so people would only find my DIY site by surfing to it. At this point the penny dropped that although my experience amounted to a few evenings experimentation, I was already ahead of a professional design agency in my knowledge of how the internet works.

In 1998 I got a new temp admin job (ok, it was “receptionist”, but I like to gloss over that) in the computer science dept of a university, where I had access to relatively fast always-on internet. Even though it wasn’t part of my remit, I volunteered to help keep their department intranet up to date and spent most of my time teaching myself HTML and javascript while I pretended to work. I also started experimenting with “paint shop pro”, and voluntarily building websites for friends and colleagues. This job was a massive improvement over the call centre, but I was still pretty much on minumum wage and felt like I was going nowhere. Still at least I had a new hobby..

A few months in I took a life-changing phone call. A cold call from a recruitment agent is the bane of any receptionist’s life, but this one phoned the department asking if we’d stick a notice up asking for graduates with HTML knowledge as he a had a big client looking for several people to start ASAP. I obliged, but also, after some dilemma over whether I was good enough (scarred by constant job application rejection) emailed him a link to my personal website and CV, which now contained some inflated references to my web design experience. A week later I went for an interview. Two weeks later I was the director of a one-man-band ltd company, sitting on a train to Cardiff to start work as a contract “web designer” in a new department of BT.

I suddenly had a career – for the first time ever I was making an acceptable living, and for the first time I had colleagues to swap notes with. Someone taught me how to use layers in photoshop, someone else how to lay out web pages using tables and framesets. The “maverick” of the department demoed some experiments he had been doing with “Cascading Style Sheets”, which could be used on newer browsers such as IE4. We churned out hundreds of terrible, but improving websites giving small businesses their first web presence. We huddled together round a monitor confused and delighted as we stumbled across some of the first macromedia flash websites appearing on the web. HTML was dead we naively decided – we needed to learn flash fast or be become obsolete. Luckily, I was also introduced to using ASP and access databases to create dynamic web sites, and also started experimenting with PHP. The rest is on linked in.

The point i’m laboriously making is that although the techniques have moved on, i’m self-taught and i’m colleague-taught. There were no college courses back then that taught the skills needed because the technology was being constantly invented and reinvented. This isn’t just a history lesson, the technology is *still* being invented and the courses and tutors can’t keep up. The nearest we have now are the workshops run by industry professionals and conferences with talks by industry professionals. But, even then don’t think you’ll be learning anything that you can’t learn from someone’s blog, from studying the source code of their site (for front-end at least, try github for serverside code examples), or from someone you chat to on a mailing list, twitter, IRC channel or forum – the cutting edge layout techniques are being invented and experimented with right now by a fifteen year old in his/ her bedroom, months or years before they will appear in a workshop or conference.

I still have to teach myself new techniques or technologies every time I start a new project, and will continue to keep learning. Despite being in the game for over a decade, I still feel “grateful” that i’ve managed to find something I enjoy doing and can make a living from. I’m aware that I can’t become complacent – even though I don’t jump instantly on every new technique that gets shouted round the twitterverse, i’m aware that I need to keep up with anything pertinent or risk getting left behind. I also freely share my knowledge, via this blog, via twitter, via old-skool mailing lists and forums. I hope it is always this way – new techniques to keep things fresh and the best learning resources are not behind a pay-wall, allowing anyone with the determination and aptitude can pursue a career (or hobby) in web design and/or development.

If you are looking to learn web development, the best you can do is find yourself some free web space and set up a personal sandbox site to experiment and display what you are working on. Set up a blog to document it all. My lucky break came in the early days learning HTML just as there was a “goldrush” for people with HTML knowledge – you may have to aim a bit higher now. The goldrushes are still happening though – right now it seems to be mobile website development, facebook app/page development (shudder) and Drupal development, but who knows what it will this time next year. The point is you will already need to have experience in what employers are looking for, and the person to teach it to you is none other than yourself.

Luckily this is a unique industry where knowledge is shared freely and we all learn from each other. Whilst it my implode into bickering sometimes, we have an active, talkative, web design and development community. If you specialise in a particular technique or technology there are whole thriving sub-communities dedicated to talking about it, having meet-ups and grassroots conferences, discussing it, day by day, hour by hour. Go and find them and get involved!

Swoop Patagonia re-skin 3

screengrab of swoop reskin version 3

Last night Dan Fairs pushed the latest version of the django powered Swoop Patagonia site live. The site has several new content management features created by Dan with the help of Ben Mason allowing swoop staff to create and manage content in a more flexible manner and has been re-skinned (by yours truly) to use a new design created by the talented designer Ming Cheung. Another successful team effort!

Test post from droptext

Just experimenting to see if it is possible to create a blog post on my new eatStatic based blog using droptext on my iphone.

Under the current set-up, if I wanted to use the “drafts” folder, I’d then need to log into dropbox.com to move the file to the main folder, as there is no way of moving files in droptext (as far as I can see)

Inserting an image would also be tedious – I can upload a photo using the dropbox app, but I can’t rename it something suitable, without going to dropbox.com, and then writing HTML on an iPhone is never much fun

I think if I want to consider mobile blogging, I’ll need to build something more convenient, such as an email to blog post script, similar to Posterous and wordpress plugins I’ve seen.

Object storage and retrieval in PHP part 2 – MongoDb

In part one, I talked about how to save and retrieve a PHP object instance using JSON files, and in this post I talk about the same operation using mongoDb, and some gotchas.

I’ve only tried this in very limited circumstances, mainly to see how feasible it would be to make eatStatic seamlessly switch between json files and mongo – I naively thought that you would just throw a json file at mongo and have it store it for you, but the examples i’ve found takes the php object and converts to JSON magically, and also passes back a PHP object instance rather than raw JSON.

This post doesn’t cover installing mongo, I skipped between several different examples/ tutorials before I got it working, so can’t remember exactly how I did it in the end. Once installed though you can connect to it from PHP like this:-


$m = new Mongo(); // connect
$db = $m->cms; // select a database


For comparison purposes we’ll create a simple case study object like in Part 1:-


class case_study {
var $id;
var $title;
var $body_text;
var $skills = array();
}

$case_study = new case_study;

$case_study->id = 'my/case_study';
$case_study->title = 'My case study';
$case_study->body_text = 'Some text for the case study';
$case_study->skills['css'] = 'CSS';
$case_study->skills['sitebuild'] = 'Site Build';


which gives us:-


case_study Object
(
[id] => my/case_study
[title] => My case study
[body_text] => Some text for the case study
[skills] => Array
(
[css] => CSS
[sitebuild] => Site Build
)

)


To store this in mongo db, we simply specify a collection to use (“collection” is analogous to table in a relational database, but you can create them on demand, and don’t have to specify a schema) and them insert our object:-


$case_studies = $db->case_studies;
$case_studies->insert($case_study);


To get it back we use:-


$case_study = $case_studies->findOne(array('id' => 'my/case_study'));


Passing this to print_r() gives us:-


Array
(
[_id] => MongoId Object
(
[$id] => 4e6de720d2db288b0c000000
)

[id] => my/case_study
[title] => My case study
[body_text] => Some text for the case study
[skills] => Array
(
[css] => CSS
[sitebuild] => Site Build
)

)


Note a couple of things:-

  • It has given us back an Array, instead of an object
  • It has inserted it’s own unique ID [_id]

We don’t need to worry about the extra ID, as we’ll be using our own for lookups, so it can be ignored. To convert the array to an object, simply do:-


$case_study = (object) $case_study;


Which takes us back to:-


stdClass Object
(
[_id] => MongoId Object
(
[$id] => 4e6de720d2db288b0c000000
)

[id] => my/case_study
[title] => My case study
[body_text] => Some text for the case study
[skills] => Array
(
[css] => CSS
[sitebuild] => Site Build
)

)