Remove all blocks from a Drupal theme

Very useful when moving towards Features:

DELETE FROM blocks WHERE theme = 'your_theme_name';

From drush sql-cli, of course.

This is especially useful when building a subsite, for which I'm now mostly convinced by Sections.

(mdb to) csv to MySQL

Quick and dirty PHP script to turn a CSV file into a table in a MySQL database. Used for a Drupal project, so I ran it with drush php-script. Couldn't find anything better online. Feel free to use it.

If I need it again some time I will probably make it a bit nicer (I might also make it nicer if you ask me nicely and/or pay me to do it).

In the project I'm using it, I first converted an .mdb file to .csv with mdbtools.

<?php

$handle = fopen("/tmp/test.csv", "r");
$headers = fgetcsv($handle);
$sql = 'CREATE TABLE test_csv (';
foreach ($headers as $field) {
    $field = strtolower($field);
    $sql .= strtolower($field).' VARCHAR(255), ';
}
$sql .= ')';
$sql = str_replace('), )', '))', $sql);
echo $sql;

// db_query('DROP TABLE test_csv');
db_query($sql);

while ($data = fgetcsv($handle)) {
    $sql = 'INSERT INTO test_csv VALUES (';
    foreach ($data as $field) {
        $sql .= '"' . $field . '", ';
    }
    $sql .= ')';
    $sql = str_replace(', )', ')', $sql);
    db_query($sql);
}

Rewrite Rules (not) - Lowercase URLs, but only for some specific paths

This took me enough time to get right to post a little blog post about it:

        RewriteEngine on
        RewriteMap lc int:tolower
        RewriteCond %{REQUEST_URI} (shared|Shared|download|Download)/[A-Z]
        RewriteRule (.*) ${lc:$1} [R=301,L]

Note that this doesn't work in .htaccess - you have to put it higher up in the Apache configuration.

I tried extra RewriteConds, to no avail, somehow Apache seems to add [OR]s anyway, even though the documentation states that you have to specify them (there is no [AND] directive). I tried adding the "shared" and "download" to the RewriteRule, leading to infinite redirects. Of course adding [NC] to the RewriteCond will also lead to infinite redirects.

Apache configuration is so much fun.

Recursively create lowercase symlinks to filenames with uppercase letters - in Python

I'm working on a project to convert a big ASP website into Drupal. On Windows OSes there is not really a distinction between upper and lower case characters in filenames. At first I thought to just leave the capitals, but on web pages links were sometimes with capitals and sometimes lowercase. So I added some stuff to the Apache configuration, usually inside the VirtualHost directive (this does not work in .htaccess):

        
        RewriteEngine on
        RewriteMap lc int:tolower
        RewriteCond %{REQUEST_URI} [A-Z]
        RewriteRule (.*) ${lc:$1} [R=301,L]

But that wasn't all. For the project I'm parsing thousands of ASP files and the plan is to do this everyday while the existing website is updated. We're rsyncing files to be parsed, and the recursively rename to lowercase script I found is nice but it's not very efficient to copy and rename almost 3 GB everyday. I wrote a little Python script in the train today to create lowercase symbolic links to file and directory names with uppercase letters. The hardest part was to properly change directories - it's important to change into the directory the symlink is created but at the end of an os.walk it's necessary to get back to the current working directory.

I'm sure it can be useful to other people dealing with similar issues...

lowlink.py

#!/usr/bin/env python
"""
lowlink.py

Recursively creates lower case symlinks to filenames with uppercase letters.

Created by Kasper Souren in 2010, consider this public domain, copy and re-use freely.
"""

import os

def lowlink(path = '.'):
    cwd = os.getcwd()  # os.walk can't handle path changes very well 
    for root, dirs, files in os.walk(path):
        # change directory for symlink creation
        os.chdir(os.path.join(cwd, root))
        print root
        for name in files + dirs:
            lowname = name.lower()
            if name != lowname and not os.path.exists(lowname):
                os.symlink(name, lowname)
        os.chdir(cwd) # restore path for os.walk

lowlink()
my working setup

Support for Dutch sites in Drupal Service Links

For my little project site about swimming pool construction I decided I needed some way to spread links better over Dutch sites. So I hacked around a little bit in Drupal's Service Links module and I just uploaded some files to support nujij en eKudos. I want to add some more Dutch sites, but there ain't that many it seems. The result can be viewed on the individual articles pages of my blog - there's still some work on Service Links before it can be conveniently shown on the main page.

Ads are back - this time FLOSS only though!

This month I found out about the free software advertising network. I took the opportunity of moving my blog to Drupal to add ads for ethical computing, approved by the Free Software Foundation: "The Free Software Community now has an ethical alternative to ad networks that promote proprietary software".

Damn, I'm even tempted to click on these ads myself!

Moving my blog from WordPress to Drupal

WordPress is a great blogging platform. I've been using it for a couple of years now for my blog. However, with some small exceptions I haven't really dived deeper into it. Since most of my professional time (and a lot of my hobby time) goes into Drupal I started looking into moving my blog to Drupal. I've also been thinking about how I want to publish more about the work I've been doing.

