<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Flapping Head</title>
	<atom:link href="http://scottbarnham.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://scottbarnham.com/blog</link>
	<description>Code and comments on web development, Django, Python and things (un)related.</description>
	<lastBuildDate>Mon, 16 May 2011 19:22:44 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>What is mysql doing?  Why too many connections?</title>
		<link>http://scottbarnham.com/blog/2011/04/29/what-is-mysql-doing-why-too-many-connections/</link>
		<comments>http://scottbarnham.com/blog/2011/04/29/what-is-mysql-doing-why-too-many-connections/#comments</comments>
		<pubDate>Fri, 29 Apr 2011 22:43:27 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=94</guid>
		<description><![CDATA[I recently had to troubleshoot a busy mysql database server for a client.  Here&#8217;s some basic tips.
SHOW PROCESSLIST is your friend
Inside mysql you can run show processlist to find out what the server is doing.  From the list you can see how many connections there are, which database, whether they are causing a [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had to troubleshoot a busy mysql database server for a client.  Here&#8217;s some basic tips.</p>
<h2>SHOW PROCESSLIST is your friend</h2>
<p>Inside mysql you can run <code>show processlist</code> to find out what the server is doing.  From the list you can see how many connections there are, which database, whether they are causing a lock, waiting for a lock, and even the query being run.  Very helpful.</p>
<p>You can get the same info from the <code>mysqladmin</code> program.  A simple way to monitor what the server is doing is to have <code>cron</code> email you every hour (or whatever interval) with the process list:</p>
<p><code>crontab -e</code></p>
<pre>MAILTO="you@example.com"
31 * * * * mysqladmin -u root -psecret --verbose processlist</pre>
<h2>Sleeping connections need closing</h2>
<p>If you have a lot of connections in a <code>sleep</code> state, it means they&#8217;re not doing anything but are still held open.  The server can run out of connections if they&#8217;re all busy sleeping.</p>
<p>Assuming the database is being accessed by a website (e.g. php code), you could look for ways to close the database connection sooner.</p>
<p>If you&#8217;re using Smarty, instead of:</p>
<pre>// open mysql connection
// do stuff
$smarty->display('template.tpl');
// close mysql connection</pre>
<p>you might try:</p>
<pre>// open mysql connection
// do stuff
$output = $smarty->fetch('template.tpl');
// close mysql connection
print $output;</pre>
<p>The difference is, you&#8217;re closing the mysql connection before returning data to the client.  If you&#8217;ve got slow clients (and assuming no reverse-proxy or load balancer to spoon-feed) it could release the database connection much sooner.</p>
<h2>EXPLAIN those queries</h2>
<p>If you have slow queries, you can find out why using <a href="http://dev.mysql.com/doc/refman/5.0/en/explain.html">explain</a>.  See how many rows they need to read (perhaps there&#8217;s no index the query can use) and if they need to be optimised.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2011/04/29/what-is-mysql-doing-why-too-many-connections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Posting unicode with urllib2</title>
		<link>http://scottbarnham.com/blog/2011/01/06/posting-unicode-with-urllib2/</link>
		<comments>http://scottbarnham.com/blog/2011/01/06/posting-unicode-with-urllib2/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 13:22:00 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=88</guid>
		<description><![CDATA[While integrating an xml api in to a django project, I needed to post some xml to a site.  I was using urllib2.urlopen but because my xml contained a non-ascii character (a £ pound sign) I was getting dreaded encoding errors like:
'ascii' codec can't encode character u'\xa3' in position 359: ordinal not in range(128)
After [...]]]></description>
			<content:encoded><![CDATA[<p>While integrating an xml api in to a django project, I needed to post some xml to a site.  I was using <code>urllib2.urlopen</code> but because my xml contained a non-ascii character (a £ pound sign) I was getting dreaded encoding errors like:</p>
<pre>'ascii' codec can't encode character u'\xa3' in position 359: ordinal not in range(128)</pre>
<p>After some messing, I came up with this:</p>
<pre>input_xml = render_to_string('integration/checkout.xml', {'booking': booking})
req = urllib2.Request(url, input_xml.encode('utf-8'), {'Content-type': 'text/xml; charset=utf-8'})
response = urllib2.urlopen(req)
</pre>
<p>The key part is: <code>input_xml.encode('utf-8')</code>.  The unicode string needs to be encoded to utf-8.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2011/01/06/posting-unicode-with-urllib2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android PhoneGap SetupTask cannot be found</title>
		<link>http://scottbarnham.com/blog/2010/12/30/android-phonegap-setuptask-cannot-be-found/</link>
		<comments>http://scottbarnham.com/blog/2010/12/30/android-phonegap-setuptask-cannot-be-found/#comments</comments>
		<pubDate>Thu, 30 Dec 2010 12:20:28 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=85</guid>
		<description><![CDATA[I was building an Android app using PhoneGap, but couldn&#8217;t get it to build.  It was failing to build the Java stuff because the path to the SDK was wrong.
I kept getting error:
framework/build.xml:49: taskdef class com.android.ant.SetupTask cannot be found
It&#8217;s because my PATH environment variable was wrong.  Specifically, it had trailing slashes.
This was on [...]]]></description>
			<content:encoded><![CDATA[<p>I was building an Android app using PhoneGap, but couldn&#8217;t get it to build.  It was failing to build the Java stuff because the path to the SDK was wrong.</p>
<p>I kept getting error:</p>
<p><code>framework/build.xml:49: taskdef class com.android.ant.SetupTask cannot be found</code></p>
<p>It&#8217;s because my <code>PATH</code> environment variable was wrong.  Specifically, it had trailing slashes.</p>
<p>This was on Ubuntu/Linux.</p>
<p>Got the same problem?  Try this to see if it is a problem with slashes:</p>
<p><code>which android</code></p>
<p>Did the path have a double slash like: <code>android-sdk-linux_x86/tools//android</code></p>
<p><code>echo $PATH</code></p>
<p>Do you have a path in there to the Android SDK <code>tools</code> directory which ends with a slash?  Get rid of that slash and try again.  You&#8217;re welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2010/12/30/android-phonegap-setuptask-cannot-be-found/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make a slug in PostgreSQL translating diacritics</title>
		<link>http://scottbarnham.com/blog/2010/12/20/make-a-slug-in-postgresql-translating-diacritics/</link>
		<comments>http://scottbarnham.com/blog/2010/12/20/make-a-slug-in-postgresql-translating-diacritics/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 20:09:57 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Postgresql]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=79</guid>
		<description><![CDATA[I needed to make slugs in Postgresql from names which included diacritics.  Though not complete, here&#8217;s a reasonable stab at it:
select regexp_replace(translate(replace(lower(your_field_name_here), ' ', '-'), 'áàâãäåāăąÁÂÃÄÅĀĂĄèééêëēĕėęěĒĔĖĘĚìíîïìĩīĭÌÍÎÏÌĨĪĬóôõöōŏőÒÓÔÕÖŌŎŐùúûüũūŭůÙÚÛÜŨŪŬŮ','aaaaaaaaaaaaaaaaaeeeeeeeeeeeeeeeiiiiiiiiiiiiiiiiooooooooooooooouuuuuuuuuuuuuuuu'), '[^\w -]', '', 'g') as slug
The translate is not quite right because it translates some uppercase to lowercase, but it&#8217;s all lowercase for the slug, so it doesn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>I needed to make slugs in Postgresql from names which included diacritics.  Though not complete, here&#8217;s a reasonable stab at it:</p>
<pre>select regexp_replace(translate(replace(lower(your_field_name_here), ' ', '-'), 'áàâãäåāăąÁÂÃÄÅĀĂĄèééêëēĕėęěĒĔĖĘĚìíîïìĩīĭÌÍÎÏÌĨĪĬóôõöōŏőÒÓÔÕÖŌŎŐùúûüũūŭůÙÚÛÜŨŪŬŮ','aaaaaaaaaaaaaaaaaeeeeeeeeeeeeeeeiiiiiiiiiiiiiiiiooooooooooooooouuuuuuuuuuuuuuuu'), '[^\w -]', '', 'g') as slug</pre>
<p>The translate is not quite right because it translates some uppercase to lowercase, but it&#8217;s all lowercase for the slug, so it doesn&#8217;t matter here.</p>
<p>[Update] Added &#8216;g&#8217; flag to regexp_replace to replace all occurrences, not just first.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2010/12/20/make-a-slug-in-postgresql-translating-diacritics/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Django static media always returning 404 not found</title>
		<link>http://scottbarnham.com/blog/2010/10/06/django-static-media-always-returning-404-not-found/</link>
		<comments>http://scottbarnham.com/blog/2010/10/06/django-static-media-always-returning-404-not-found/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 21:19:55 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Django]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=74</guid>
		<description><![CDATA[I spent too long tonight figuring out a weird problem.
On a dev server, I was using django.views.static.serve to serve media files.  But it was returning 404 (not found) for any file.
The requests for media files weren&#8217;t even showing up in Django&#8217;s built-in server&#8217;s output.  That had me baffled until I dug deep enough [...]]]></description>
			<content:encoded><![CDATA[<p>I spent too long tonight figuring out a weird problem.</p>
<p>On a dev server, I was using <code>django.views.static.serve</code> to serve media files.  But it was returning 404 (not found) for any file.</p>
<p>The requests for media files weren&#8217;t even showing up in Django&#8217;s built-in server&#8217;s output.  That had me baffled until I dug deep enough in Django&#8217;s code to figure it out.</p>
<p>The <code>ADMIN_MEDIA_PREFIX</code> was the same as <code>MEDIA_URL</code>.  That was it.</p>
<p>Django&#8217;s built-in server doesn&#8217;t log requests for admin media, so that&#8217;s why there was no log output.</p>
<p>The built-in server also handles admin media separately, so when I tried to request a media file, it intercepted and looked for it in the admin media.</p>
<p>The solution is for the <code>ADMIN_MEDIA_PREFIX</code> to be different from <code>MEDIA_URL</code>, e.g. <code>/media/</code> and <code>/media/admin/</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2010/10/06/django-static-media-always-returning-404-not-found/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Repair all tables in MySQL</title>
		<link>http://scottbarnham.com/blog/2010/09/08/repair-all-tables-in-mysql/</link>
		<comments>http://scottbarnham.com/blog/2010/09/08/repair-all-tables-in-mysql/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 12:08:04 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=70</guid>
		<description><![CDATA[In mysql you can repair a table using:
repair table mytable;
How do you repair all the tables in a database?  There&#8217;s no command for that, so you&#8217;ll need to repair each one individually.
That&#8217;s quite tedious, so here&#8217;s a bit of help in MySQL 5.
select concat('repair table ', table_name, ';') from information_schema.tables where table_schema='mydatabase';
Change mydatabase to [...]]]></description>
			<content:encoded><![CDATA[<p>In mysql you can repair a table using:</p>
<pre>repair table mytable;</pre>
<p>How do you repair all the tables in a database?  There&#8217;s no command for that, so you&#8217;ll need to repair each one individually.</p>
<p>That&#8217;s quite tedious, so here&#8217;s a bit of help in MySQL 5.</p>
<pre>select concat('repair table ', table_name, ';') from information_schema.tables where table_schema='mydatabase';</pre>
<p>Change <code>mydatabase</code> to the name of your database.</p>
<p>This gives you a load of repair table statements.  They&#8217;re formatted in a table with vertical bars, so copy the whole lot, paste in to a text editor or word processor, do a find and replace: find &#8220;|&#8221; replace with nothing.  Don&#8217;t worry about the spaces.</p>
<p>Copy and paste that lot in to your mysql command prompt.  Job done.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2010/09/08/repair-all-tables-in-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>UK Postcodes to Latitude/Longitude</title>
		<link>http://scottbarnham.com/blog/2010/08/27/uk-postcodes-to-latitudelongitude/</link>
		<comments>http://scottbarnham.com/blog/2010/08/27/uk-postcodes-to-latitudelongitude/#comments</comments>
		<pubDate>Fri, 27 Aug 2010 17:23:12 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Data]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=66</guid>
		<description><![CDATA[For location-based stuff, it&#8217;s useful to take a UK postcode and get the lat/long to plot it on a map (such as Google Maps).
The Google Maps API only has postcodes down to sector-level (e.g. NW1 4), so its results are approximate.
Ordnance Survey released the Code Point dataset free as part of OpenData.  Among other [...]]]></description>
			<content:encoded><![CDATA[<p>For location-based stuff, it&#8217;s useful to take a UK postcode and get the lat/long to plot it on a map (such as Google Maps).</p>
<p>The Google Maps API only has postcodes down to sector-level (e.g. NW1 4), so its results are approximate.</p>
<p>Ordnance Survey released the <a href="http://www.ordnancesurvey.co.uk/oswebsite/products/code-point-open/index.html">Code Point dataset</a> free as part of OpenData.  Among other things, it includes full postcodes with grid references.</p>
<p>The grid references are OSGB36, rather than lat/long.  Converting them is more difficult than you&#8217;d think.  Here&#8217;s the solution I used, based on what I cobbled together from forum posts and the like.</p>
<h3>Get the data</h3>
<p><a href="https://www.ordnancesurvey.co.uk/opendatadownload/products.html">Download</a> the Code Point data.  It&#8217;s a series of CSV files, one for each postcode area.</p>
<p>You might want to concatenate them in to one file.  Or if you only want London, postcodes, try the <code>e, ec, n, nw, se, sw, w, wc</code> files.</p>
<h3>Convert OSGB36 to WGS84 Lat/Lng</h3>
<p>The grid references need to be transformed to latitude/longitude on the WGS84 system.  There are a few ways to do this, but I used <a href="http://proj.osgeo.org/">PROJ4</a>&#8217;s cs2cs program.</p>
<p>The command is:</p>
<pre>cs2cs -f '%.7f' +proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894 +units=m +no_defs +to +proj=latlong +ellps=WGS84 +towgs84=0,0,0 +nodefs</pre>
<p>There is a PROJ wrapper for Python (pyproj), but I wasn&#8217;t smart enough to figure out how to do the options, so instead I spawned the cs2cs program from a Python script.</p>
<p>Here&#8217;s the script.  It&#8217;s not great, but it does the job.</p>
<pre>
#!/usr/bin/python

import sys
import csv
import subprocess
import re

def main(argv=None):
    if argv is None:
        argv = sys.argv

    if len(argv) != 3:
        print """\nUsage: %s input_file.csv output_file.csv\n""" % argv[0]
        return 1

    input = open(argv[1], 'r')
    reader = csv.reader(input)

    output = open(argv[2], 'w')
    output.write('flatpostcode,postcode,easting,northing,latitude,longitude\n')

    input_fields = []
    for index, row in enumerate(reader):
        postcode, easting, northing = row[0], row[10], row[11]
        input_fields.append((postcode, easting, northing))
        if index % 1000 == 0:
            process(input_fields, output)
            input_fields = []
            print 'processed', index
    process(input_fields, output)
    print 'done'

def process(input_fields, output):
    args = ['cs2cs', '-f', '%.7f', '+proj=tmerc', '+lat_0=49', '+lon_0=-2', '+k=0.9996012717', '+x_0=400000', '+y_0=-100000', '+ellps=airy', '+towgs84=446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894', '+units=m', '+no_defs', '+to', '+proj=latlong', '+ellps=WGS84', '+towgs84=0,0,0', '+nodefs']
    cs2cs = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    data = cs2cs.communicate('\n'.join(['%s %s' % (input[1], input[2]) for input in input_fields]))[0]
    for index, line in enumerate(data.split('\n')):
        if line:
            postcode, easting, northing = input_fields[index]
            data_parts = re.split('\s+', line)
            output.write('%s,%s,%s,%s,%s,%s\n' % (postcode.replace(' ', ''), format_postcode(postcode), easting, northing, data_parts[1], data_parts[0]))

def format_postcode(postcode):
    postcode = postcode.replace(' ', '')
    return '%s %s' % (postcode[0:-3], postcode[-3:])

if __name__ == '__main__':
    main()
</pre>
<p>Run it with your Code Point csv file as input.  The output contains the postcode, OS grid refs, latitude and longitude.</p>
<h3>Postgresql</h3>
<p>Bonus: if you&#8217;re using Postgresql, here&#8217;s how to get the csv data in to your database.</p>
<p>Create a table matching the csv file layout:</p>
<pre>create temporary table postcode (
flatpostcode varchar(8),
postcode varchar(8),
easting varchar(10),
northing varchar(10),
latitude numeric(10,8),
longitude numeric(10,8)
);</pre>
<p>Load it in:</p>
<pre>copy postcode from '/path/to/your/output.csv' with delimiter ',' csv header;</pre>
<p>Then copy the fields you want to your real table.</p>
<p>I hope this saves you some time and bafflement.   It would be nice to just give you the postcode + lat/long data, but redistributing it is against Ordnance Survey&#8217;s terms of use.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2010/08/27/uk-postcodes-to-latitudelongitude/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>OpenX Upgrade Page Full of Errors</title>
		<link>http://scottbarnham.com/blog/2010/08/20/openx-upgrade-page-full-of-errors/</link>
		<comments>http://scottbarnham.com/blog/2010/08/20/openx-upgrade-page-full-of-errors/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 10:29:04 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=63</guid>
		<description><![CDATA[I was moving and upgrading OpenX for a client (v2.8.5).  I changed some things in the config file, then went in to the admin interface (install page).
I got a screen full of baffling error messages starting:

MESSAGE: Undefined variable: imgPath
TYPE: Notice
FILE: /home/nice/public_html/www/admin/install.php
LINE: 75
DEBUG INFO:

70 $oMenu->add(new OA_Admin_Menu_Section('install', '', ''));
71
72 if ($oController->hasLayout()) {
73 //layout
74 $oPageHeader = $oController->getModelProperty('pageHeader');
75 [...]]]></description>
			<content:encoded><![CDATA[<p>I was moving and upgrading OpenX for a client (v2.8.5).  I changed some things in the config file, then went in to the admin interface (install page).</p>
<p>I got a screen full of baffling error messages starting:</p>
<pre>
MESSAGE: Undefined variable: imgPath
TYPE: Notice
FILE: /home/nice/public_html/www/admin/install.php
LINE: 75
DEBUG INFO:

70 $oMenu->add(new OA_Admin_Menu_Section('install', '', ''));
71
72 if ($oController->hasLayout()) {
73 //layout
74 $oPageHeader = $oController->getModelProperty('pageHeader');
75 phpAds_PageHeader('install', $oPageHeader, $imgPath, false, true, false);

76 }
77 if ($view) {
78 $view->display();
79 }
80 echo $actionContent;

MESSAGE: Only variable references should be returned by reference
TYPE: Notice
FILE: /home/nice/public_html/lib/OA/Admin/Menu/Section.php
LINE: 354
DEBUG INFO:

349 {
350 if ($this->type == $type) {
351 return $this;
352 }
353 else {
354 return $this->parentSection != null ? $this->parentSection->getParentOrSelf($type) : null;

355 }
356 }
357
358
359 /**

MESSAGE: Only variable references should be returned by reference
TYPE: Notice
FILE: /home/nice/public_html/lib/OA/Admin/Menu/Section.php
LINE: 354
DEBUG INFO:

349 {
350 if ($this->type == $type) {
351 return $this;
352 }
353 else {
354 return $this->parentSection != null ? $this->parentSection->getParentOrSelf($type) : null;

355 }
356 }
357
358
359 /**

MESSAGE: Undefined index: PREF
TYPE: Notice
</pre>
<p>Undefined variables.  Something&#8217;s wrong with reading the config file.</p>
<p>I had to edit the code to find out what the problem was.  In the <code>init-parse.php</code> file, look for <code>$conf = @parse_ini_file</code>.  Remove that @ sign &#8211; it&#8217;s suppressing the error message.  Try again and you should see an error saying can&#8217;t parse ini file on line X.</p>
<p>In my case, it&#8217;s because I put a dollar sign in the database password.  Seems that&#8217;s not valid in the ini file.  I changed the password and it&#8217;s working.</p>
<p>Pretty obscure, no?</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2010/08/20/openx-upgrade-page-full-of-errors/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Porting MooTools to jQuery</title>
		<link>http://scottbarnham.com/blog/2010/07/08/porting-mootools-to-jquery/</link>
		<comments>http://scottbarnham.com/blog/2010/07/08/porting-mootools-to-jquery/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 09:49:01 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[mootools]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=58</guid>
		<description><![CDATA[Last night I ported some JavaScript code that used MooTools to use jQuery instead.  In many ways I prefer MooTools to jQuery, but jQuery is easier to integrate in code that uses other libraries (e.g. Prototype).
Here&#8217;s a few quick hints for things you need to change if you&#8217;re doing the same.
$(&#8216;element_id&#8217;)
You need a leading [...]]]></description>
			<content:encoded><![CDATA[<p>Last night I ported some JavaScript code that used MooTools to use jQuery instead.  In many ways I prefer MooTools to jQuery, but jQuery is easier to integrate in code that uses other libraries (e.g. Prototype).</p>
<p>Here&#8217;s a few quick hints for things you need to change if you&#8217;re doing the same.</p>
<h3>$(&#8216;element_id&#8217;)</h3>
<p>You need a leading hash: <code>$('#element_id')</code></p>
<p>No need for two dollars to use selectors: <code>$('#element_id form input.special')</code> works.</p>
<p>There&#8217;s a difference of approach to what happens when you use <code>$(...)</code>: MooTools adds stuff to the DOM element.  jQuery gives you a new object which wraps the element.  This means you can&#8217;t just call DOM stuff on the object jQuery gives you.  e.g.</p>
<p>MooTools:<br />
<code>$$('a.special_link').href</code> &#8211; access the normal DOM properties</p>
<p>jQuery<br />
<code>$('a.special_link').attr('href')</code> &#8211; ask the jQuery object to access the underlying DOM element</p>
<p>A jQuery object can represent a list of elements, not just a single one.  You can access the underlying element using index zero: <code>$('a.special_link')[0].href</code></p>
<h3>Class</h3>
<p>jQuery doesn&#8217;t do classes.  There&#8217;s code and plugins around, or you can use a standard JavaScript approach like:</p>
<pre>var MyClass = function(blah) {
    // this is your constructor
    this.blah = blah;
};
MyClass.prototype.doStuff = function(name) {
    // this is a member function
    return this.blah + name;
}

// instantiate and call like normal
var thing = new MyClass('hello');
thing.doStuff('monty');
</pre>
<h3>bind(this)</h3>
<p>Oh this one hurts.  When you have a function, perhaps a callback, that you want to reference your class instance as &#8220;<code>this</code>&#8220;, in MooTools you use something like:</p>
<pre>new Request.JSON({url: '...', onSuccess: function(data){
    this.doStuff(data.name);
}<strong>.bind(this)</strong>);</pre>
<p>The equivalent is to use JavaScripts <code>apply</code> method which lets you pass an object to use for &#8220;<code>this</code>&#8220;.  You might also want &#8220;<code>arguments</code>&#8221; which is an array of all arguments passed to the function.  e.g.</p>
<pre>var self = this;
$.getJSON('...', <strong>function(){return</strong> function(data){
    this.doStuff(data.name);
}<strong>.apply(self, arguments)}</strong>);</pre>
<h3>addEvent</h3>
<p>This is what jQuery calls <code>bind</code>.  e.g.</p>
<pre>$('#element_id a').bind('click', function(e){..});</pre>
<h3>each</h3>
<p>Instead of MooTools&#8217; <code>$$('a.special').each(function(elem){...})</code></p>
<p>Try <code>$.each($('a.special'), function(index, elem){...})</code>.  Note the first param to your function is index, not the element.</p>
<h3>Request.JSON</h3>
<p>As above, try <code>$.getJSON(url, func)</code>.  You can also use <code>$.post</code> if it&#8217;s a POST request (seems to decode the JSON response automatically).</p>
<h3>get and set</h3>
<p>Instead of <code>elem.get('href')</code> try <code>elem.attr('href')</code>.  Instead of <code>elem.set('text', 'blah')</code> there&#8217;s <code>elem.text('blah')</code>.</p>
<p>That&#8217;s my braindump for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2010/07/08/porting-mootools-to-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Staplefish joins Red Robot Studios</title>
		<link>http://scottbarnham.com/blog/2010/03/18/staplefish-joins-red-robot-studios/</link>
		<comments>http://scottbarnham.com/blog/2010/03/18/staplefish-joins-red-robot-studios/#comments</comments>
		<pubDate>Thu, 18 Mar 2010 11:58:58 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://scottbarnham.com/blog/?p=53</guid>
		<description><![CDATA[I&#8217;ve been working as a freelancer under the Staplefish business name for over four years now.  Since mid-2008, I&#8217;ve also be working with Andrew at our Red Robot Studios business.
I&#8217;m moving all my Staplefish work under the Red Robot Studios brand.  The aim is to simplify some business things (accounting, tax, invoicing, etc) [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working as a freelancer under the Staplefish business name for over four years now.  Since mid-2008, I&#8217;ve also be working with Andrew at our <a href="http://www.redrobotstudios.com/">Red Robot Studios</a> business.</p>
<p>I&#8217;m moving all my Staplefish work under the Red Robot Studios brand.  The aim is to simplify some business things (accounting, tax, invoicing, etc) and offer better service by teaming up with Andrew (e.g. one of us can cover while the other goes on holiday).  It also marks our decision to focus on Red Robot Studios and offer great <a href="http://www.redrobotstudios.com/django-development/">Django development</a> and <a href="http://www.redrobotstudios.com/mobile-development/">mobile development</a> services.</p>
<p>To all Staplefish clients: Please be assured Scott is still working for you, just under a different business name and your websites will not be affected.  Feel free to contact me with any questions or concerns.</p>
]]></content:encoded>
			<wfw:commentRss>http://scottbarnham.com/blog/2010/03/18/staplefish-joins-red-robot-studios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.267 seconds -->
<!-- Cached page served by WP-Cache -->

