Facebook Page Like Buttons: Quick and Dirty [en]

[fr] Comment ajouter à votre sidebar WordPress un bouton "J'aime" simple pour vos pages Facebook.

Sorting out my mess of Facebook pages and groups (part 2 coming soon!), I’ve spent way too much time struggling with the Facebook Like Box creator and a couple of WordPress plugins (Facebook Social Plugins and Facebook Like Box Widget). I just didn’t manage to get what I want, which is a simple, minimal list of my Facebook pages and a Like button next to them.

Here’s what I wanted (it’s in the CTTS footer now, so you can also scroll down and see it live… and like my pages!)

Quick and Dirty Facebook Page Like Buttons

I didn’t want a Like Box full of stuff. Just the page name, avatar, and the like button.

Here’s how I finally did it (it’s dirty, but it works — just stick the code in a text widget if you have a WordPress blog):

<iframe src="http://www.facebook.com/plugins/likebox.php?id=7812744463" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:220px;height:60px;" allowTransparency="true"></iframe>

Just replace the number after id= by your page’s ID (you can find it easily by going to your page, it’s the number following your page name in the URL.

If your page name is long, you might want to increase the height of your iframe to 80px or 100px (trial and error, you’ll find the right height).

There you go!

Oh, and I added like buttons to my posts, too, with the Facebook Like Button plugin. Dunno if it’s the best one out there or not, but it seems to work and I didn’t have to struggle too much setting it up.

Similar Posts:

Blog Host Ugliness [en]

[fr] Une amie Serbe s'est vu poser un ultimatum par son hébergeur de blogs: 24 heures pour supprimer commentaires d'un autre blogueur et liens vers ses sites, ou voir son blog disparaître.

L'hébergeur en question (qui utilise WordPress multi-utilisateurs, comme WordPress.com) avait en outre désactivé la fonction d'exportation de blog.

On s'en est sortis comme on a pu (voir ici).

Mis à part le côté technique de l'affaire, il est absolument scandaleux qu'un hébergeur de blogs se permette d'agir ainsi. Certes, tout hébergeur est libre de "virer" des clients -- mais déactiver au préalable la fonction d'exportation des blogs, cela atteint des sommets de mesquinerie. A bon entendeur.

Edit: sur Seesmic, l'histoire en français et en vidéo.

***Note:** I’ve updated this post as I gathered information allowing me to see more clearly in this whole mess. **Please read the comment** if you’re going to jump in the conversation or blog about this.*

Wednesday night, my friend [Sanja from BlogOpen](http://climbtothestars.org/archives/2007/11/12/blogopen-in-novi-sad-serbia/) (she was my very kind and competent hostess) pinged me on IM. She had less than 24 hours to export her blog before her blog host shut it down.

It was a blog hosted by [WordPress multi-user](http://wordpress.org/) [**Edit:** [not WPMU](http://climbtothestars.org/archives/2008/01/26/blog-host-ugliness/#comment-381845)]. Easy enough, I thought. There is an export function. Unfortunately, when I logged in (the interface was in Serbian, but I can find my way through WordPress with my eyes closed), this is what I found:

WordPress (MU?) with no Export

Even if you don’t understand Serbian, you can see there is a missing tab. I tried calling `/wp-admin/export.php` directly, but the file had been removed.

Well, after a bit of poking, prodding and thinking, this is what I came up with (reminder: WPMU means that you can’t there was no possibility to install plugins and no direct access to the server):

Last Hope Export of WordPress MU Blog

I went into Options > Reading. I set the feeds to “entire post”. As there were 110 posts in this blog, I set the home page to display all of them, with a little margin for error. There were more than 1400 comments, so I set the maximum number of items in a feed to 1500.

Then I did three things:

– saved `/feed` (an RSS dump of the blog posts)
– saved `/comments/feed` (an RSS dump of the comments)
– scraped the blog (with single blog post pages) as an extra backup by running `wget -r -l1 -w1 BLOGURL` (thanks, [John](http://twitter.com/urRaku)) from my server (also to save the images).

The blog was saved. I couldn’t import the RSS dump of blog posts into WordPress.com, where I told Sanja to open [a new blog account](http://aurorineavanture.wordpress.com/), so I quickly set up a regular WordPress install on my server, imported it there, and exported it in WXR format. Great.

Comments, however, are [another story](http://wordpress.org/support/topic/153722). If you’re in a hackish mood, any help would be appreciated.

We’ll probably have to deal with the images too once the blog has been completely wiped off the 381.com server — for the moment it seems like it was [disabled](http://auroraborealis.blog381.com/), but the images are still there (see [this one](http://auroraborealis.blog381.com/wp-content/uploads/3/34/auroraborealis/2007/12/windowslivewriterizubbolikadjeupalj-93aaanti-stress-therapy-posters-thumb3.jpg) for example).

There, that was for the technical part.

Now for a personal comment. I find it **utterly disgusting and shocking** that a blog host owner would give people an **ultimatum to leave** and **disable the export function** in the blogging software. Sanja tells me that they had the export function until a few days before the ultimatum.

Of course, a blog host can choose not to host certain people. But trying to lock people in by disabling export of *their own data* is simply evil. If you’re kicking people off your system, you damn well better make sure they can take their data with them.

**Edit, 27.01, 12:00**: I’m happy to learn that [it seems the disabling of the export function was not related to the ultimatum](http://climbtothestars.org/archives/2008/01/26/blog-host-ugliness/#comment-381845), and that the blog381 people were not *actually trying to actively lock people in*. However, it remains that it’s pretty delicate in a conflictual situation to tell people to “submit or leave” when they don’t have a way to export their data on their own.

So, people, please. If you need a blog host, choose a *serious one*. [WordPress.com](http://wordpress.com) for example. Or [Blogger](http://blogger.com). Or [Typepad](http://typepad.com). Putting your precious blog between the hands of an individual is risky (weblogs.com, anybody? and if you remember, people on weblogs.com at least had the guarantee they could export their data…)

How did this happen?

I got some details about the situation, but a word of warning about that, first. The source material to this Serbian blogosphere drama is all in… Serbian. I’m relying here on what my friend Sanja told me about the situation, and I do not doubt her good faith. I know, though, that stories do have multiple sides, and that there might be more to the background than what I’m telling you here — but whatever the background story, it cannot justify the behaviour of [this blog host](http://blog.blog381.com).

From what I gathered, what brought about this crisis is a quarrel between two bloggers: [Tatjana aka Venus aka Lang](http://www.laluve.com/) *(**Update**: Tatjana is not happy that I’m linking to her and has redirected visitors to this site elsewhere; to see her blog, copy-paste the link http://www.laluve.com/ in your browser)*, the owner of the [Serbian blogging platform blog381.com](http://blog.blog381.com/) (**not** the [Tatjana](http://www.mooshema.com/) who organized [BlogOpen](http://blogopen.eu/)!), and another pretty [popular blogger](http://bruh.org/ludizmaj/). At some point, Tatjana decided to forbid the people using her platform from linking to this other blogger or harbouring his comments.

Here is the warning she posted on the community forums:

Vlasnik blogova





(ima verovatno jos ali ne mogu da trazim)

je ovom blog sistemu naneo stetu laziranjem glasova oko izbora za najblogera (na kom je on bio ‘pobednik’), ‘miniranjem’ sledeceg izbora, sirenjem neistina, traceva, vrbovanjem novih blogera sa tri osam jedan sistema, a sve u cilju da se naskodi ovom sistemu a poveca sopstveni traffic i “ugled”.

Za one koji nisu dovoljno informisani i sve ostale koji su slusali ili nisu, samo jednu stranu price od gore pomenutog, necu dodatno iznositi nikakve detalje, niti vise imam nameru da se borim sa provincijalizmima pojedinih ljudi koji su bili ili jesu na neki nacin u komunikaciji sa blogom381 i njegovim korisnicima.

Slobodna volja svakog od nas da pise kako i gde hoce, ali oni koji se odluce da i dalje pisu ovde nece moci da imaju linkove ka ovim blogovima niti komentare vlasnika istih.

Ukoliko imate zelju,nameru ili potrebu da ostanete na ovom blog sitemu, obrisite linkove i komentare gore pomenutog blogera u roku od 24h.

Translation (Sanja was a bit tired, so forgive the wobbliness):

> The owner of these blogs

> has caused damage to this blog system by faking votes for the election of “The best blogger” (where he was “the winner”), and was undermining the next election by spreading gossip, lies, and recruiting new 381 bloggers, with only one aim: to damage this community and increase his own blog traffic and “reputation”.

> For those who are not informed well enough, and all others who were listening or didn’t, only one side of the story of the person mentioned above, I will not give any additional details, nor do I have the intention to fight with provincialism of some people who were or in some way are connected to blog381 communication and their users.

> It is the free will of each of us to write how and where we want to, but those who decide to keep writing here, will not be able to have links to these blogs or comments by their owner.

> Those of you who have the wish, intention or need to stay on this blog system, should delete links and comments of the blogger (mentioned above) within 24 hours.

Sanja learnt about this because the owner of the blogging platform left a comment on one of her posts (not the most recent) to let her know about it. Given that the “other blogger” in question is a friend of Sanja’s, she wasn’t going to comply.

Other bloggers have also seen their blogs deleted, or at least de-activated (actually, before the 24-hour limit was up). A dozen or so, says Sanja.

If you want to chime in on the “political” side of this story (particularly if you’re involved in this story or a direct witness), you’re welcome to use my comments. However, I ask (as always) that everybody remain civil and refrain from personal attacks (commonsense blogging etiquette, y’know).

Update: It seems that since Sanja’s blog was deactivated, the whole blogging platform has been shut down, with a message that people can e-mail the administrator to get an export of their blog. This message was not there during the ultimatum period.

In a [comment to this post](http://climbtothestars.org/archives/2008/01/26/blog-host-ugliness/#comment-381722), Tatjana aka Lang asked me to remove the link to her blog, http://www.laluve.com/ , which I had placed upon her name. As I have [refused to remove it](http://climbtothestars.org/archives/2008/01/26/blog-host-ugliness/#comment-381724) (linking to the people involved in this story is perfectly relevant, and on the web, you can link to who you want, anyway), she has set up a redirection which sends visitors from this site straight off to CNN. So, I’ve left the link in, of course, but provided you with a handy copy-paste if you want to go and visit her all the same.

Similar Posts:

Print CSS Plugin (WordPress) Needs CSS Guru [en]

[fr] Un nouveau plugin, qui permet d'insérer automatiquement une feuille de style pour l'impression dans son blog WordPress.

La feuille de style que j'ai pondue étant bien pauvre, incomplète, et franchement pas terrible, l'aide d'un gourou CSS serait fort appréciée pour mettre à disposition une feuille de style pour impression qui soit jolie, conforme, et à un peu près universelle. Crédit sera donné, bien entendu. (C'est un anglicisme, ça?)

Right, here we go — another plugin. I noticed some time back that many WordPress themes were provided without [a print stylesheet](http://www.alistapart.com/stories/goingtoprint/).

In my attempt to stop fiddling with my theme files, I dreamed up a simple little plugin that would add a link to a [print stylesheet](http://codex.wordpress.org/Styling_for_Print) in the page header, and provide a simple, universal, print stylesheet that people could use.

Well, I’ve got half the work done, and it’s my new plugin [Bunny’s Print CSS](/code/print-css.tgz) ([zip](/code/print-css.zip), [.phps](/code/print-css.phps). “Half the work” because it includes a sample stylesheet and links to it automatically in the theme header when activated, but the stylesheet is nowhere near “complete”, “universal”, “pretty”, or any other nice adjectives you’d like to find associated with a print stylesheet bundled in a plugin.

So, call to all you CSS gurus out there. Can you improve on my [print.css](/code/print-css/print.css)? It would be nice if it were at least somewhat sandbox/kubrick compatible. Credit will be (loudly) given.

Now, aren’t there other plugins out there doing similar things? Not that many, at least in the [plugin repository](http://wordpress.org/extend/plugins/). [MyCSS](http://wordpress.org/extend/plugins/mycss/) allows you to add custom theme-independant CSS to your blog. [WP-Print](http://wordpress.org/extend/plugins/wp-print/other_notes/) creates a “printable version” of your blog (if I understood correctly, by creating a set of print-friendly pages).

Similar Posts:

Two Plugin Updates: Basic Bilingual 0.32 and Language Linker 0.2 [en]

[fr] Je me suis levée à l'aube pour aller faire la nouille sur RSR1 et prendre un p'tit déj improvisé chez une ancienne copine d'uni. Ensuite, j'ai passé la journée les mains dans le PHP, ce qui veut dire que je n'ai beaucoup blogué, mais que j'ai mis à jour deux plugins: Basic Bilingual, qui permet de tenir sans peine un blog "bilingue" comme celui-ci (c'est ce qui me permet de rédiger et d'afficher ce petit extrait en français) et Bunny's Language Linker, très utile pour afficher des liens entre pages correspondantes des différentes traductions d'un site.

After waking up at an ungodly hour this New Year’s Day (for a [live radio appearance](http://info.rsr.ch/fr/rsr.html?programId=110451&bcItemName=le_grand_8&rubricId=8888&contentDisplay=last_five&siteSect=1000#mardi) and impromptu breakfast at a uni friend’s home nearby) I spent the rest of my day elbows deep in PHP code. As a result, I haven’t written the half-dozen of posts that have been sitting in my drafts list over Christmas, but I have updated two plugins — an old one, and a new-born.

**[Basic Bilingual](http://wordpress.org/extend/plugins/basic-bilingual/) 0.32**

[Download](/code/basic-bilingual.tgz) | [zip](/code/basic-bilingual.zip) | [.phps](/code/basic-bilingual.phps)

This release fixes the [disappearing excerpts problem](http://climbtothestars.org/archives/2007/12/18/nasty-problem-with-basic-bilingual-plugin/) (was fixed in 0.31 actually, but I never announced it) and replaces the ugly “language box” floating somewhere near the top of the post admin page by a pretty DBX (let me know what it stands for) box in the sidebar:

Basic Bilingual got a dbx box for the new year!

**[Bunny’s Language Linker](http://wordpress.org/extend/plugins/bunnys-language-linker/) 0.2**

[Download](/code/language-linker.tgz) | [zip](/code/language-linker.zip) | [.phps](/code/language-linker.phps)

(I always want to call it “Language Links”, which was the initial name I chose — still not sure I was right to change.) Anyway, this version is pretty exciting, as it does something I’ve been thinking of for a while: it puts the link to the other localized versions of the page you’re viewing in the menu bar if you’re using a Sandbox-based theme:

Language Linker link in the menu bar!

Otherwise, it puts it at the end of the page in its own div (you can style it the way you wish). I’m not saying this is the best, final solution, but I think it’s headed in the right direction.

Similar Posts:

Bunny's Language Linker: New WordPress Plugin [en]

[fr] Un nouveau plugin WordPress que je viens d'écrire. Celui-ci vous permet de gérer les liens entre pages équivalentes de deux versions linguistiques d'un site. Par exemple, si vous avez http://stephanie-booth.com/en et http://stephanie-booth.com/fr (deux installations WordPress séparées!), le plugin vous aidera à faire en sorte qu'il y ait des liens entre http://stephanie-booth.com/en/about et http://stephanie-booth.com/fr/a-propos.

Ladies and Gentlemen, I’m proud to announce the WordPress plugin [Bunny’s Language Linker](/code/language-linker.tgz) ([zip](/code/language-linker.zip), [phps](/code/language-linker.phps)).

I’ve been wanting to write this plugin for ages, and I’ve finally done it this evening. This is a plugin for people who have a WordPress site with content duplicated in more than one language, like I’m going to have with [stephanie-booth.com](http://stephanie-booth.com). For example, you have an “about” page in English, and another “about” page in German. This plugin helps you create and manage links between such “sister” pages. (“Pages”, not “posts”. It doesn’t work with posts at all.)

The plugin adds an extra field to the page editing form, inviting you to input the *page slug* of the sister page:

Bunny's Language Linker - Admin view

The screenshot is a bit small, but there on the right, there is a little box with “a-propos” — the slug of the French sister page. It works with more than one other language, too. You just need to edit the settings in the plugin file to specify which languages you’re playing with (instructions are in the plugin file). If I had sites in 3 other languages, say French, Spanish, and German, my settings line in the plugin file would look like this:

$bll_other_languages=array(‘fr’, ‘es’, ‘de’);

And the little box would provide three different fields for the page slugs of the different localized sites. (OK, I’m making this sound complicated, sorry.)

The plugin then automatically adds links to the sister pages you’ve indicated. Here’s what it could look like:

Bunny's Language Linker - Page view

There’s a readme file with the plugin which will give you some more details. I’ll soon have a client site in production using that plugin, so if these explanations weren’t very clear, hopefully the demonstration will help.

Similar Posts:

Browser Language Detection and Redirection [en]

[fr] Une explication de la méthode que j'ai suivie pour que http://stephanie-booth.com redirige le visiteur soit vers la version anglaise du site, soit la française, en fonction des préférences linguistiques définies dans son navigateur.

**Update, 29.12.2007: scroll to the bottom of this post for a more straightforward solution, using Multiviews.**

I’ve been working on [stephanie-booth.com](http://stephanie-booth.com) today. One of my objectives is the add an [English version](http://stephanie-booth.com/en/) to the previously [French-only site](http://stephanie-booth.com/fr/).

I’m doing this by using two separate installations of WordPress. The content in both languages should be roughly equivalent, and I’ll write a WordPress plugin which allows to “automate” the process of linking back and forth from equivalent content in different languages.

What I did today is solve a problem I’ve been wanting to attack for some time now: use people’s browser settings to direct them to the “correct” language for the site. Here is what I learnt in the process, and how I did it. It’s certainly not the most elegant way to do things, so let me know if you have a better solution by using the comments below.

First, what I needed to know was that the browser language preferences are sent in the HTTP_ACCEPT_LANGUAGE header (HTTP header). First, I thought of [capturing the information through PHP](http://www.webdeveloper.com/forum/showpost.php?s=d989341270ceae8820a3bc1c6273dc9e&p=217863&postcount=2), but I discovered that Apache (logical, if you think of it) could handle it directly.

[This tutorial was useful in getting me started](http://www.ibm.com/developerworks/library/wa-apac.html), though I think it references an older version of Apache. Out of the horses mouth, [Apache content negotiation](http://httpd.apache.org/docs/2.0/content-negotiation.html) had the final information I needed.

I’ll first explain the brief attempt I did with Multiviews (because it can come in handy) before going through the setup I currently have.

### Multiviews

In this example, you request a file, e.g. test.html which doesn’t physically exist, and Apache uses either test.html.en or test.html.fr depending on your language preferences. You’ll still see test.html in your browser bar, though.

To do this, add the line:

Options +Multiviews

to your .htaccess file. Create the files test.html.en and test.html.fr with sample text (“English” and “French” will do if you’re just trying it out).

Then, request the file test.html in your browser. You should see the test content of the file corresponding to your language settings appear. Change your browser language prefs and reload to see what happens.

This is pretty neat, but it forces you to open a file — and I wanted / to redirect either to /en/ or to /fr/.

It’s explained pretty well in [this tutorial I already linked to](http://www.ibm.com/developerworks/library/wa-apac.html), and [this page has some useful information](http://unix.org.ua/orelly/linux/apache/ch06_03.htm) too.

### Type maps

I used a type map and some PHP redirection magic to achieve my aim. A type map is not limited to languages, but this is what we’re going to use it for here. It’s a text file which you can name menu.var for example. In that case, you need to add the following line to your .htaccess so that the file is dealth with as a type map:

AddHandler type-map .var

Here is the content of my type-map, which I named menu.var:

URI: en.php
Content-Type: text/html
Content-Language: en, en-us, en-gb

URI: fr.php
Content-Type: text/html
Content-Language: fr, fr-ch, fr-qc

Based on my tests, I concluded that the value for URI in the type map cannot be a directory, so I used a little workaround. This means that if you load menu.var in the browser, Apache will serve either en.php or fr.php depending on the content-language the browser accepts, and these two PHP files redirect to the correct URL of the localized sites. Here is what en.php looks like:

And fr.php, logically:

Just in case somebody came by with a browser providing neither English nor French in the HTTP_ACCEPT_LANGUAGE header, I added this line to my .htaccess to catch [any 406 errors (“not acceptable”)](http://www.checkupdown.com/status/E406.html):

ErrorDocument 406 /en.php

So, if something goes wrong, we’re redirected to the English version of the site.

The last thing that needs to be done is to have menu.var (the type map) load automatically when we go to stephanie-booth.com. I first tried by adding a DirectoryIndex directive to .htaccess, but that messed up the use of index.php as the normal index file. Here’s the line for safe-keeping, if you ever need it in other circumstances, or if you want to try:

DirectoryIndex menu.var

Anyway, I used another PHP workaround. I created an index.php file with the following content:

And there we are!

### Accepted language priority and regional flavours

In my browser settings, I’ve used en-GB and fr-CH to indicate that I prefer British English and Swiss French. Unfortunately, the header matching is strict. So if the order of your languages is “en-GB, fr-CH, fr, en” you will be shown the French page (en-GB and fr-CH are ignored, and fr comes before en). It’s all explained in the Apache documentation:

> The server will also attempt to match language-subsets when no other match can be found. For example, if a client requests documents with the language en-GB for British English, the server is not normally allowed by the HTTP/1.1 standard to match that against a document that is marked as simply en. (Note that it is almost surely a configuration error to include en-GB and not en in the Accept-Language header, since it is very unlikely that a reader understands British English, but doesn’t understand English in general. Unfortunately, many current clients have default configurations that resemble this.) However, if no other language match is possible and the server is about to return a “No Acceptable Variants” error or fallback to the LanguagePriority, the server will ignore the subset specification and match en-GB against en documents. Implicitly, Apache will add the parent language to the client’s acceptable language list with a very low quality value. But note that if the client requests “en-GB; q=0.9, fr; q=0.8”, and the server has documents designated “en” and “fr”, then the “fr” document will be returned. This is necessary to maintain compliance with the HTTP/1.1 specification and to work effectively with properly configured clients.

Apache, Content Negotiation

This means that I added regional language codes to the type map (“fr, fr-ch, fr-qc”) and also that I changed the order of my language preferences in Firefox, making sure that all variations of one language were grouped together, in the order in which I prefer them:

Language Prefs in Firefox

### Catching old (now invalid) URLs

There are lots of incoming links to pages of the French site, where it used to live — at the web root. For example, the contact page address used to be http://stephanie-booth.com/contact, but it is now http://stephanie-booth.com/fr/contact. I could write a whole list of permanent redirects in my .htaccess file, but this is simpler. I just copied and modified the rewrite rules that WordPress provides, to make sure that the correct blog installation does something useful with those old URLs (**bold** is my modification):

# BEGIN WordPress

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . **/fr**/index.php [L]

# END WordPress

In this way, as you can check, [http://stephanie-booth.com/contact](http://stephanie-booth.com/contact) is not broken.

### Next steps

My next mission is to write a small plugin which I will install on both WordPress sites (I’ve got to write it for a client too, so double benefit). This plugin will do the following:

– add a field to the write/edit post field in which to type the post slug of the correponding page/post in the other language *(e.g. “particuliers” in French will be “individuals” in English)
– add a link to each post pointing to the equivalent page in the other language

It’s pretty basic, but it beats manual links, and remains very simple. (I like simple.)

As I said, if you have a better (simpler!) way of doing all this, please send it my way.

### A simpler solution **[Added 29.12.2007]**

For each language, create a file named index.php.lg where “lg” is the language code. For French, you would create index.php.fr with the following content:

Repeat for each language available.

**Do not** put an index.php file in your root directory, just the index.php.lg files.

Add the two following lines to your .htaccess:

Options +Multiviews
ErrorDocument 406 /fr/

…assuming French is the default language you want your site to show up in if your visitor’s browser doesn’t accept any of the languages you provide your site in.

You’re done!

Similar Posts:

Ridding WordPress Plugins of Template Tags [en]

[fr] Cet article décrit une méthode permettant de se défaire des "template tags" qu'utilisent certains plugins. Plutôt que de copier le fameux template tag à 3 endroits différents dans son thème (comme c'était le cas auparavant pour Basic Bilingual), il est possible de modifier à peu de frais un plugin pour qu'il injecte automatiquement son contenu dans le blog.

If you’re like me and use a bunch of plugins to liven up your WordPress blog, you’ve probably noticed that adding template tags in your favourite (or favourite-of-the-week) theme files can quickly become a royal pain in the neck.

One of the things I wanted to do with [Basic Bilingual, and which I did with the last release](http://climbtothestars.org/archives/2007/11/30/basic-bilingual-03-for-multilingual-blogging/), was make the plugin inject the text for the “other excerpt” (the French text you can see at the top of this post) automatically into the templates and feeds.

Once I’d figured out how to do that, I realised I could modify other plugins, too. And I’m going to tell you how you can do it, too. This method should work for any plugin which generates a template tag, as long as you want the content generated by the plugin to go immediately after or before the post content. (I’m still working on advanced rules for cases where you want to make modifications elsewhere in the template.)

[Christine](http://www.neato.co.nz/)’s [Inline Tag Thing](http://www.neato.co.nz/wordpress-things/inline-tag-thing) put me on the track (thanks!), as it does just that. Here’s the trick:

1. create a function which concatenates (= “adds”) the plugin output to the content
2. add an action hook to the plugin to apply that function to “the_content”.

Fear not, I’ll explain all. You don’t need to really know much PHP to do this, as long as you’re comfortable wading through a bit of code and copy-pasting stuff and making a few small modifications.

Let’s take an example: [the Similar Posts plugin](http://rmarsh.com/plugins/similar-posts/), which I’m now using to point out posts related to the current one (normally, in a box at the top of the post if you’re on the website, and as a list at the end of the post if you’re reading [the feed](http://feeds.feedburner.com/ctts)).

Similar Posts provides a template tag, <?php similar_posts(); ?>, which you can paste in your template where you like the related posts to appear. Personally, I want them to appear on the main blog page, on the individual archive pages, and on the monthly, category, and taggy archive pages. This means I need to paste the tag into at least 3-4 different template files. And if I decide that I want the tag at the top of the post rather than the bottom, or I decide to remove it, there I go again. Not optimal.

So, here’s how I made it “better” (for me):

A. First, I looked at the plugin code to figure out where the template tag function was; in this case, quite easy, it’s the function called similar_posts(), logically. Here are the last two lines of this function, which do the actual data output:

print $result;
if (defined(‘POC_CACHE’)) print $cache_time;

I changed them to:

return $result;
if (defined(‘POC_CACHE’)) return $cache_time;

So that they didn’t print directly (ie, output text), but just return the value of the data we want to insert.

Then, I created the following function:

function sp_embed_similar_posts($content) {
$content = similar_posts() . $content;
return $content;

This function takes one parameter ($content), and sticks the output of similar_posts() in front of it. Now you see why we needed to change the other function so that it didn’t print. We’re just modifying the value of the $content string. This new function returns the modified value for the content (in our case, imagine it as being the content of your post with the code for the similar posts listing stuck in front.

Now all that is left to do is to tell WordPress to actually *use* that function at some point (plugins are usually a collection of functions, followed by a series of “hooks” which actually execute the functions at certain chosen moments). Here’s the action we’ll use:

add_action(‘the_content’, ‘sp_embed_similar_posts’);

Try it!

This will also add the list of similar posts to the feed.

So, in summary, here is what we have done:

– modified the template tag function so that it *returns* a value instead of *printing* it (in some plugins, you’ll find a function that already does that!)
– created a function to stick that value on the beginning or end of a parameter, $content
– add an action hook on the_content to execute the function.

Happy hacking!

Similar Posts:

Excluding One Category From Blog Homepage (WordPress) [en]

[fr] Comment exclure une catégorie de la première page de votre blog WordPress tout en la gardant dans les archives.

The simplest method I’ve found up to now (and I’ve only just found it) if there are certain categories of posts you do not want to see appear on your main blog page, but that you still want to see in the archives, is to use query_posts().

Here’s an example:

This needs to come in right before the while ( have_posts() ) { line. The $query_string parameter means that you can still pass parameters in the URL, so things like special Event Calendar pages will still work.

Careful, though, this only works for one category at a time. You need to use WP_Query for that, and build a separate loop for the homepage.

Similar Posts:

Remove Paging From WordPress Archives [en]

[fr] Pour supprimer les "pages" de vos archives WordPress, utilisez le code ci-dessous dans le fichier functions.php du thème que vous utilisez.

Thanks a lot to [Matt](http://photomatt.net) for giving me the code which allows me to remove paging from the archives on this blog. I’ve been wanting to do that for a long time, but didn’t know where to start.

Just add the following code to the functions.php file of your theme.

function yay_nopaging($query) {
if ( !is_home() && !is_feed() && ” === $query->get(‘nopaging’) )
$query->set(‘nopaging’, 1);

add_action(‘parse_query’, ‘yay_nopaging’);

Unfortunately, this breaks the Recent Posts widget, which starts displaying… all the posts (that’s a lot of them, here). I removed the widget, but if you have a solution, I’d be happy to hear it.

Similar Posts:

Basic Bilingual and Bunny's Technorati Tags Plugins Updated for WordPress 2.1 [en]

[fr] Mise à jour de mes deux plugins pour WP2.1 qui les cassait gravement. Mises à jour pas testées, à manier avec précaution.

Thanks to [Sudar](http://sudarmuthu.com/blog/), who took the trouble to [fix Bunny’s Technorati Tags so that it worked with WP2.1](http://sudarmuthu.com/blog/2007/01/31/wordpress-21-and-custom-field-plugin-gotcha.html), here are up-to-date version of these two plugins, [Bunny’s Technorati Tags](http://climbtothestars.org/archives/2005/01/18/technorati-tags-plugin/) and [Basic Bilingual](http://climbtothestars.org/archives/2005/01/23/basic-bilingual-plugin/):

– [Bunny’s Technorati Tags 0.6](/code/bunny-tags.zip) ([.phps](/code/bunny-tags.phps))
– [Basic Bilingual 0.3](/code/basic-bilingual.zip) ([.phps](/code/basic-bilingual.phps))

The previous, WordPress 2.0-compatible versions are still available:

– [Bunny’s Technorati Tags 0.5](/code/bunny-tags-0.5.zip) ([.phps](/code/bunny-tags-0.5.phps))
– [Basic Bilingual 0.21](/code/basic-bilingual-0.21.zip) ([.phps](/code/basic-bilingual-0.21.phps))

**Warning:** these old versions suffer from the [empties custom fields problem](http://markjaquith.wordpress.com/2007/01/28/authorization-and-intentionorigination-verification-when-using-the-edit_post-hook/). Don’t use them with 2.1.

**Disclaimer:** I’m swamped with work, haven’t upgraded yet, and haven’t tested the new versions of the plugins. Use carefully. Let me know if there are glitches. Bunny’s Technorati Tags is [the very version Sudar put online](http://sudarmuthu.com/blog/wp-content/uploads/2007/01/bunny-tags.zip) (I’m making it available here mainly as there are links to it out there beyond my control, not the least from the [wp-plugins.org wiki](http://dev.wp-plugins.org/wiki/) which has been closed to editing due to spam.) For **Basic Bilingual, however,** I adapted the code Sudar had added to Bunny Tags, but I don’t fully understand if it works. **Backup, try gingerly, and please leave comments here to let others (and myself) know if it works or breaks.**


Similar Posts: