Jun21

Learning Python – Day 2

I’m excited about my new admin interface. Page 2 on the tutorial goes into how to customize the admin. I don’t care about that at the moment so I go to page 3.

Page 3 is about URLs. Django uses a sequence of tuples populated with regular expression -> url maps. Great, this is how I did things in PHP. I add a couple of URLs and move on.

Next it’s time to create my views. I write my first view which simple prints “Hi!”. It works, great. I see that the basics of the template language used in Django are very similar to how I do it in PHP. I port my view from my PHP template to the template in Django.

{% foreach company in category.company.all() %}

Unfortunately this doesn’t work. It’s not looping over my categories/companies/videos. I think it’s because it’s having trouble going backwards with my foreign key relationships.

I find that in order to go backwards you have to do this

{% for company in category.company_set.all() %}

You have to use _set to access foreign key items. This doesn’t work either! I give up on this route and I try the method I use in PHP… creating a giant multi-dimensional array and then looping over that.

This is where I hit a wall. I quickly find out that Python’s version of arrays, called dictionaries, can’t be created like they can in PHP. I don’t like that one bit.

Python doesn’t have a version of

$video['company_id']['category_id']['video_id']['name'] = 'Video Name';

I find some custom classes via google, but Django won’t iterate over them. A couple hours later I figure I need help. I ask a couple of places and everyone suggests that it is possible with Django’s ORM, I just need to remove the ()

I find that you have to do this!

{% for company in category.company_set.all %}

You have to remove the () for functions that have no arguments. Works like a champ. Two minutes later I have all categories/companies/videos displayed correctly. I’m still using Django’s development server though so I have no styles/images, just black test on a white background.

I read somewhere that I should be using mod_wsgi instead of mod_python (I can’t find the source). Using this I get it working with Django pretty quickly.


Good:Django’s ORM

Bad: Python’s dictionary handling not my favorite. I enjoy the way PHP has implemented arrays and how they can be used as lists, dictionaries, stacks, etc. Django’s documentation is thorough, but I get lost in the maze of versions it has.

Notes: I don’t know why I didn’t think of this, but it’s been pointed out to me that you can do this:

a = dict()
a['foo'] = dict()
a['foo']['bar'] = {'this works': 'yes it does'}

That probably would have solved my problem.

Jun20

PHP template engines and why they’re useless

For the past 4 or 5 years I’ve been a proponent of using PHP as it’s own template engine. I cringe every time I see someone using smarty, btemplate, fastTemplate, etc… because I’ve never had to do anything in my html that couldn’t be done with PHP. Never! Why add a layer to your app if you don’t have to?

To illustrate this I’m going to show you a template written in a template engine, and then in PHP.

Here’s an example from the Smarty website

<table border="0" width="300">
    <tr>
        <th colspan="2" bgcolor="#d1d1d1">Guestbook Entries (<a href="{$SCRIPT_NAME}?action=add">add</a>)</th>
    </tr>
    {foreach from=$data item="entry"}
        <tr bgcolor="{cycle values="#dedede,#eeeeee" advance=false}">
            <td>{$entry.Name|escape}</td>        
            <td align="right">{$entry.EntryDate|date_format:"%e %b, %Y %H:%M:%S"}</td>        
        </tr>
        <tr>
            <td colspan="2" bgcolor="{cycle values="#dedede,#eeeeee"}">{$entry.Comment|escape}</td>
        </tr>
    {foreachelse}
        <tr>
            <td colspan="2">No records</td>
        </tr>
    {/foreach}
</table>

Here’s an example using PHP. e() is an escaping function you write yourself.

<table border="0" width="300">
    <tr>
        <th colspan="2" bgcolor="#d1d1d1">Guestbook Entries (<a href="{$SCRIPT_NAME}?action=add">add</a>)</th>
    </tr>
    <?php if ( count( $data ) ): ?>
    <?php foreach( $data as $entry ): ?>
        <tr bgcolor="<?php if( $i++ % 2 ): ?>#dedede<?php else: ?>#eeeeee<?php endif; ?>">
            <td><?= e( $entry['name'] ) ?></td>        
            <td align="right"><?= date( $entry['entryDate'], 'e b Y H M S' ) ?></td>        
        </tr>
        <tr>
            <td colspan="2" bgcolor="<?php if( $i % 2 ): ?>#dedede<?php else: ?>#eeeeee<?php endif; ?>"><?= e( $entry['comment'] ) ?></td>
        </tr>
     <?php endforeach; ?>
     <?php else: ?>
        <tr>
            <td colspan="2">No records</td>
        </tr>
     <?php endif; ?>
</table>

As you can see there is only 2 added lines of code. I had to add an if statement to account for smarty’s foreachelse. No added layer. No extra work for the interpreter. Just as readable (unless you’re a developer, then it will be more readable)

In closing read this post on the sitepoint forums. Pay particular attention to Voostind’s replies (#1, #2, #3)

Jun17

Learning Python – Day 1

Step one: Does my server have python? Yes.

Great, I have python. Now what? I don’t know. I google “python web development”. I click the first link. Python webservers! I have to embed python into apache! Duh!

sudo apt-get install libapache2-mod-python

Now I have mod python running. Two hours later I have a hello world on my development site. That took way too long. I’m annoyed. I start asking people for recommendations. I just want to code! I’m sick of setting up my server. With PHP it’s cake. One call to apt-get install and off you go.

98% of the people I ask recommend Django. So I install django via apt-get install, head over to djangoproject.com, and start reading the tutorials.

Page 1 is pretty straight forward. I do some creation/configuring and create/activate my models. Then I get to play with my models. Django’s ORM is pretty nice. I usually prefer to write all my own SQL, but I could get used to this.

I get to page 2 of the tutorial where they start talking about the automatic admin. I’m shocked. This is amazing. Are frameworks in PHP this awesome? I’ve always used my own PHP framework. I’ll have to check that out. Back to Django.

This admin app is amazing I have to try this with SVO. I go back to page 1 on the tutorial and start following it but with SVO details. I get to page 2 and then import all my data into my newly created tables. I have a fully functioning admin in 10 minutes!

That’s all for day one.


Good: Django, Django’s automatic admin

Bad: Server setup not so easy

Notes:

1. To view the Django development server on a host other than localhost bind it to your server’s IP address

sudo python manage.py runserver 0.0.0.0:8000
Jun15

I’ve decided to learn Python

I decided to learn Python by rewriting skate videos online in it.

I’m going to chronicle my experience right here… for noone to read =)

