Smokes your problems, coughs fresh air.

Author: Rowan Rodrik (Page 18 of 27)

Rowan is mainly a writer. This blog here is a dumping ground for miscellaneous stuff that he just needs to get out of his head. He is way more passionate about the subjects he writes about on Sapiens Habitat: the connections between humans, each other, and to nature, including their human nature.

If you are dreaming of a holiday in the forests of Drenthe (the Netherlands), look no further than “De Schuilplaats”: a beautiful vacation home, around which Rowan maintains a magnificent ecological garden and a private heather field, brimming with biological diversity.

FlashMQ is a business that offers managed MQTT hosting and other services that Rowan co-founded with Jeroen and Wiebe.

Customizing Google AdSense alternate ads

When AdSense runs out of inspiration (i.e.: no targeted ads are available), it displays public service ads by default. You can choose to replace this with a custom ad of your own choosing. To do this, you have to put a HTML page somewhere and change the alternate ads settings for the appropriate ad unit:

AdSense unit: alternate ads settings for HardhoutWiki leaderboard

Alternate ads settings for HardhoutWiki leaderboard AdSense unit

Instead of the public service ads, I wanted to serve a banner ad to promote our beautiful family vacation home. I created this image a few years ago for an AdWords campaign started by my uncle because he wanted to reach more potential vacation goers.

Schuilplaats banner ad

The 728x79 banner image

I put put up a page with the image at http://www.bigsmoke.us/schuilplaats-banner-ad/. The HTML is very simple:

<html>
  <head></head>
  <body>
    <a href="http://www.hugovandermolen.nl/schuilplaats/startpagina.php"><img src="schuilplaats-banner-ad.jpg" /></a>
  </body>
</html>

If anyone wants to promote our vacation home for free, all they have to do is to change Alternate ads or colors to Show non-Google ads from another URL and fill in http://www.bigsmoke.us/schuilplaats-banner-ad/.

Although I put the alternate ad up over a year ago, I was prompted to blog about it because two months ago, for the first time, I suddenly saw the ad actually being serviced on my Dutch HardwoodWiki:

The alternate ad in action

The alternate ad in action

Complete WordPress Atom feed: an XSLT transformation

Previously, I tried obtaining a full Atom feed without pagination from WordPress. I didn’t succeed, so I ended up writing an XSL transformation which merges all the pages of this Atom feed into one valid Atom XML stream.

The transformation: wordpress-full-atom-feed.xsl

<?xml version="1.0" encoding="UTF-8"?>
 
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:thr="http://purl.org/syndication/thread/1.0"
xmlns="http://www.w3.org/2005/Atom">
 
<xsl:param name="base_url" select="atom:feed/atom:link[@rel='self']/@href" />
 
 
<xsl:template match="/">
  <xsl:apply-templates select="node()" />
</xsl:template>
 
<xsl:template match="*">
  <xsl:element name="{name(.)}">
    <xsl:apply-templates select="node()" />
  </xsl:element>
</xsl:template>
 
<xsl:template match="@*|node()">
  <xsl:copy-of select="." />
</xsl:template>
 
<xsl:template match="atom:feed">
  <feed>
    <xsl:apply-templates select="@*|node()" />
 
    <xsl:call-template name="process_feed_page">
      <xsl:with-param name="page" select="number('2')" />
    </xsl:call-template>
  </feed>
</xsl:template>
 
<xsl:template name="process_feed_page">
  <xsl:param name="page" />
 
  <xsl:variable name="page_doc" select="document(concat($base_url, '?paged=', $page))" />
 
  <xsl:if test="$page_doc/atom:feed/atom:entry">
    <xsl:apply-templates select="$page_doc/atom:feed/atom:entry" />
  
    <xsl:call-template name="process_feed_page">
      <xsl:with-param name="page" select="$page + 1" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>
 
</xsl:transform>

