Complying to “Do Not Track” browser settings

Do Not Track (DNT) is a privacy preference that users can set in their web browsers. Twitter has announced support for this new standard.

If you care about privacy, you would want to implement this on your websites. This is really simple because a browser that supports it will send a HTTP header "DNT". Value 1 means opt out and 0 opt in.

So just read the header and do your magic (or not according to the setting).

In PHP you can do the following:

if( empty($_SERVER['HTTP_DNT']) ) {
  // Put your tracking code here
}

Do Not Track is supported by Firefox 5+, Internet Explorer 9+, and Safari 5.1+.

More information on DNT:

VirtualHost rewrite rules for Silex

After seeing Igor Wiedler‘s presentation on symfony Day I really wanted to try SIlex. It’s a PHP micro-framework that seems especially well-suited for creating small sites and API’s.

The Silex documentation lists the Apache rewrite rules when using a .htaccess file:

  <IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On
    #RewriteBase /path/to/app
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
  </IfModule>

But if possible, I put the Apache rewrite rules into the VirtualHost configuration. This requires to change the rules a bit. Namely adding a slash to index.php.

VirtualHost settings:

    Options -MultiViews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ /index.php [L]

So I hope this will be useful to someone. Happy coding!

Free fonts for presentations

For presentations it is always good to have nice looking and readable fonts. Usually I publish my presentations as PDF on Slideshare. Because fonts are embedded in the PDF document they should be free to use. I have been looking around for quite a while and have tried various fonts. At the moment I use the following set of fonts.

Fonts
Calluna Sans Body text (Sans-Serif)
Calluna Title, quotes (Serif)
Inconsolata Code (Monospace)
Architect's Daughter Notes (Handwritten)

A collection of free fonts is available from Google web fonts. Inconsolata and Architect's Daughter fonts are in there. The complete collection is available as a mercurial repository:
hg clone https://googlefontdirectory.googlecode.com/hg/ googlefontdirectory

Mobilism Workshop Frankfurt

Lately, I have been looking into development for the mobile web. Fortunately I was offered the opportunity to host a mobile web workshop in Frankfurt on 28 + 29 Sept. 2011 as part of the Mobilism Workshops Series.

Mobilism workshops are a two-day affair where at least half of the time is spent in actually testing websites on mobile devices; including a few you’ve never even heard of. The other half of the time is taken up by PPK and Stephen Hay talking about various aspects of mobile web design and development.

So if you are interested and live in Germany, register for the workshop.

Getting host interface networking to work again in VirtualBox

After installing a new version of openSUSE I had some issues with VirtualBox. Before the install I exported my virtual machines (VM) as appliances. This makes it easy to re-use VMs without having to install an OS from scratch. Exporting and importing is literally as easy as clicking a button.

Unfortunately after importing my VMs, I got the following error message:

Failed to open a session for the virtual machine Windows.



Failed to open/create the internal network ‘HostInterfaceNetworking-eth0′ (VERR_SUPDRV_COMPONENT_NOT_FOUND).



One of the kernel modules was not successfully loaded. Make sure that no kernel modules from an older version of VirtualBox exist. Then try to recompile and reload the kernel modules by executing ‘/etc/init.d/vboxdrv setup’ as root (VERR_SUPDRV_COMPONENT_NOT_FOUND)

Running /etc/init.d/vboxdrv setup actually did not help. I was told the kernel module was already installed. Running the network in NAT mode worked. Only the bridged adapter option caused this error and I really needed that option to communicate between VMs over ssh.

After some searching, it turned out that openSUSE had installed the VirtualBox guest kernel module. That is apparently useful if you run openSUSE inside VirtualBox. But I was running VirtualBox inside openSUSE.

So in Yast I added the virtualbox-host-kmp-desktop package and removed all virtualbox-guest-* packages. Rebooted and problem solved!

Using pretty URLs in concrete5 with Nginx

The Nginx web server is becoming ever more popular as an alternative to Apache. Especially if you want to use the PHP FastCGI Process Manager (php-fpm) that shipped with PHP 5.3.3.

Lately I have been using the concrete5 CMS a lot. It offers an option to use pretty URLs, but only tells how to configure it for Apache. After reading the Nginx documentation and searching the web I came up with a simple configuration (tested with nginx-0.8.54).


http {
  include mime.types;
  default_type application/octet-stream;
  sendfile on;
  keepalive_timeout 65;
  access_log logs/access.log;
  index index.html index.php;

  #default server
  server {
    listen 80 default_server;
    server_name _;
    root html;
  }

  #concrete5
  server {
    server_name concrete5.com www.concrete5.com;
    root /srv/www/vhosts/concrete5.com;
    access_log logs/concrete5.access.log;

    location / {
      try_files $uri $uri/ /index.php/$request_uri;
    }

    #pass PHP scripts to FastCGI server
    location ~ \.php($|/) {
      set $script $uri;
      if ($uri ~ "^(.+\.php)(/.+)") {
        set $script $1;
      }

      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root$script;
      fastcgi_intercept_errors on;
      fastcgi_pass 127.0.0.1:9000;
    }
}

Converting URLs to links with PHP

While trying to read user timelines from the Twitter API, I found out that the tweets are only available in plain text. Of course, it is nicer (and more usable) if URLs are actually displayed as links. With a little use of regular expressions, this can easily be done.

But if you have long URLs and are displaying tweets in a relatively narrow column, this leads to a problem. Your tweets can have large gaps, depending how your browser puts line breaks in URLs. Some browsers break on slashes, some on dashes, on both or not at all. So I wrote a small function in PHP to add zero width breaks to links. Because I want to determine how links break and not leave it up to some random browser.


function linkify($str) {

    return preg_replace_callback('@(https?://)(\S+)@smu', 'linkify_callback', $str);

}



function linkify_callback($matches)

{

    $title = str_replace(

        array('/', '.', '-'),

        array('/&#x200B;','.&#x200B;', '-&#x200B;'),

        $matches[2]);



    return '<a href="' . $matches[1] . $matches[2] . '">' . $matches[1] . $title . '</a>';

}

And in case you are wondering. Yes, I do not like to use URL shorteners.

Validating email addresses in PHP made simple

An important aspect of processing user input on a website should be filtering it. Primarely for security reasons, but also to have valid data. Since PHP 5.2 it is very easy to validate (and sanitize) user input using the filter functions. But a lot of PHP developers seem not to be aware of them and create their own filters using regular expressions. Which is very easy to get wrong. So I highly recommend the built-in PHP filters.

Here is a simple example for validating email addresses:

if( !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ) {
    echo 'Invalid email address';
}

Because who needs invalid data?

Activating translations for Yii core messages

The excellent Yii framework makes it easy to jumpstart development and quickly create a working prototype. It also includes flexible translation features. But the official documentation for internationalization isn’t all that clear on how to activate the translations for the Yii core messages. A lot of translations are included in the default download.

Turns out that you have to define both the source language and the target language. The default source language is english, but it only seems to work if you define it explicitly.

To activate translations for your entire app, change “protected/config/main.php” accordingly:


return array(
  …
  'language' => 'de',
  …
  'components'=>array(
    …
    'coreMessages' => 'en',
    …
 &nbsp),
  …
);

Modernism & Post-Modernism in Web Design

Here are the slides of my talk at Web Montag Frankfurt