Jun12

Merge query string

Ever have a url like this…

index.php?dosearch=true&page=1&search[co_name]=best+buy&search[address1]=12+main+st&search[city]=bridgeport&search[state_province_abbrev]=ct

…and wanted to create a link that would go to page=2, but keep the rest of the query string?

This recently happened to me so I created a function. Normally this would be a trivial call to array_merge, but I needed it to handle single-level arrays too.

I present to you mergeQuery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function mergeQuery( $link ) {
 
	parse_str( $_SERVER['QUERY_STRING'], $qry );
	parse_str( $link, $lnk );
	$mergedQry = array_merge( $qry, $lnk );
 
	foreach( $mergedQry as $var => &$val ) {
 
		if ( is_array( $val ) ) {
			foreach ( $val as $val_k => $val_v ) {
				$finalQry .= sprintf( '%s[%s]=%s&', $var, $val_k, $val_v );
			}
		}
		else {
			$finalQry .= sprintf( '%s=%s&', $var, $val );
		}
 
	}
 
	return '?' . rtrim( $finalQry, '&' );
 
}

Any variables you supply will overwrite variables from the current query string.

Examples

<a href="<?= mergeQuery( 'page=1&id=23' ) ?>">
<a href="otherpage.php<?= mergeQuery( "page=5&id={$data['id']}" ) ?>">

Maybe someone else will find some use for it

Jun11

Current Reads

While doing some research on Lokesh Dhakar’s lightbox, I came across a post of his where he took pictures of the books he was currently reading.

I liked the idea, so I’m stealing it.

Here are some books I’m currently reading.

Books i'm currently readin

The Unlimited Freelancer
Don’t Make Me Think: A Common Sense Approach to Web Usability, 2nd Edition
HTTP: The Definitive Guide
Code Complete: A Practical Handbook of Software Construction
PHP in Action: Objects, Design, Agility

Jun09

Forget about pushing your Gmail, use the Gmail mobile app

Pushing Gmail to my blackberry was annoying. While it hit my inbox very quickly, I found the drawbacks far outweighed the only advantage.

  • The Blackerry mail interface is terrible.
  • Having all my message (email, texts, missed calls, voice mails) in one place is annoying.
  • Reading a Gmail message on your Blackberry does not mark it as read in your Gmail inbox. Deal breaker!

Using Gmail for mobile 2.0 is a much better option.

  • Everything you can do in your Gmail inbox you can do on the Gmail mobile app including searching, adding stars/labels
  • Gmail for mobile notifies you when you have new messages

The only drawbacks I’ve found are that Gmail for mobile only checks for new mail every 20 minutes or so, and if the Gmail app has focus you won’t be alerted of new emails. If you send Gmail to the background the latter isn’t an issue.

To install it visit m.google.com/mail in your Blackberry browser.

Here are some of the more useful shortcut keys:

i = inbox (if your viewing the inbox i will refresh)
/ = search
c = compose
shift+i = mark as read
shift+u = mark as unread
#,d,delete = Delete
s = toggle star
e = archive
! = report spam
z = undo
t = first conversation (top)
b = last conversation (bottom)

While viewing a mail message

r = reply
a,? = reply to all

Jun01

Returning an instance of a class from PDO

You can have PDO create and return an object(s) of a specific class. It can be a little tricky getting it to work though…

With fetchAll() you can pass ( PDO:FETCH_CLASS, ‘class_name’ ) directly

$sql = sprintf( 'select * from %s where prod_id=:prod_id', TABLE );
$findProducts = $this->db->prepare( $sql );
$findProduct->execute();
$products = $findProducts->fetchAll( PDO::FETCH_CLASS, 'Product' );

But with fetch() you must initiate it with setFetchMode

$sql = sprintf( 'select * from %s where prod_id=:prod_id', TABLE );
$findProduct = $this->db->prepare( $sql );
$findProduct->setFetchMode( PDO::FETCH_CLASS, 'Product' );
$findProduct->execute();
$product = $findProduct->fetch( PDO::FETCH_CLASS );
May18

Change Firefox’s default search engine

I recently installed yahoo messenger, and in doing so the damn thing set yahoo as the default search engine for firefox. I will have none of that.

Here’s how to change it back to google:

  1. Go to about:config
  2. Search for keyword.URL
  3. Change the value to http://www.google.com/search?q=
May13

Get the lat long from google maps

Quick way to get the lat long of the center of google maps

Add this as a bookmark

javascript:void(prompt('(lat,lng)', window.gApplication.getMap().getCenter()));

If you are using firefox, and you better be, go to the properties of the bookmark and give it a keyword. I gave mine m

When you have the map location centered:

  1. press f6 to highlight the url
  2. type in your keyword and hit enter
  3. CTRL C to copy
  4. Escape to close the prompt

Thanks to The Distant Librarian for his improved javascript that made copying the lat/lng easier.