The transformation works by processing the atom:feed element. Before closing that, the process_feed_page template is called. This template tries to open the next page and process all atom:entry elements in there. Then it tries to recurse to the next page.

The next page’s URL can be guessed because this is the normal feed URL with ?paged=[pagenum] appended to it. The feed URL can be found because WordPress adds it to the feed:

<link rel="self" type="application/atom+xml" href="http://blog.bigsmoke.us/author/halfgaar/feed/atom" />

For very old WordPress versions this doesn’t work, because the paged parameter isn’t supported there. Also, older versions might require you to supply the $base_url param to the XSLT processor, because the rel='self' link is incorrectly set to the URL of the default feed within all other feeds (such as the author feed or the tag feed).

Invocation

Invocation is simple. I use libxslt‘s xsltproc:

xsltproc wordpress-full-atom-feed.xsl http://blog.bigsmoke.us/author/halfgaar/feed/atom

That’s it. You end up with a full feed as if there never was any pagination to begin with; it almost looks as if WordPress does support the nopaging option for feeds.

Enforcing Drupal URL aliases

I hate modules, especially core modules. I prefer code to be tightly integrated. I want it to work together. Is that too much to ask? In Drupal, most functionality has been stuffed in modules. There’s a Locale module, a Content Translation module and a Path module. What’s missing is a Working Together module.

For me, clean, meaningful URLs are a number one, two and three requirement for any website that I do. Drupal considers /node/54673 to be a cool URL. I don’t. So, as a kind of afterthought, Drupal comes with the Path module. This module allows you to set URL aliases per node.

The problem is that there’s no concept of a canonical URL. The URL alias works, but so does the node/3242 URL. Neither redirects to the other. In many cases this is not much of a problem (because regular visitors will not notice this) but for our current project it is.

We have a lot of blocks with URL dependent visibility settings. For example, for a section about investing we have a menu that is displayed on all URLs starting with /investing, such as /investing/projects and so on.

After editing a page, Drupal helpfully redirects the user to node/[nodenumber]. For us, this means that the menu is no longer displayed and even the theme will be wrong. (We use the Sections module to select a subtheme based on which section you’re in.)

Global Redirect doesn’t work

The Global Redirect module promises to solve this by allowing you to redirect node/[nodenumber] URLs to their alias if available. It kinda does, in some circumstances.

Our Drupal website sports two languages: English (EN) and Dutch (NL). English is the default language (not the fallback language; we don’t use a fallback) and doesn’t use a prefix. Dutch uses the nl prefix. Two example URLs:

URL alias Generic URL
http://www.example.com/investing/projects http://www.example.com/node/288
http://www.example.com/nl/beleggen/projecten http://www.example.com/nl/node/110

When /node/288 is requested, the client is correctly redirected to /investing/projects, but when /node/110 is requested, no redirect takes place. It will take place when prefixing /nl, but this is completely useless since Drupal’s built-in actions such as edit don’t redirect using this prefix, and these actions were what we needed this module for in the first place.

A very simple hack that does work

We ended up tearing our hair out trying to fix Global Redirect until we decided that we could just delete the module and replace it with a RewriteRule and a simple PHP script.

Modify: .htaccess

# Put this after RewriteBase and before Drupal's default rewrite rules
RewriteRule ^(../)?node/([0-9]+)$ fixurl.php?nid=$2 [L]

Add: fixurl.php

<?php
 
require_once './includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
 
$result = db_query("SELECT * FROM {url_alias} WHERE src = 'node/%d' LIMIT 1", $_GET['nid']);
if ( db_error() ) die("O agony!");
 
$url_alias_object = db_fetch_object($result);
$destination = $url_alias_object->dst;
 
$result = db_query("SELECT prefix FROM {languages} WHERE language = '%s'", $url_alias_object->language);
if ( db_error() ) die("O agony!");
 
$prefix = db_result($result);
 
if ( !empty($prefix) )
  $prefix .= '/';
 