So I naturally came across the WordPress import module and started playing with it. It was mostly great. I had some password protected pages on my WordPress blog. The module didn't really handle these, it didn't even inform the user about these pages. I posted an issue and the module got updated a while ago. drupal.org still seemed a bit weird in its inner workings, but since this WordPress issue I got back into it again. Anyway, now the pages are just left unpublished, which is good enough for me.

Views has a nice monthly archive view to replace the archive functionality in WordPress, but the links to archives in WordPress look like guaka.org/2010/02, which is currently a bit harder to achieve in Drupal. It would be possible with a smart .htaccess rule but I found out that Google and Yahoo haven't indexed any of these archive pages, which makes it much less urgent to fix this.

Fixing tags and categories URLs took a little bit of tampering with pathauto, and I don't think it's completely working already, but I don't mind a minor SEO penalty for a couple of broken links if it allows me to add a lot more and varied content to guaka.org.

For the theme I decided to give Acquia Prosper theme a try. Through the Skinr module it becomes really easy to make quick changes. I decided to be lazy for now and used the CSS injector instead of subtheming Prosper.

So as it stands I'm happy enough with the current state of guaka.org and I'm going to switch right now...

I'm going to FOSDEM

I'm going to FOSDEM, the Free and Open Source Software Developers' European Meeting

memcache doesn't necessarily speed up your Drupal sites

Sites that show up quickly on a user's screen tend to keep the user's attention for longer and also rank better in Google. So when listening to the excellent Lullabot Podcast 80: Top 40 Drupal Modules Revisited I was caught by Drupal experts stating that Memcache would even speed up your site if it's not a high traffic site. It could off-load the database. I decided to give it a try on a relatively low traffic site of one of my clients. The site is already being served by nginx so the load times are already pretty good. When setting up the experimentation I was a bit confused by the thorough but chaotic instruction to set up memcache. I ran into a problem setting up PECL memcache:
$ sudo pecl install memcache
downloading memcache-2.2.5.tgz ...
Starting to download memcache-2.2.5.tgz (35,981 bytes)
..........done: 35,981 bytes
11 source files, building
running: phpize
Configuring for:
PHP Api Version:         20041225
Zend Module Api No:      20060613
Zend Extension Api No:   220060519
shtool at '/tmp/pear/temp/memcache/build/shtool' does not exist or is not executable.
Make sure that the file exists and is executable and then rerun this script.

ERROR: `phpize' failed
Since I run Debian I solved this by running apt-get install php5-memcache instead. I restarted php-fastcgi (needed for nginx) and added $conf['cache_inc'] ='sites/all/modules/memcache/memcache.db.inc'; to settings.php. Then I ran some tests in Hammerhead.  Not on the front page since there is an embedded Youtube video. I chose a page without any external elements. I was a bit confused at first, and ran several short tests. I forgot to log out and the memcache module was adding a lot of extra information in the bottom.  I thought that was the reason that my site was a lot slower with memcache than without it.  So I logged out and tried again:
count latest median avg
empty cache with memcache 4 1449 1449 1759
primed cache with memcache 4 1277 1186 1184
empty cache without memcache 4 1239 1283 1483
primed cache without memcache 4 1014 900 950
It could be that I'd have to tweak some memcache settings, or run longer tests, but I think these numbers are clear enough: memcache made my site slower instead of faster!

Adding Group overview to CiviCRM contact summary page

Intal's CiviCRM needed some customizations. So I delved into CiviCRM's templating system, which is based on smarty. Most things were pretty easy but it took some more time to figure out how to add the Group overview to the Contact Summary. In sites/default/civicrm_custom/CRM/Contact/Page/View/Summary.tpl I added to the appropriate spot. {include file="CRM/Contact/Page/View/GroupContact.tpl"} In order to keep my customizations separate from the core CiviCRM code I tried adding the following lines to the template. {php} require_once 'CRM/Contact/Page/View/GroupContact.php'; CRM_Contact_Page_View_GroupContact::browse(); {/php} But that did not work unfortunately. So for now I stick with adding the following lines to CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View::view() in sites/all/modules/civicrm/CRM/Contact/Page/View/Summary.php: require_once 'CRM/Contact/Page/View/GroupContact.php'; CRM_Contact_Page_View_GroupContact::browse(); There should be a nicer solution that doesn't require hacking core CiviCRM code...

A job?! And, time tracking in Drupal?

I'm looking for a decent time tracking tool for Drupal, both for my freelance work as well for my employer, Intal. Briefly, Intal is an NGO working with partner NGOs in many countries (and places), among which Philippines, Congo, Gaza, Cuba and Colombia, in the fields of health care, development, peace and human rights. It would be cool if there was Drupal based solution for time tracking that would integrate well with OpenAtrium so that we can replace the OpenOffice spreadsheets currently in use. By the way, at Intal I'm also working a lot with Ubuntu, LTSP, CiviCRM and solving general office IT issues.
Syndicate content