Hairy .htaccess Dreamhost WordPress Problem Solved! [en]

[fr] Résolution d'un problème qui m'a littéralement empoisonné mes vacances. Ouf.

Thanks to grimboy, my “parent” .htaccess now has two extra lines and looks like this (and the problem that has kept me awake for the last week is solved):

AddDefaultCharset OFF
# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/membres.*$ [OR]
RewriteCond %{REQUEST_URI} ^/failed_auth.html$
RewriteRule ^.*$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php

# END WordPress

Thanks so much!

Hack: Make Bunny Tags Point to Your Blog Tagspace [en]

[fr] Un petit bidouillage pour que mon plugin wordpress pour ajouter des tags ne montre (dans Technorati) que les billets de votre propre blog.

Here’s a quick hack for all of you who, like Fabienne, are disappointed that my Bunny’s Technorati Tags plugin points to the technorati tagspace instead of just your own posts.

For it to work, your plugin files need to be writable (how to do this is beyond the scope of this post, but try looking for a way to chmod 777 or whatever in your FTP program; if you use the command line, then chmod -R 777 wp-content/plugins should do it). Then, open the plugin editor (WP admin screen > Plugins > Plugin Editor) and edit the file for Bunny’s Technorati Tags.

Look for this code:

 $tag_link='<a href="' . urlencode(urldecode($tag))
 . '" title="' . __('See the Technorati tag page for', 'BunnyTags') . ' ''
 . urldecode($tag) . ''." rel="tag">' . $display_tag . '</a>' . $separator;
 // make a link to the technorati tag page, with tag link text

And replace it with this:

 $tag_link='<a href="' . urlencode(urldecode($tag))
 . '?from=' . get_settings('home') . '" title="'
 . __('On Technorati: see posts from this blog tagged', 'BunnyTags') . ' ''
 . urldecode($tag) . ''." rel="tag">' . $display_tag . '</a>' . $separator;
 // make a link to the technorati tag page, with tag link text

This isn’t quite the same as pointing them to a page on your blog which contains all the posts. But the final result is pretty similar. Otherwise, Fabienne says that Jerome’s Keywords Plugin does the trick for her.

Getting Rid of www [en]

[fr] Une recette pour faire disparaître magiquement ce satané "www" des noms de domaines que j'héberge...

I personally hate having “www” in front of a domain name. It’s redundant. If we’re visiting a website, we’re on the web anyway. It also brings no end of problems when people start writing for the web and creating links, because they think that what makes something a “website address” is the “www” in front if it, instead of “http://”. That’s how they end up with links like “” on their sites. But I digress.

On one of the sites I manage, we have a restricted members-only area. However, our users started reporting that when they used “www” in front of the domain name, they were being asked for the password twice. I tried myself, and I was simply asked for the password ad aeternam. Probably a server configuration glitch somewhere.

Anyway, I decided the simplest solution was to redirect all “www” requests to the non-www domain. I know I had that in place for CTTS at some point, but the setting must have got lost at some point. Instead of sticking rewrite rules in .htaccess as suggests, I modified my vhost configuration slightly so that it looked like this:

DocumentRoot /home/example/www/
ErrorLog logs/example-error
CustomLog logs/example-access combined

Redirect permanent /

Try it!

Many thanks to those who gave suggestions and nudged me along the way to this solution.

Problèmes d'encodage MySQL [fr]

Un joli mélange de latin-1 et d’utf-8 dans ma base de données. Un script python pour nettoyer tout ça.

[en] I've been to MySQL encoding hell and back. The little question marks you may have seen in place of accented characters a few weeks back were caused by a lovely mix-up of utf-8 and latin-1 inside my databases. Dda_ from #joiito kindly helped me by writing a python script to identify fields with non-utf-8 characters in them, and convert them back.

Vous avez peut-être remarqué, il y a une semaine ou deux, que les accents de ce site avaient été remplacés subrepticement par de vilains points d’interrogation. Une fois de plus, je me trouvais dans la situation où je croyais avoir de l’utf-8 dans mes bases de données, pour réaliser ensuite qu’il s’agissait en fait de latin-1. Et cette fois, c’était encore bien pire qu’avant: j’avais un mélange d’utf-8 et de latin-1.