header("Location: /$prefix$destination",TRUE,301);
 
?>

Shortcomings in our hack

The code assumes that every content page has an URL alias. For us, this is okay, because we need these pretty URLs to even have menus show up or to have the right page be displayed with the right theme.

Also, this code is specifically tailored to language code in the URL prefix. For subdomain based language selection, for example, you’d need to modify it.

Gentoo update: system

This Gentoo box needs upgrading badly. I started this in February, so perhaps it’s time to continue.

Trying to update the world profile causes a few too many problems, so I start with updating everything in the system profile:

# emerge --update --deep --newuse system

sys-apps/man-pages

The first blockage of the day is “sys-apps/man-pages-3” that is blocking “sys-apps/man-pages-posix-2003a“. The latter is pulled in by “sys-apps/man-pages-posix“, which in turn is required by “sys-apps/man-pages-3.20“.

Somehow, unmerging “sys-apps/man-pages” resolved this blockage:

# emerge --unmerge sys-apps/man-pages

I just had to ignore a few warnings about the package being part of my system profile and I could reissue the system update command. The unmerged package is neatly remerged.

# emerge --update --deep --newuse system

This command started merging 99 packages. The only interruption left in this process was caused by the savedconfig use flag which made the busybox ebuild fail.

With Vimperator it almost feels as if I can control Firefox

Wednesday, after returning to Groningen from Barcelona, I saw Ying using Vimperator. I was sold immediately.

I like to use the keyboard. Point and click is not really my cup of tea. It just doesn’t work without a touch screen. (A while ago I had the opportunity to see an expensive tilt-able touch screen in action and I was quite impressed by how suddenly a GUI became less of a disaster.) I’m an avid VIM user. Although I’ve tried training myself to Emacs, I’ve never made the switch. Even if I would have, this wouldn’t have changed the fact that I’m a shell person, not a desktop person.

Editing in an external editor

I do a lot of writing from my web browser (Firefox). This is not the most enjoyable activity imaginable using the typical <textarea>. It’s not that HTML textareas are so bad, it’s just that I don’t like typing anything extensive without using VIM.

The It’s All Text! Firefox add-on is one way to solve this problem. It adds a small “edit” button to the bottom right of all textareas. (It also adds a context submenu, but this can only be used to edit the whole page’s source (which I found to be a little bit disappointing as I’d rather seen that this acted on just the textarea when going there from a textarea).) The button executes an external editor of choiseGVIM.

Using Vimperator, when in insert mode (inside a textarea), I just have to press Ctrl-i to execute GVIM. The It’s All Text! add-on has thus been deprecated.

Better WindowMaker integration

Due to my reluctance to switch to a tiling window manager, I’m still using WindowMaker. Starting Firefox in WindowMaker is a bit of a nuisance because the main window opens too far out beyond the top left of my workspace. The only way to change this is to tell it to start maximized. However, the main window and the dialogs have the same WM_CLASS and I was somehow annoyed with getting all the popups maximized as well.

Vimperator starts these windows within the browser tabs, so there’s no longer a good reason not to start Firefox maximized. This saves me another keystroke whenever I begin a new browsing session.

Modes

Normal mode
In normal mode, I can perform all navigational tasks quickly an concisely. Especially identifying and following links is revolutionary. No more remembering access keys for every web app. I can just press f and type a number. The View Access Keys extension is no longer necessary.
Insert mode
I had never considered how much a seperate insert mode would have made me feel more in control of Firefox. The fact that I can escape it and scroll a bit or follow a link before continuing to type is priceless.
Pass-through mode
There are many modern web applications such as Gmail that have keystrokes conflicting with Vimperator. The great thing about Vimperator is that it wins. But, by pressing Ctrl-z, you can make the web page win until you escape the mode.

There are more modes, but I’m not here to write a tutorial. 🙂

Scrolling

