Archive for July, 2009

Custom flickr sidebar via wget, cron & PHP

Wednesday, July 29th, 2009

The new site launched with a sidebar that shows two random photos from our flickr account, using their javascript widget. This was a great way to get things going, but now we’ve developed slightly more involved needs and I’ve had to come up with a custom solution.

Getting the list of photos

You need a flickr API key, which is quick & easy to get. Then wget & cron to get ‘em: wget --quiet 'http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=YOUR_API_KEY&user_id=YOUR_USER_ID&tags=website&per_page=500' -O photos.xml

Note that this includes a tags argument. The thing that pushed me to switch the workflow was the desire to be able to upload photos to our flickr account that don’t necessarily fit into the sidebar format, such as panoramics. To handle this, everything that belongs on the website gets the tag website, and we only fetch those ones. We’ve also talked about just getting landscape oriented photos, but haven’t implemented that.

I’m running this daily, which is plenty often to update the available photo list. I believe this gets the newest 500, which seems more than adequate, particularly since we don’t have close to 500 photos yet.

Parsing the list & generating the HTML

PHP5’s SimpleXML is pretty nice — here’s what we’re doing:

try {
  $xml = new SimpleXMLElement(file_get_contents('photos.xml'));
    $number_of_photos = count($xml->photos->photo);
    $displayed_photos = array();
    array_push(
      $displayed_photos,
      $xml->photos->photo[rand(0, $number_of_photos - 1)]);
    array_push(
      $displayed_photos,
      $xml->photos->photo[rand(0, $number_of_photos - 1)]);
    foreach ($displayed_photos as $photo) { ?>
  <div>
<?php
      print "<a href=\"http://www.flickr.com/photos/8562013@N07/" .
        $photo['id'] . "\"><img src=\"http://farm" . $photo['farm'] .
        ".static.flickr.com/" . $photo['server'] . "/" . $photo['id'] . "_" .
        $photo['secret'] .  "_m.jpg\" alt=\"" . $photo['title'] . "\" /></a>";
?>
  </div>
<?php
 }
} catch (Exception $e) {
  error_log("flickr badge had some troubles: " .
    $e->getMessage());
}

This snippet takes my laptop less than 1/20th of a second to run from the command line, which suits me fine. The actual code sits in page.tpl.php.

Flickr’s API docs, in particular the API Explorer, were awful handy in figuring this all out.

Joe’s hacky approach to getting arbitrary behavior out of Drupal

Tuesday, July 28th, 2009

Wherein I disqualify myself for work as a “drupal developer”

Self indulgent history part

Way back in 1999 when I started out writing web apps, Embperl seemed like the logical tool to use — so I’m used to having direct access to every step in the request-to-response process. In years since, I’ve progressed through a bunch of different tools and approaches, which have included writing a few rudimentary content management systems and using a bunch of prexisting ones.

Over the last few years I’ve become a big fan of ruby on rails, so if a site does much of anything (simple, recent example: The Food Project’s online summer program application), that’d be my starting point.

so, why use Drupal?

Even so, when a site is basically about some content that’s written and edited on an ongoing basis by other folks, Drupal starts looking like a reasonable tool. It’s pretty easy to get it to generate semantic output with reasonable URLs, and the editor-facing UI does a fair job of offerring a large degree of control and customizability without being overwhelmingly complex.

Despite having done some custom work on a few live Drupal sites, I still get confused about the best way to do some of the arbitrary web interaction tasks that were so straightforward back in the Embperl days. There are a billion modules in the Drupal ecosystem, but I often find that it takes more time to figure out if there is an appropriate one for my task & if it works with the current version of Drupal than it would to code up a solution on my own. Also, while I’ve made several attempts to solve programming tasks in what I understand to be the Drupal way, wrapping my head around all the relevant APIs (which can totally change every 6-12 months, with each Drupal release) similarly tends to take more time than bypassing Drupal’s functionality & handling things in Plain Old PHP.

Here’s a common approach I’ll take, then. I have no interest in extensive coding through a web browser (i.e. putting a bunch of PHP in a node or block), so I’ll set up a Drupal module to hold my application’s arbitrary php functions. Then I’ll create a page at the desired URL and enter a line of PHP to route the GET and/or POST to my code, as appropriate.

Example

I’m working on an email list signup that needs to communicate with a FileMaker database. An HTML form POSTs to http://thefoodproject.org/mailing_list_signup, which is just a Drupal page using the PHP input filter (which you now need to turn on via admin settings) containing <?php tfp_process_list_signup($_POST); The code for that function lives in sites/all/modules/tfp/tfp.module, and does the normal PHP things to pull information out of the POST & hand that info off to the FileMaker database. Here’s a bit of it:

function tfp_process_list_signup($_POST) {
  $reply = '';
  $sent_plausible_address = FALSE;
  if ($_POST['email']) {
    $supplied_email = $_POST['email'];
    if (preg_match(PLAUSIBLE_EMAIL, $supplied_email)) {
      $sent_plausible_address = TRUE;
      $reply = "Thanks! We'll add your to our mailing list.";
    } else {
      $reply = "'$supplied_email' doesn't look like an email address to me. ";
    }
    //. . .
  }
  return $reply;
}

On the upside, this is quick & easy. The downside with this approach vs. writing a module the Drupal way is that I’m losing out on Drupal’s form API and its associated validation, antispoofing, etc. services. On the upside, last time I checked the linked documentation for the form API, it said

Warning - this page has only been partially updated for the Drupal 6.x API
Until it has been fully updated, reference this page as well: Drupal 5.x to 6.x FormAPI changes

so I’m quite happy to not have to wade through all of that! (more…)

Lazyweb: 5 hr layover in Amsterdam airport?

Monday, July 20th, 2009

Any readers out there who know what options exist for a 5 hr layover in Amsterdam? This is before an international flight, so it’s not like I have 5 actual hours to play with. A (not this) Friday morning.

Wikipedia claims it’s a 20 minute trip into the city, which suggests that some minimal tourism should be possible…