Dda_ a eu la grande gentillesse de passer plusieurs heures à  me pondre un script en python qui fait le tour de tous les champs de toutes les tables de toutes les bases de données, et les convertit en utf-8 s’il y détecte des caractères non-utf-8 (ce qui signifierait, dans mon cas, qu’on se trouve en présence de latin-1). Une fois que c’est fait, le script va changer l’encodage des tables pour que tout nouveau contenu y soit stocké en utf-8.

Bref, voici l’explication et le script.

Simple Technorati Tags Plugin for WordPress [en]

A simple plugin for WordPress which lets you display tags (or keywords) in your posts. Tags are stored in a Custom Field (no database modification required).

[fr] Un plugin simple pour WordPress qui vous permet de garnir vos billets de 'tags' (étiquettes) qui seront compris et interprétés par Technorati. Ce plugin ne modifie pas la base de données, et permet l'affichage de tags stockés dans un Custom Field nommé "tags", sous forme de liste de mots séparés par des espaces. Il est aussi possible d'afficher ainsi des mots-clés se trouvant dans un Custom Field nommé "keywords".

Update 31.01.07: The wiki isn’t allowing edits anymore. The plugin has been updated to version 0.6, compatible with WordPress 2.1, by Sudar. Get Bunny Tags.

Update 21.01.05: Please see Bunny’s Technorati Tags on the wiki for information about this plugin!

As isn’t letting me in yet, here is a little post to announce my first real live plugin for WordPress (one can’t exactly say that Batch Categories is a proper plugin).

Bunny’s Technorati Tags (zip, phps) provides you with a template function that you can use to easily display Technorati tags for your posts. The tags are stored in a Custom Field, so this plugin does not require any modifications of the database structure. The plugin has not been thoroughly tested on different versions, though it works fine on my recent 1.5 nightly. As it is really very basic, I don’t believe you’ll run into any major compatibility issues on other versions (do keep me informed, though).