I have many of the scrolling options that I’m used to in VIM. Most importantly, I can scroll half a page instead of a whole page! Before, I’ve spent a lot of time mucking around trying to find out how to make Firefox do this and the only extension that seemed to be able to deliver was Firemacs which I shied away because it did away with many of Firefox’s default key bindings, which is ironic because Vimperator seems much more extreme in this regard. 😛

Flash focus

On thing that I would really like Vimperator to do is to disable Flash content from stealing focus. That would remedy the last type of situation where I simply don’t feel in control of my web browser.

Drupal 5 image management

Today, I have to face the task of finding reliable Drupal 6 modules for image uploading and WYSIWYG editing, so I dug into my drafts bin and found an old unfinished post dated March 24, 2008 about a similar quest for Drupal 5:

I’ve founded this new website, www.worldwide-wilderness.com. (Don’t mention the name; I know it’s sheer genius.) Drupal is going to power the site. At least I hope it will. First, I have to somehow convince Drupal’s media management not to suck, so far to little avail. 🙁 This post is my attempt at getting my thoughts straight. (It’s the logging in blogging that is of great help to me when, later, I can quickly pick up a problem where I left it. Also, sometimes, a better solution is thrown at me.)

So, Drupal: Drupal is great! The installation is a snap. The organization of the management interface is very intuitive and I love how interdependent modules are handled (i.e.: the fact that they’re handled). I ended up with Drupal in my search for a system which can power a weblog and a wiki at the same time. Drupal is a CMS framework which I had often come across but for some reason had never taken a closer look at. Much to my detriment, was my first thought during the configuration/exploration phase after installation.

Before I continue about Drupal, I should tell you something about what I want to do with www.worldwide-wilderness.com. Naturally, the topic will be wilderness. The site’s purpose is to popularize the wild, uncontrolled aspect of nature. I’m doing this because I’d like to see wilderness everywhere, but especially in your eyes. The site will mostly be a blog, with illustrated stories, podcasts and even video’s. But, we want to have the ability to add a knowledge base (with wiki power). And everything has to be integrated, much more deeply than in my Point Omega project where I simply installed MediaWiki and WordPress, each on their own subdomain.

Now, I need to make a selection from the many media management modules which are available for Drupal. Initially there will be some posts with many photographs on www.world-wide-wilderness.com. Uploading and annotating these one-by-one will take all the fun out of it, so I want this to be made easy. The modules which I choose will have to facilitate this.

  • EXIF extraction is an absolute must. IPTC extraction is optional, as long as the IPTC information is not stripped from the original images. If changes to the extracted data would be changed back in the original images, this would be especially nice.
  • Batch uploading is another requirement. I don’t care much whether this is through WebDAV, a Gallery2 API or even using a compressed archive, but I don’t want to upload images one by one.
  • A final wish is the mass editing of captions and/or other meta-data. I like very much how Google’s Picasaweb does this. If this works well, it could somewhat mitigate the need for EXIF/IPTC meta-data extraction.

Up till now I’ve tried the following:

  • The first thing to decide was whether to use the regular Image module or not. I chose yes because there are so many other modules which depend on this module. It comes with a few contributed add-on modules already. The included gallery module is quite to my taste, so that’s good.

  • When using the Image module, there are many options for inserting images. So far, I like the GUI of Image Assist for uploading and inserting single images. I do think that the button messes up the layout of the content creation page though. Also, a module like this is completely useless when you want to upload more than a few files, which I do. 😕

    Drupal content creation screen with the img_assist module enabled
    The content creation screen was so beautifully sober without the intrusive Image Assistant icons!

    There’s another module, Upload Image, which might be even better for uploading single images. I like that it integrates with the attachment functionality which keeps my screen clean and comes from a core module. What this module does extra is that it turns each attached image into an actual image node, opening up many advantages such as adding the attached images to albums and everything. If I keep using the Image module, this module will also remain part of my toolkit for sure!

    The Upload Image module is supposed to display thumbnails instead of filenames in the attachment list. It doesn’t for me. But there’s another module, Upload Preview, which does just this and only this. Too bad that this module doesn’t work. It seems easy enough to fix, so I might patch this if I decide to go this route.

    I haven’t tried Node Images. It doesn’t have a proper release yet, and I’m not sure what it’d add over the other attachment features.

    But, of course, there’s competition for the core upload module: File Field uses the Content Construction Kit to do the same.

  • The Exif module can only display Exif data at this time, while I want to extract at least a caption. Support for extraction is planned. David Lesieur, the author of the module is not actively developing the module at this point.
  • Independently from the Image module, I’ve tried the Asset module. This module doesn’t seem to like safe_mode very much and I think that its file picker/upload dialog is inferior to img_assistant’s.

Something I haven’t tried: I like the ideas of the Media Manager module, but it’s hardly feature-complete or even stable at this point.

Maybe in the end I’ll have to settle for using a service such as Flickr or Picasaweb with some integration module. That would be quite a bummer, actually.

Because I was in a time-squeeze at that time, having the images hosted elsewhere was actually the last-minute solution that I chose for anything more involving than a few loose images.

Then, there’s still audio and video, but I think I really have to save that for a later time, although if this makes me choose for a the Asset module, for example, I might be totally screwed if I’ve already come to depend on another (incompatible) set of modules for image management.

Also, there’s an annoying bug in Image Uploading module.

This post applies to Drupal 5, while both that website and the website I’m working on now run on Drupal 6.

As a sidenote, the upgrade from Drupal 5 to Drupal 6 at the time was a total disaster, probably due to all the messing with modules and ended up with me painstakingly reconstructing all content from an SQL backup. 🙁

100th post!

Fireworks reflect off the waters of Pickering Wharf in Salem, MA while the "Friendship" takes it all in.

Fireworks reflect off the waters of Pickering Wharf in Salem, MA while the Friendship takes it all in. Photograph by Flickr user snowriderguy.

I just published the 100th post here on blog.bigsmoke.us. Who would have thought that when I published my first post?

(Actually, that first post, although the first post to have been published through this blog, is no longer chronologically the first, not since I started backposting my older regular website content on this blog.)

Hopefully, the 1000th post will be a bit sooner than the 100th post; I still keep stumbling upon issues that I wish I had blogged about so that I don’t have to solve them twice. Also, there’s a lot of content that got stuck in the feeling of formality that was induced by having to give it a permanent place on a static website. That feeling made me want to elaborate beyond what was actually in my head at any given moment. This blog induces less and less of such inhibitions, which in turn generated more and more content.

Styling XML SVN logs with CSS

My friend, Wiebe, keeps his website in Subversion. (Always keep your project files in version management or you’ll be sorry.) He used to manually track the date with the last significant change in each file (because who cares about typos, right?). But, of course, he kept forgetting to update this when he actually made such changes. So, he decided that he wanted to publish the full SVN log for each page.

The raw SVN logs are a bit raw, reason enough to try to turn it in something prettier. Luckily, there’s no need to parse the log files, because svn log has a command-line option, --xml. This option causes the log file to be printed in a simple XML format:

<?xml version="1.0"?>
<log>
<logentry revision="345">
<author>halfgaar</author>
<date>2009-05-25T10:50:07.560914Z</date>
<msg>Added very useful note to index about an awkward sentence.
</msg>
</logentry>
<!-- Snipped the rest of the logentry elements -->
</log>

Now we can use any number of ready-to-use XML tools to process this log, but I figured that, maybe, a very simple solution could work: CSS. Cascasing Stylesheets can be used for more than just styling HTML. One of the few differences is that with non-HTML XML, there are no defaults for the CSS properties (and aren’t we always trying to discover and override the various browser-specific CSS defaults anyway?)