Once you’ve installed and activated the plugin (manually or with the Plugin Manager, enter a space-separated list of tags in a Custom Field named “tags”, and place the following code in your template where you want the list of tags to appear:

<php the_bunny_tags(); ?>

If you’re like me and you’ve been painfully entering comma-separated keywords for your posts using a Custom Field of same name, you can use the following line to use these existing keywords as tags:

<php the_bunny_keyword_tags(); ?>

Update 21.01.05: by setting $bunny_strict to false (see SETTINGS at the top of the plugin code) you will display keywords as tags for posts which do not have tags.

This might not be the greatest idea, as I believe tagging and choosing keywords is a different process, but it makes me happy for the moment, so I thought I’d share this possibility with you too.

Future development of the plugin includes adding a text input to the “Create New Post” form for easy tagging. (Coming as soon as I can figure out how to do it.)Done!

Plugin available on and

Update 21:40 Who’dathunkit? Version 0.2 is out already, with a nice little “Tags” field in the post editing form. the_bunny_keyword_tags() has been revised to display keywords only when no tags are present. All the tagging pleasure is yours to take!

Update 21.01.05 Version 0.3 is out. Upgrade strongly recommended, or your tags won’t be indexed correctly by Technorati.

Fixing Newline Abuse in WordPress [en]

Newlines had crept into some of my old posts and corrupted the formatting. Quick and dirty script I used to solve the problem.

[fr] Des retours à  la ligne excédentaires se sont glissés dans mes anciens posts à  un moment donné, cassant des liens et le formattage en général. J'ai utilisé un petit script pour supprimer tous les retours à  la ligne de ces posts.

I only realised right now how badly broken about 500 of my old posts where. Somewhere in the process, newlines got added at the end of each line, and not just at the end of each paragraph. As WordPress kindly and intelligently adds the necessary HTML markup for paragraph and line breaks in posts, this meant that lots of my posts had broken links (when the newline occurred in the middle of a link) and uneven lines.

Victims: about 500 posts.

Solution: luckily, all the concerned posts had complete HTML formatting in them. Purely and simply removing all the newlines with a short PHP script was the way to go.

Thanks to all those who helped. You probably won’t be able to use the script as is, but if you have a similar problem at some point, it might help. The script pulls out the posts from the WordPress database, removes the newlines, and puts the post back into the table.

Easier TopicExchange Trackbacks for WordPress [en]

A WordPress hack which makes it quicker to add TopicExchange channels to trackback, and makes them visible (like categories) in the weblog. (Sorry for the duplicate postings, trying to fix it.)

[fr] Ce 'hack' pour WordPress permet d'ajouter facilement des trackbacks vers les canaux de TopicExchange, et liste sur le weblog les canaux concernés pour chaque billet.

Here is a solution to make it a little quicker to trackback TopicExchange channels with WordPress, and make those channels visible in your weblog.

I love TopicExchange. When I asked Suw what they had talked about during BlogWalk, she mentioned trackbacks. I asked if anything had been discussed about trackback etiquette. For example, I’m often tempted to trackback people who have written posts related to mine, but which I haven’t linked to. Well, the consensus is that this is not what trackback is for. Trackback is really for making a “backlink”. TopicExchange is the answer to the “related posts” issue.

I’ve been using TopicExchange a lot during the last weeks, but nobody has noticed it, apart from those people who already use TopicExchange as a source of information. As Seb Paquet notes, TopicExchange needs to be made more viral. It needs visibility. What follows is my interpretation of “making ITE easier to use, and more visible.”

This WordPress hack creates an extra field in the posting form where ITE channel ID’s (e.g. “wordpress”, “multilingual_blogging”) can be entered (I was tired of typing the whole trackback URL’s all the time). It then stores these channel ID’s as post meta data (in the postmeta table), so that it can retrieve them and display links to the corresponding channels along with the post, just as is usually done with categories.

First of all, add the following code to my-hacks.php. Then, edit post.php (in your wp-admin directory) and add this code where indicated (the comment at the top of the file explains where to insert the code).

Also in post.php, after the line add_meta($post_ID);, insert the following code:

// add topic exchange channels
		$_POST['metakeyselect'] = 'ite_topic';
		foreach($topics as $topic)
    		$_POST['metavalue'] = $topic;

In edit-form.php, add this code to create an extra input field for ITE trackbacks:

$form_ite = '<p><label for="ite-topic"><strong>Trackback</strong> TopicExchange:</label>
(Separate multiple channel ID's with spaces.)<br />
<input type="text" name="ite-topic" style="width: 360px" id="ite-topic"
tabindex="8" /></p>';

It goes near the top of the file, after the line which defines $form_trackback (do a search for that and you’ll find it).

Finally, in your index.php template, you can use <?php the_ite_channels(); ?> to display a paragraph containing a comma-separated list of channels trackbacked for each post. If you want to change the formatting, play around with the function definition in my-hacks.php.

If, like me, you have old posts with trackbacks to TopicExchange, and you would also like these to appear on your posts, use this patch from inside wp-admin. The patch will tell you what meta data it is adding — just load it once in your browser and check the result in your weblog. (Don’t load it twice — it’s supposed to be able to check the existing channels in the database to avoid duplicate entries, but I haven’t got it to work. Read instructions and debug notes at the top of the patch file.)

In future, it will also be possible to use the TopicExchange API to return the “nice title” for the channels listed — so we sould have “Multilingual blogging” instead of “multilingual_blogging”. (I’ve asked, it will behas been added to the API.)

Good luck with this if you try it, and as always, comments most welcome!

Note: as far as I have tested, the code seems to work now.

Converting MySQL Database Contents to UTF-8 [en]

I finally managed to convert my WordPress database content to UTF-8. It’s easy to do, but it wasn’t easy to figure out.

[fr] Voici comment j'ai converti le contenu de ma base de données WordPress en UTF-8. C'est assez simple en soi, mais ça m'a pris longtemps pour comprendre comment le faire!

A few weeks ago, I discovered (to my horror) that my site was not UTF-8, as I thought it was. Checking my pages in the validator produced this error:

The character encoding specified in the HTTP header (iso-8859-1) is different from the value in the XML declaration (utf-8). I will use the value from the HTTP header (iso-8859-1).

In all likeliness, my server adds a default header (iso-8859-1) to the pages it serves. When I switched to WordPress, I was careful to save all my import files as UTF-8, and I honestly thought that everything I had imported into the database was UTF-8. Somewhere in the process, it got switched back to iso-8859-1 (latin-1).

The solution to make sure the pages served are indeed UTF-8, as specified in the meta tags of my HTML pages, is to add the following line to .htaccess:

AddDefaultCharset OFF

(If one wanted to force UTF-8, AddDefaultCharset UTF-8 would do it, but actually, it’s better to leave the possibility to serve pages with different encodings, isn’t it?)

Now, when I did that, of course, all the accented characters in my site went beserk — proof if it was needed that my database content was not UTF-8. Here is the story of what I went through (and it took many days to find the solution, believe me, although it takes only 2 minutes to do once everything is ready) to convert my database content from ISO-8859-1 to UTF-8. Thanks a lot to all those who helped me through this — and they are many!

First thing, dump the database. I always forget the command for dumps, so here it is:

mysqldump --opt -u root -p wordpress > wordpress.sql

As we’re going to be doing stuff, it might be wise to make a copy of the working wordpress database. I did that by creating a new database in PhpMyAdmin, and importing my freshly dumped database into it:

mysql -u root -p wordpress-backup < wordpress.sql

Then, conversion. I tried a PHP script, I tried BBEdit, and they seemed to mess up. (Though as I had other issues elsewhere, they may well have worked but I mistakenly thought the problem was coming from there.) Anyway, command-line conversion with iconv is much easier to do:

iconv -f iso-8859-15 -t utf8 wordpress.sql > wordpress-iconv.sql

Then, import into the database. I first imported it into another database, edited wp-config.php to point to the new database, and checked that everything was ok:

mysql -u root -p wordpress-utf8 < wordpress-iconv.sql

Once I was happy that it was working, I imported my converted dump into the WordPress production database:

mysql -u root -p wordpress < wordpress-iconv.sql

On the way there, I had some trouble with MySQL. The MySQL dump more or less put the content of all my weblog posts on one line. For some reason, it didn’t cause any problems when importing the dump before conversion, to create the backup database, but it didn’t play nice after conversion.

I got this error when trying to import:

ERROR 1153 at line 378: Got a packet bigger than 'max_allowed_packet'

Line 378 contained half my weblog posts… and was obviously bigger than the 1Mb limit for max_allowed_packet (the whole dump is around 2Mb).

I had to edit my.cnf (/etc/mysql/my.cnf on my system) and change the value for max_allowed_packet in the section titled [mysqld]. I set it to 8Mb. Then, I had to stop mysql and restart it: mysqladmin -u root -p shutdown to stop it, and mysqld_safe & to start it again (as root).

This is not necessarily the best way to do it, and it might not work like that on your system, but it’s what I did and the site is now back up again. Comments welcome, and hope this can be useful to others!

Batch Categories 0.9 [en]

Batch Categories for WordPress has been fixed and enhanced. If you have major category jobs to do, it can probably help you. Feedback and testers welcome.

[fr] Batch Categories pour WordPress a été corrigé et fonctionne à  présent. Le compagnon idéal si vous desirez changer les catégories de nombreux billets en même temps.

Batch Categories 0.9 is out! It’s the ideal companion for large-scale post-import messy category work. List all posts belonging to a category or matching a keyword, and edit their categories, easily visible at a glace with a collection of sexy drop-down lists. What’s new since the the first draft?

  • It now works, and does not “eat” categories without a warning. (Pretty nice of it, huh?)
  • It tells you what it did — which categories it added to which posts, and which ones it removed.
  • Add a whole bunch of posts to a category with one click.
  • Remove a whole bunch of posts from a category with one click.
  • Ensures that all the categories for a post are always listed, whatever the setting for the limit number of drop-down lists.
  • This is what it can look like.

You can still access it as a plugin or edit the Edit navigation menu, as described in my post introducing Batch Categories. If you’re in a hurry, just drop the PHP file into your wp-admin directory and send your browser straight on it.

Next steps?

  • Gather feedback from courageous testers (please don’t blame me if you haven’t backed up your post2cat table and things go wrong) for chasing the last bugs, improving interface and functionality.
  • Redo the code which generates the drop-down lists to take advantage of the category cache, and avoid flooding the database with useless queries.
  • Allow more subtle selection of posts: combinations of categories (AND/OR/NOT), categories without their subcategories…
  • Anything else you would want…?

Update 24.07.04: BB made me notice that “All” and “None” didn’t make much sense in the drop-down which allows one to select the categories to display. Replaced them in v. 0.91 by “Any category”.

Life and Trials of a Multilingual Weblog [en]

Here is an explanation of how I set up WordPress to manage my bilingual weblog. I give all the code I used to do it, and announce some of the things I’d like to implement. A “Multilingual blogging” TopicExchange channel is now open.

[fr] J'explique ici quelles sont les modifications que j'ai faites à WordPress pour gérer le bilinguisme de mon weblog -- code php et css à l'appui. Je mentionne également quelques innovations que j'ai en tête pour rendre ce weblog plus sympathique à mes lecteurs monolingues (ce résumé en est une!) Un canal pour le weblogging multilingue a été ouvert sur TopicExchange, et vous y trouverez peut-être d'autres écrits sur le même sujet. Utilisez-le (en envoyant un trackback) si vous écrivez des billets sur le multinguisme dans les weblogs!

My weblog is bilingual, and has been since November 2000. Already then, I knew that I wouldn’t be capable of producing a site which duplicates every entry in two languages.

I think this would defeat the whole idea of weblogging: lowering the “publication barrier”. I feel like writing something, I quickly type it out, press “Publish”, and there we are. Imposing upon myself to translate everything just pushes it back up again. I have seen people try this, but I have never seen somebody keep it up for anything nearing four years (this weblog is turning four on July 13).

This weblog is therefore happily bilingual, as I am — sometimes in English, sometimes in French. This post is about how I have adapted the blogging tools I use to my bilingualism, and more importantly, how I can accommodate my monolingual readers so that they also feel comfortable here.

First thing to note: although weblogging tools are now ready to be used by people speaking a variety of languages (thanks to a process named “localization”), they remain monolingual. Language is determined at weblog-level.

With Movable Type, I used categories to emulate post-level language awareness. This wasn’t satisfying at all: I ended up with to monstrous categories, Français and English, which didn’t help keep rebuild times down.

With WordPress, the solution is far more satisfying: I store the language information as Post Meta, or “custom field”. No more category exploitation for something they shouldn’t be used for.

Before I really got started doing the exciting stuff, I made a quick change to the WordPress admin interface. If I was going to be adding a “language” custom field to each and every post of mine, I didn’t want to be doing it with the (imho) rather clumsy “Custom Fields” form.

In edit.php, just after the categorydiv fieldset, I inserted the following:

<fieldset id="languagediv">
      <legend>< ?php _e('Language') ?></legend>
	  <div><input type="text" name="language" size="7"
                     tabindex="2" value="en" id="language" /></div>

(You’ll probably have to move around your tabindex values so that the tabbing order makes sense to you.)

I also tweaked the wp-admin.css file a bit to keep it looking reasonably pretty, adding the rule below:

#languagediv {
	height: 3.5em;
	width: 5em;

and adding #languagediv everywhere I could see #poststatusdiv, so that they obeyed the same rules.

In this way, I have a small text field to edit to set the language. I pre-set it to “en”, and have just to change it to “fr” if I am writing in French.

We just need to add a little piece of code in the form processing script, post.php, just after the line that says add_meta($post_ID):

 // add language
	$_POST['metakeyselect'] = 'language';
        $_POST['metavalue'] = $_POST['language'];

The first thing I do with this language information is styling posts differently depending on the language. I do this by adding a lang attribute to my post <div>:

<div class="post" lang="<?php $post_language=get_post_custom_values("language"); $the_language=$post_language['0']; print($the_language); ?>">

In the CSS, I add these rules: {
  content: " [fr] ";
  font-weight: normal;
} {
  content: " [en] ";
  font-weight: normal;
background-color: #FAECE7;

I also make sure the language of the date matches the language of the post. For this, I added a new function, the_time_lg(), to my-hacks.php. I then use the following code to print the date: <?php the_time_lg($the_language); ?>.

Can more be done? Yes! I know I have readers who are not bilingual in the two languages I use. I know that at times I write a lot in one language and less in another, and my “monolingual” readers can get frustrated about this. During a between-session conversation at BlogTalk, I suddenly had an idea: I would provide an “other language” excerpt for each of my posts.

I’ve been writing excerpts for each of my posts for the last six months now, and it’s not something that raises the publishing barrier for me. Quickly writing a sentence or two about my post in the “other language” is something I can easily do, and it will at least give my readers an indication about what is said in the posts they can’t understand. This is the first post I’m trying this with.

So, as I did for language above, I added another “custom field” to my admin interface (in edit-form.php). Actually, I didn’t stop there. I also added the field for the excerpt to the “simple controls” posting page that I use (set that in Options > Writing), and another field for keywords, which I also store for each post as meta data. Use at your convenience:

<fieldset style="clear:both">
<legend><a href=""
title="<?php _e('Help with excerpts') ?>"><?php _e('Excerpt') ?></a></legend>
<div><textarea rows="1" cols="40" name="excerpt" tabindex="5" id="excerpt">
<?php echo $excerpt ?></textarea></div>
<fieldset style="clear:both">
<legend><?php _e('Other Language Excerpt') ?></legend>
<div><textarea rows="1" cols="40" name="other-excerpt"
tabindex="6" id="other-excerpt"></textarea></div>
<fieldset style="clear:both">
<legend><?php _e('Keywords') ?></legend>
<div><textarea rows="1" cols="40" name="keywords" tabindex="7" id="keywords">
<?php echo $keywords ?></textarea></div>
<!-- I moved around some tabindex values too -->

I inserted these fields just below the “content” fieldset, and styled the #keywords and #other-excerpt textarea fields in exactly the same way as #excerpt. Practical translation: open wp-admin.css, search for “excerpt”, and modify the rules so that they look like this:

#excerpt, #keywords, #other-excerpt {
	height: 1.8em;
	width: 98%;

instead of simply this:

#excerpt {
	height: 1.8em;
	width: 98%;

I’m sure by now you’re curious about what my posting screen looks like!

To make sure the data in these fields is processed, we need to add the following code to post.php (as we did for the “language” field above):

// add keywords
	$_POST['metakeyselect'] = 'keywords';
        $_POST['metavalue'] = $_POST['keywords'];
   // add other excerpt
	$_POST['metakeyselect'] = 'other-excerpt';
        $_POST['metavalue'] = $_POST['other-excerpt'];

Displaying the “other language excerpt” is done in this simple-but-not-too-elegant way:


    <div class="other-excerpt" lang="<?php print($the_other_language); ?>">
    <?php print($the_other_excerpt); ?>

accompanied by the following CSS:

background-color: #FAECE7;
background-color: #FFF;
div.other-excerpt:before {
  content: " [" attr(lang) "] ";
  font-weight: normal;

Now that we’ve got the basics covered, what else can be done? Well, I’ve got some ideas. Mainly, I’d like visitors to be able to add “en” or “fr” at the end of any url to my weblog, and that would automatically filter out all the content which is not in that language — maybe using the trick Daniel describes? In addition to that, it would also change the language of what I call the “page furniture” — titles, footer, and even (let’s by ambitious) category names. Adding language sensitivity to trackbacks and comments could also be interesting.

A last thing I’ll mention in the multilingual department for this weblog is my styling of outgoing links if they are written in a language which is not my post language, using the hreflang attribute. It’s easy, and you should do it too!

Suw (who has just resumed blogging in Welsh) and I have just set up a “Multilingual blogging” channel on TopicExchange — please trackback it if you write about blogging in more than one language!