First, we want to add a <?xml-stylesheet?> processing instruction to the log file:

svn log --xml example_file.xhtml | sed -e '/<\?xml / a<?xml-stylesheet type="text/css" media="screen" href="/css/svn-log.css"?>'

The XML file now references the CSS file that we’re going to make:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" media="screen" href="svn-log.css"?>
<!-- snip -->

svn-log.css:

log {
 :;
 :('http://svn.collab.net/repos/svn/trunk/notes/logo/256-colour/subversion_logo-200x173.png');
 :;
 :;
 :;
 :;
 : 2em 204px 2em 5ex;
}
 
logentry {
 :;
 :;
 : 1em;
 :;
 :;
 : #999;
}
 
author {
 :;
}
 
date {
 :;
 : 10ex;
  /* If Firefox would support font families even when you force a font,
     I could use 'overflow: hidden' to hide everything except the date part of <date>. */
 :;
 :; 
 :;
 :;
 : 110%;
 : #7488a7;
}
 
msg {
 :;
 : pre-wrap;
 :;
}

We now have a nicely formatted log file. Other things you could do:

  • Add styles for printing (in a separate stylesheet or by using @media blocks).
  • Display the revision author instead of hiding it.

Of course, you could do all this and much more with XSLT, but that’s just all too obvious. 🙂

If you want to see the stylesheet in action, take a look at Wiebe’s website and look for a View revision log of this page link in the footer of any of his pages.

XML SVN log styled with CSS

XML SVN log styled with CSS

Some new (upcoming) PostgreSQL features

These are some random new PostgreSQL features that I’m interested in:

  • The EXECUTE USING feature in PostgreSQL 8.4 will allow the use of more secure dynamic SQL in PL/PgSQL.

  • User defined exceptions in PostgreSQL 8.4 are a very exciting feature to me. In our unit tests we often check if an exception is properly raised. However, for exception that we raise ourselves, we’ve never been able to check which exception is raised.

    Another exciting possibility is that this will allow us to come up with a very clean validation scheme that produces exceptions that we’ll be able to use in the client web GUI.

  • WITH queries in PostgreSQL 8.4 will allow some very cool things, the coolest of which is something that I’ve wished for on more than one occasion: recursion.

  • The introduction of proper support for the SQL standard XML Type makes me wish that my favorite web hosting provider would support a real database besides their standard MySQL offering.

  • Enumerated Types will make some of my table definitions slightly clearer.

    -- This isn't too shabby (thanks to the CHECK constraint):
    CREATE TABLE persons (
    the_gender CHAR(1) CHECK (gender = 'm' OR gender = 'f')
    );
     
    -- But, I like this much better:
    CREATE TYPE gender AS ENUM ('male', 'female');
    CREATE TABLE persons (
    the_gender gender
    );

Extra kudos to the PostgreSQL development team for their accelerating pace! 😀

Blog posts don’t need a point

I take blogging very literal. For me, the primary use of a weblog is to keep a log of (complicated) thoughts and activities. The reason to keep a log is very self-evident: to be able to find out how and why I came to some solution or how far I was in the problem-solving process. This becomes ever so clear to me when I find myself confronted with finding out something which I’m sure I already did.

Most of the time I still don’t think about blogging my thoughts because I associate writing with making a point and supporting that point well. That association is a mistake. Instead, I would like to cultivate the following reasons to blog:

  1. Writing is fun because sharing is fun.
  2. Writing is fun because reiterating an experience is liberating.
  3. Redoing my research and problem-solving is not fun.
  4. Receiving comments to your writing is fun.
  5. The very act of writing down an unsolved problem often reveals the solution.
  6. If it doesn’t, some visitor will.
  7. Often a problem is really not a problem at all. Trying to formulate such a problem will make this painfully obvious.

Blog posts don’t need a point, blogging is the point.

« Older posts Newer posts »

© 2024 BigSmoke

Theme by Anders NorenUp ↑