Archive for plugins

anatomy of a new plugin

Update:
Italian translation appended 31 Oct 06

English

Overview

Well I dove deeper into the WordPress documentation since this plugin I wanted to do several things with this one: I wanted it to have an administration panel to enter information, and I did NOT want to make anyone using the plugin have to do anything more than set options through the panel. In other words, no more code tweaking.

Several reasons for that. In the first place, not everyone using WordPress is a geeky hacker like myself. In the second place, it’s annoying even for a geeky hacker like myself to move around themes or update WordPress and have to re-do all the little hacks and edits. So I’m becoming a bigger fan of plug’n'play plugins.

Now to be fair, this isn’t always avoidable. In particular, sidebar elements aren’t easily hooked in (I think this is the idea behind the sidebar widgets project, but I haven’t looked deeply enough into that to be sure). But I’ve already seen some interesting workarounds by other plugin authors and I think it’s possible to avoid many of these problems.

In any case, this plugin is about favicons. Here was my wish list:

  1. To enter an arbitrary image for the favicon
  2. Specify the image relevant to my WordPress directory or as absolute URI
  3. To change it whenever I wanted
  4. To use gif/icon/png files for the favicon
  5. Optionally use it in my rss2 feed
  6. Optionally use it in my atom feed
  7. Everything configurable from the admin panel
  8. A “plug and play” plugin — install and activate, nothing more

To my surprise, this was pretty easy. Perhaps an hour or so of reading the relevant documentation, about 15 minutes coding, another hour or so testing it, and about two hours of writing up and documentation. :-D That’s a pretty typical ratio…

Update: the completed plugin is available at http://www.digitalramble.com/favicon-manager-wordpress-plugin/ (take a peek at the sidebar).

Header Hooks

In order to add something to the headers, without requiring the user to edit their WordPress files, you use

// insert favicon into header using hooks
add_action('wp_head', 'add_favicon_to_headers');

where add_favicon_to_headers is a simple parameterless function that prints out what you want added into the headers. It’s that simple. The first cut at the function does what it’s supposed to do, upon testing:

function add_favicon_to_headers()
{
  $favicon_location="http://example.com/example.ico";
  $favicon_type="x-icon";
  print ' <link rel="icon" href="'. $favicon_location .'" type="image/'. $favicon_type .'" />';
  print "\n";
  print ' <link rel="shortcut icon" href="'. $favicon_location .'" type="image/'. $favicon_type .'" />';
  print "\n";
}

Of course this is only the first crack at it, just to make sure it works. As it does indeed, if you were to drop the above (encapsulated in the <?php enclosures and with a correct location other than example.ico) into a file with the .php extenstion into your plugin directory. There is in fact a very simple favicon plugin out there that does just that but of course it’s not configurable as per my wish list ;-).

Database

In order to have persistent, retrievable values, I had to make use of the database utilities offered in WordPress. There’s add_option, update_option and get_option for a very simple interface. So I make sure there’s a database entry for the favicon’s location:

// add the saved items to the database if not already there
function favicon_mgr_add_options()
{
        add_option('fm_favicon_location', '');
}
 
favicon_mgr_add_options();

At this point the database now has a new item with an empty string value for this plugin to use. I tried to use long descriptive names to reduce the possibliity of name space collision. It would have been easier on my fingers to just use “favicon” but of course the possiblity is higher that sooner or later it will run into someone else with the same brilliant idea.

This means that the hook should now retrieve the value from the database:

function add_favicon_to_headers()
{
  $favicon_location=get_option('fm_favicon_location');
  $favicon_type=get_favicon_type($favicon_location);
  print ' <link rel="icon" href="'. $favicon_location .'" type="image/'. $favicon_type .'" />';
  print "\n";
  print ' <link rel="shortcut icon" href="'. $favicon_location .'" type="image/'. $favicon_type .'" />';
  print "\n";
}

Now you see why I used variables to begin with :). The get_favicon_type is another function I wrote (but didn’t include for clarity above) that returns the correct type (x-icon, gif, jpg, png) depending on the favicon’s name. So now I’m set regardless of what the user enters (I do need to add a check in case the extension is unknown, but again I’m keeping things as short as I can).

Admin panel

Wordpress also provides a pretty straightforward set of functions for creating an admin panel. It was actually pretty easy. First there’s the hook to put a new menu item under Options (you can do more, but for basic stuff like this, Option’s fine).


// create hook for new submenu
add_action('admin_menu', 'favicon_mgr_admin_menu');
 
// title of page, name of option in menu bar, which function lays out the html
function favicon_mgr_admin_menu()
{
        add_options_page(__('Favicon Manager Options'), __('Favicons'), 5, basename(__FILE__), 'favicon_mgr_options_page');
}
 
// html layout for option page, plus detection/update on new settings
function favicon_mgr_options_page()
{
  ...
}

So what this all does is first a menu item is added in. The menu item in turn specifies the function that lays out its page. So then that function prints out the html necessary to allow input, etc. That page will also have to update the database entries so that the header hook retrieves the correct value to drop into the headers. So it’s starting to come together. Here’s the first cut at the options page:


function favicon_mgr_options_page()
{
        $updated = false;
 
        if (isset($_POST['fm_favicon_location']))
        {
                $fm_favicon_location = $_POST['fm_favicon_location'];
                update_option('fm_favicon_location', $fm_favicon_location);
                $updated = true;
        }
        $fm_favicon_location = get_option('fm_favicon_location');
        if ($updated)
        {
                ?>
                <div class="updated"><p><strong>Options saved.</strong></p></div>
                <?php
        }
 

Let’s take the pause that refreshes. Remember that this page can be used when the user first enters the option page, or after they’ve hit the submit button. So the first thing to check is to see if this is on submission. isset provides a way of checking to see if that form input element has been set or not. If it has, I drop it into the database, and set update to true.

        ?>
        <div class="wrap">
                <h2>Favicon Settings</h2>
                <form name="form1" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
 
                        <fieldset class="options">
 
                                <legend>Favicon in WordPress Pages</legend>
                                <table width="100%" cellspacing="2" cellpadding="5" class="editform">
                                <tr valign="top">
                                        <th width="33%" scope="row">Location:</th>
                                        <td><input name="fm_favicon_location" type="text" width="60" value="<?php echo $fm_favicon_location; ?>"/>
                                        </td>
                                </tr>
                                </table>
 
                        </fieldset>
 
                        <p class="submit">
                          <input type="submit" name="Submit" value="Update Options &raquo;" />
                        </p>
                </form>
 
        </div>
 
        <? php
}

This part prints out the actual form page, with values in the input field if any exist. The layout is already controlled via the stylesheets and classes used here, so the familiar blue and white theme layout comes right up.

That’s it! Pretty much the only items left are the arbitrary or relative locations for the favicon (I want the users to be able to enter the location either way) and the RSS2/Atom options. The former is easily resolved with one more function:

function create_favicon_uri($favicon_location)
{
  // if an absolute location entered, don't try to add the site url...
  if (preg_match("/^http/", $favicon_location))
  {
        $favicon_url=$favicon_location;
  }
  else
  {
        $favicon_url= get_settings('siteurl') . '/' . $favicon_location;
  }
  return $favicon_url;
}

And now I update instances where I get the favicon_location to run the results through this before using it. I do not use this before storing the location into the database, though. To avoid user confusion, I prefer to retain what they actually entered.

The Feed Options

I’m only going to describe the RSS2 additions here. The Atom is exactly the same other than the actual output in the hook.

As of WordPress 2.0, hooks are provided for RSS2:

function add_image_to_rss2_feed()
{
  // do this or not depending on user settings in panel!
  if (get_option('fm_rss2_feed_option')=="Y")
  {
        $favicon_location=create_favicon_uri(get_option('fm_favicon_location'));
        echo "<image>\n";
        echo "  <link>". get_bloginfo_rss('url') ."</link>\n";
        echo "  <url>". $favicon_location ."</url>\n";
        echo "  <title>". get_bloginfo_rss('name') ."</title>\n";
        echo "</image>\n";
  }
}
 
// insert image into rss2 feed
add_action('rss2_head', 'add_image_to_rss2_feed');

So now I add it to my database:

// add the saved items to the database if not already there
function favicon_mgr_add_options()
{
        add_option('fm_favicon_location', '');
        add_option('fm_rss2_feed_option', '');
}

This gets added to the option page function before printing out whether or not new options have been saved:

        // checkboxes flip on/off
        if ($_POST['fm_rss2_feed_option']!=get_option('fm_rss2_feed_option'))
        {
                $fm_rss2_feed_option = $_POST['fm_rss2_feed_option'];
                update_option('fm_rss2_feed_option', $fm_rss2_feed_option);
                $updated = true;
        }
        $fm_rss2_feed_option = get_option('fm_rss2_feed_option');

The checkboxes work a little bit differently than text input boxes. If you uncheck a checkbox, you do NOT get input. Since this is an on/off switch, the fix is to simple check if the value is the same as what is stored since only two values are possible.

Now I add in the bit of HTML to ask the user to check off whether they want the favicon added to their RSS2 feed:

                                <legend>Images in Feeds</legend>
                                <table width="100%" cellspacing="2" cellpadding="5" class="editform">
                                <tr valign="top">
                                        <th width="33%" scope="row">Add to RSS2 Feed?</th>
                                        <td><input name="fm_rss2_feed_option" type="checkbox" value="Y" <?php if ($fm_rss2_feed_option=="Y") echo "checked"; ?> >
                                        </td>
                                </tr>
                                </table>

This is put into the fieldset wrapper of the options page.

Atom is identical, but the image is added through an &lt;icon&gt; marker and the value is simply the location of the favicon.

The feed images are handled a little differently from the header favicons. They don’t actually have to be 16×16, they can be a little bit larger. Traditionally they appear along the header field in an aggregator, and if you look at a wunderground.com weather feed in Bloglines, you’ll notice a relatively large rainstorm/weather icon at the top of its articles. But (using Bloglines for reference again), the images can also be used on the left in Blogline’s “bookmarks” tree. It may be worthwhile giving an optional image field for the feeds: if it’s left empty use the favicon, otherwise use the image for the feeds only. I haven’t decided…

Support Files

Although the code is written up and tested, I’m not yet finished. I need to put together a couple more things:

  • A readme.txt file to be bundled with the favicon manager php file
  • A zipped version with the correct directory, etc to be put out in the public directory
  • A help/support page where potential users can read about the plugin, find directions for installing, and find the bundle itself

There’s a few other more optional actions to take as well, such as whether to register the plugin with Codex, WP Plugins Database, and other forums that collect plugin info.

Some Thoughts

I might be able to make this plugin work for earlier versions of WordPress by protecting the feed options with a check for the existence of the feed hooks. If they’re not there, then skip all the feed elements. Thus the plugin would degrade to favicons-in-headers-only mode, provided none of the other function calls or hooks have changed substantially. But given that I have written this well after the 2.0 upgrade, I’m not particularly inclined to do this…especially since I don’t have the means for testing it anyway.

Italian

Panoramica

Ho scavato più in profondità nella documentazione di WordPress, perchè volevo che il mio plugin rispettasse alcuni criteri: volevo che avesse un pannello di amministrazione perchè NON volevo che chiunque lo usasse fosse obbligato a fare altro che impostare opzioni tramite il pannello. In altre parole, basta modifiche al codice.

Diverse ragioni per questo. Primo, non tutti gli utenti WordPress sono smanettoni come me. Secondo, è noioso anche per gli smanettoni come me cambiare temi o aggiornare WordPress e dover riapplicare tutte le piccole modifiche. Per questo motivo sto diventando la più grande fan dei plugin plug’n’play.

Per essere onesti, non sempre questo è evitabile. In particolare, gli elementi delle barre laterali non sono facilmente integrabili (credo sia questa l’idea alle spalle dei widget, ma non ho ancora approfondito abbastanza da esserne certa). In ogni caso ho già visto diversi metodi interessanti nel lavoro di altri autori di plugin, e credo sia possibile evitare molti di questi problemi.

Comunque sia, questo plugin riguarda le favicons. Questa era la mia lista dei desideri:

  1. Poter inserire una immagine arbitraria come favicon
  2. Poter specificare l’immagine rilevante nella mia cartella WordPress anzichè come URI assoluta.
  3. Poter modificare questa immagine in qualunque momento.
  4. Poter usare files gif/icon/png per la favicon
  5. Eventualmente usare l’immagine nel mio feed rss2
  6. Eventualmente usare l’immagine nel mio feed atom
  7. Tutto questo configurabile nel pannello di amministrazione
  8. Un plugin “plug and play” - da installare e attivare, null’altro.

Con mia sorpresa, questo è stato abbastanza semplice. Più o meno un ora per leggere la documentazione rilevante, circa 15 minuti per programmare, un’altra ora per il collaudo, e quasi due ore di scrittura e documentazione :-D Questa è un proporzione abbastanza tipica…

Il plugin completo è disponibile all’indirizzo
http://www.digitalramble.com/favicon-manager-wordpress-plugin/
(date un’occhiata sul lato).

Agganci agli header

Per aggiungere qualcosa agli header, senza obbligare l’utente a modificare i propri files di WordPress, potete usare


// insert favicon into header using hooks
add_action('wp_head', 'add_favicon_to_headers');

dove add_favicon_to_headers è una semplice funzione senza parametri che inserisce ciò che volete all’interno degli header. E’ molto semplice. La prima bozza della funzione è in grado di fare ciò che vorremmo facesse, durante i test:


function add_favicon_to_headers()
{
  $favicon_location="http://example.com/example.ico";
  $favicon_type="x-icon";
  print ' <link rel="icon" href="'. $favicon_location .'" type="image/'. $favicon_type .'" />';
  print "n";
  print ' <link rel="shortcut icon" href="'. $favicon_location .'" type="image/'. $favicon_type .'" />';
  print "n";
}

Ovviamente questa è solo una prima stesura, giusto per essere certi che funzioni. E può funzionare, se inserite il codice qui sopra (all’interno dei codici ?php e con un indirizzo corretto al posto di example.ico) in un file con estensione .php nella vostra cartella dei plugin. Esiste infatti un semplice favicon plugin che fa esattamente questo ma non è configurabile come ho detto nella mia lista dei desideri ;-)

Database

Per avere valori persistenti e recuperabili, ho dovuto fare uso delle utilità a livello database offerte in WordPress. Ci sono add_option, update_option e get_option per un interfacciamento semplice. Quindi farò in modo di verificare che sia presente un dato nel database con l’indirizzo della favicon:


// add the saved items to the database if not already there
function favicon_mgr_add_options()
{
        add_option('fm_favicon_location', '');
}
 
favicon_mgr_add_options();

A questo punto il database ha ora un nuovo elemento, con un valore vuoto (una stringa di testo) disponibile per questo plugin. Ho provato a usare nomi lunghi e descrittivi (nelle funzioni, N.d.T.) per ridurre l’eventualità di una collisione di name space. Sarebbe stato più semplice per le mie dita usare solo “favicon”, ma ovviamente sarebbe stata più alta la possibilità che qualcuno abbia avuto prima o poi la mia stessa brillante idea.

Questo significa che l’aggancio ora può recuperare valori dal database:


function add_favicon_to_headers()
{
  $favicon_location=get_option('fm_favicon_location');
  $favicon_type=get_favicon_type($favicon_location);
  print ' <link rel="icon" href="'. $favicon_location .'" type="image/'. $favicon_type .'" />';
  print "n";
  print ' <link rel="shortcut icon" href="'. $favicon_location .'" type="image/'. $favicon_type .'" />';
  print "n";
}

Ora potete vedere perchè ho usato le variabili fino ad ora :-). La funzione get_favicon_type è un’altra funzione che ho scritto (e non ho incluso sopra per chiarezza) che restituisce il tipo corretto (x-icon, gif, jpg, png) a seconda del nome della favicon. In questo modo la funzione è pronta qualunque sia l’input dell’utente (dovrei aggiungere un controllo nel caso l’estensione sia sconosciuta, ma ancora una volta sto cercando di rendere le cose più semplici possibile).

Pannello di amministrazione

WordPress offre anche un set diretto di funzioni per crare un pannello di amministrazione. E’ stato decisamente semplice. Per prima cosa è presente un aggancio per inserire un nuovo menù sotto il menu Opzioni (potete fare anche altro, ma per cose basilari come queste, Opzioni è più che sufficiente).


// create hook for new submenu
add_action('admin_menu', 'favicon_mgr_admin_menu');
 
// title of page, name of option in menu bar, which function lays out the html
function favicon_mgr_admin_menu()
{
        add_options_page(__('Favicon Manager Options'), __('Favicons'), 5, basename(__FILE__), 'favicon_mgr_options_page');
}
 
// html layout for option page, plus detection/update on new settings
function favicon_mgr_options_page()
{
  ...
}

Quindi, tutto ciò che questo produce è l’inserimento di un oggetto menu. L’oggetto specifica a sua volta la funzione che definirà la pagina. Quindi, la funzione inserirà il codice necessario a permettere gli input e il resto. Questa pagina dovrà inoltre poter aggiornare i record nel database in modo che gli agganci della testata possano ricevere i valori corretti da inserire nella stessa. In questo modo le cose iniziano a essere collegate. Una prima stesura della pagina di opzioni:


function favicon_mgr_options_page()
{
        $updated = false;
 
        if (isset($_POST['fm_favicon_location']))
        {
                $fm_favicon_location = $_POST['fm_favicon_location'];
                update_option('fm_favicon_location', $fm_favicon_location);
                $updated = true;
        }
        $fm_favicon_location = get_option('fm_favicon_location');
        if ($updated)
        {
                ?>
                <div class="updated">
<strong>Options saved.</strong></div>
                <?php
        }

Prendiamo una pausa rinfrescante. Ricordiamoci che questa pagina verrà mostrata solo quando l’utente entrerà nella pagina di opzioni, oppure dopo aver modificato le opzioni stesse. Quindi la prima cosa da verificare è se l’elemento input del modulo è stato modificato o meno. Nel primo caso, verrà inserito nel database, e verrà impostato update su true.


        ?>
        <div class="wrap">
                <h2>Favicon Settings</h2>
                <form name="form1" method="post" action="<?php echo $_SERVER['REQUEST_URI']; ?>">
 
                        <fieldset class="options">
 
                                <legend>Favicon in WordPress Pages</legend>
                                <table width="100%" cellspacing="2" cellpadding="5" class="editform">
                                <tr valign="top">
                                        <th width="33%" scope="row">Location:</th>
                                        <td><input name="fm_favicon_location" type="text" width="60" value="<?php echo $fm_favicon_location; ?>"/>
                                        </td>
                                </tr>
                                </table>
 
                        </fieldset>
 
                        <p class="submit">
                          <input type="submit" name="Submit" value="Update Options &raquo;" />
 
                </form>
 
        </div>
        <? php

Questa parte restituisce la pagina del modulo, con i valori nel campo imput se sono già impostati. La presentazione è già controllata tramite i fogli di stile e le classi usate, quindi verrà usato il familiare tema bianco e blu.

E’ tutto qui! In pratica gli unici elementi non inseriti sono la posizione abitraria o relativa della favicon (voglio che gli utenti abbiano la possibilità di inserire entrambe) e l’opzione RSS2/Atom. La prima è risolta facilmente con una ulteriore funzione:


function create_favicon_uri($favicon_location)
{
  // if an absolute location entered, don't try to add the site url...
  if (preg_match("/^http/", $favicon_location))
  {
        $favicon_url=$favicon_location;
  }
  else
  {
        $favicon_url= get_settings('siteurl') . '/' . $favicon_location;
  }
  return $favicon_url;
}

Ora aggiornerò le istanze in cui richiamo $favicon_location per processare i risultati tramite questa funzione prima di usarli. Non userò comunque questa funzione prima di memorizzare la posizione nel database. Per evitare confusioni da parte dell’utente, preferisco tenere ciò che hanno inserito.

L’opzione Feed

Spiegherò solamente l’aggiunta per RSS, in quanto l’opzione Atom è identica, eccetto l’output nell’aggancio.

A partire da WordPress 2.0, sono forniti agganci per gli RSS2:


function add_image_to_rss2_feed()
{
  // do this or not depending on user settings in panel!
  if (get_option('fm_rss2_feed_option')=="Y")
  {
        $favicon_location=create_favicon_uri(get_option('fm_favicon_location'));
        echo "<image>n";
        echo "  <link>". get_bloginfo_rss('url') ."</link>n";
        echo "  <url>". $favicon_location ."</url>n";
        echo "  <title>". get_bloginfo_rss('name') ."</title>n";
        echo "</image>n";
  }
}
 
// insert image into rss2 feed
add_action('rss2_head', 'add_image_to_rss2_feed');

Quindi inserirò nel mio database:


// add the saved items to the database if not already there
function favicon_mgr_add_options()
{
        add_option('fm_favicon_location', '');
        add_option('fm_rss2_feed_option', '');
}

Questo verrà aggiunto alla pagina di opzioni prima dell’output, a prescindere dal fatto che le nuove opzioni siano già salvate.


        // checkboxes flip on/off
        if ($_POST['fm_rss2_feed_option']!=get_option('fm_rss2_feed_option'))
        {
                $fm_rss2_feed_option = $_POST['fm_rss2_feed_option'];
                update_option('fm_rss2_feed_option', $fm_rss2_feed_option);
                $updated = true;
        }
        $fm_rss2_feed_option = get_option('fm_rss2_feed_option');

Le caselle di selezione funzionano in modo leggermente differente dai campi di input testuale. Se deselezionate una casella, NON avrete un input. Dal momento che è un selettore acceso/spento, la soluzione è controllare se il valore è lo stesso di quello memorizzato, dal momento che solo due valori sono possibili.

Ora aggiungerò del codice HTML per chiedere all’utente di scegliere se usare la favicon nei propri feed RSS2:


                               <legend>Images in Feeds</legend>
                                <table width="100%" cellspacing="2" cellpadding="5" class="editform">
                                <tr valign="top">
                                        <th width="33%" scope="row">Add to RSS2 Feed?</th>
                                        <td><input name="fm_rss2_feed_option" type="checkbox" value="Y" <?php if ($fm_rss2_feed_option=="Y") echo "checked"; ?> >
                                        </td>
                                </tr>
                                </table>

Questo è inserito nel contenitore fieldset della pagina di opzioni.

Atom è identico, ma l’immagine è inserita tramite un tag e il valore è semplicemente l’indirizzo della favicon.

Le immagini dei feed sono gestite in modo differente dalle favicon della testata. Non devono essere per forza 16×16, ma possono essere un po’ più grandi. Di solito appaiono accanto al campo della testata in un aggregatore, e se date un’occhiata al feed delle previsioni del tempo su Bloglines, potrete notare una icona relativamente grande in cima ai suoi articoli. Ma (usando per esempio ancor Bloglines), le immagini possono anche essere usate sulla destra, nei bookmarks di Bloglines (le informazioni su Bloglines possono essere variate, N.d.T. ). Può valere la pena offrire un campo opzionale per l’immagine dei feed: se è lasciato vuoto verrà usata la favicon, altrimenti verrà usata questa immagine solo per i feed. Non ho ancora deciso…

Files di supporto

Anche se il codice è scritto e collaudato, non ho ancora finito. Devo aggiungere a questo alcune cose:

* Un file readme.txt da allegare con il file php del plugin
* Una versione compressa con le cartelle e i files corretti da mettere nella mia cartella pubblica
* Una pagina di aiuto e supporto dove i potenziali utenti potranno trovare informazioni sul plugin, istruzioni per l’installazione, e dove sarà disponibile l’archivio stesso.

Ci sono alcune azioni facoltative che potreste voler intraprendere, come registrare il plugin su Codex, nel database dei plugin WP, e in altri forum che raccolgono informazioni sui plugin.

Alcuni pensieri

Potrei essere in grado di rendere questo plugin funzionante con versioni precedenti di WordPress, proteggendo l’opzione dei feed con un controllo sulll’esistenza dell’aggancio ai feed. Se non è presente, allora evita tutti gli elementi feed. In questo modo il plugin dovrebbe degradare in modalità favicon-solo-header, tenendo conto che nessuna delle altre funzioni è stata modificata. Ma dato che ho scritto questo ben dopo l’aggiornamento alla versione 2.0, non sono particolarmente invogliata a farlo… specialmente visto che non ho i mezzi necessari per fare i test.

del.icio.us:anatomy of a new plugin  digg:anatomy of a new plugin

Comments (19)

upgrading to WordPress 2.03

OK, WordPress just came out with a minor upgrade the other day. I decided to go ahead and play with this one for several reasons. First, for all that this is minor, there’s a pretty good security patch to it, the “nonce” security key that reduces the chance of someone hacking their way into the admin panel. Second, a more major upgrade (2.1) is planned for the end of summer and this would be good practice before then.

Note that some minor bugs have already been found with 2.03 (!) and a plugin released to fix those issues, which I include in the steps below. Also, if you have modified any of these files that get replaced, you may have to merge the changes with the new files. For example, I modified my rss feeder to include an image. I’ll diff the new file with my old one and if the only changes are mine, put mine back in, otherwise patch my changes into the new file.

Going from WordPress 2.0.2 to 2.0.3

  1. First back up your installation. Back up both the files in your wordpress directory and also your database. (If you haven’t got this plugin, I highly recommend it.)
  2. Remove the wp-admin directory
  3. Remove the wp-includes directory. (If you added any translation/language files/directories, keep these.)
  4. Remove all the files in the directory where WP is installed, except wp-config.php.
  5. Download and unpack 2.0.3. Do this in a separate directory, so you can control which files and directories you copy over.
  6. Install the new directories wp-admin and wp-includes.
  7. Install the files of the top directory, except for wp-config-sample.php.
  8. On entering the admin panel after this, you will see the following message:
    “Your database is out-of-date. Please upgrade” with the link to update the database. Follow the directions.

  9. Remove the files wp-admin/upgrade.php and wp-admin/install.php.
  10. Download the plugin fix here. Add and activate, no further editing needed.

(Props to blogpocket for the initial how-to list, which I translated & added commentary.)

del.icio.us:upgrading to WordPress 2.03  digg:upgrading to WordPress 2.03

Comments (1)

wading through technical difficulties…

It never rains but it pours! Last night and much of this evening I spent chasing down problems of various sorts. (To any rss feed readers, I do apologize; it seems that any changes made to the content of a post results in a few feed being prepared for that post; one of the items on my todo list is to figure out how to turn that off when I’m tinkering under the hood.)

Seems that I had/have a couple of problems. First of all I had a poor permalink customization that didn’t end with a / which caused several problems such as not being able to navigate to paginated posts (which feature I tried for the first time in “flickr slideshow”). At about the same time I noticed that I couldn’t get comments working, either. Then when I checked error logs, I found that the codesnippets and smileys plugins were generating fairly generic (ie impossible to figure out what’s going on) error messages.

Aiee.

So in the process of tracking down the problems, I nuked the plugins, nuked the theme modifications and finally went back down to the default kubric theme. Nothing solved the problem so I put in a support request to find out what’s going on.

Of course, I couldn’t stop just tinkering around and googling around to see if I could find any solutions. That’s when I discovered that Wordpress actually recommends that permalinks end in /. Oh. OH. Right, right, the rewrite rules.

OK, so I went in and fixed that and lo and behold, pagination and comments started to work! Yay!

But there’s still a few oddities, such as the error messages in the log file which do not go away. There are certain plugins that just Do Not Work. Finally I found a bit of news rummaging through DreamHost’s Wiki that allow.url.fopen is disabled over here. I’m wondering if that’s the problem showing up in the log files, but grepping thru the directories for instances of include or fopen didn’t get me any results. DreamHost recommends curl wrappers instead, which I’ll be happy to do if this is the problem and if I can locate which are the problematic calls. So that part’s on hold for now.

Of course I couldn’t quite leave well enough alone, and I decided to go ahead (since I’d been munging my permalink structure all day anyway) and reorganize the WordPress setup in my account to put everything tidily away in a subdirectory while leaving the blog as the “main” item regardless. To that end, I followed the instructions here quite faithfully — putting all but index.php into a subdirectory called wordpress. It actually went pretty smoothly for the most part, so after finishing I went back and reloaded the blog. Oooh, pretty! Except my title gif is missing. So I went back and hunted thru and changed the bloginfo call from url to a more appropriate template_directory.

Only now none of the links on the page work: the about page, the pagination pages, the permalink, nothing. So it’s clearly some sort of rewrite rule and something with generating the permalinks. All of the bad links have an extra index.php in the middle of them. I went through a half dozen google articles moderately relevant to the issue, but didn’t really find anything. Then on a hunch I went back to the article and decided that step 4 seemed wrong, given everything I’d done. So I changed the blog address to just digitalramble.com instead of digitalramble.com/index.php as it says & redid the permalinks. *cough* As I was saying about buggy documentation the other day *cough*…

Voila. Everything looks like it works, aside from the error.log generation messages, and at this point I think I have to wait for DreamHost support to get back to me. Unless I can google up more info for allow_url_fopen and find anything else that it might be tripping that’s present in the affected plugins…

del.icio.us:wading through technical difficulties...  digg:wading through technical difficulties...

Comments

the best plugin

Well I’ve been playing around with plugins, which are one of the most fun things about WordPress. I’d've started this up a long time ago if I’d realized how fun it was. Anyway I’m using a number of plugins now, a quick list:

Akismet

Default spam thingie. Because, you know, of all the comments and spam I get.

Code Snippet 2.0

This one’s handy — you can use inline tags, along with the language listed to create nicely formatted code snippets. The only thing to watch out for is that it also converts html’s code marker. I went in and disabled that (just search on the pattern in the file and comment it out). I sent a note to the developer suggesting that making that an option would be a good thing. Especially since I make extensive use of the html code markup for inline words which made the conversion to a blockquote based presentation rather deleterious to my posts (not to mention re-generating a slew of feed revisions).

Angsuman’s Feed Copyrighter 1.0

Inserts copyright message into your feeds. You don’t see the message in your posts on the webpage, but when you check the feeds, you’ll see it there.

del.icio.us - Bookmark this! 1.1

This plugin will allow you to add an “Bookmark this page on del.icio.us” link on your sidebar / posts / wherever. Nice and simple. I still want to figure out some way of automatically uploading bookmarks to my posts into delicious, but that will be another day.

WP-DBManager 2.04

Now this was a nice find. The default save on demand is all well and good (and actually ok for me, cos I know mysql just fine). But this dandy thing gives you all kinds of options for managing your database backup, restoration and other goodies, whether or not you know anything about mysql.

WP-EMail 2.04

Thinking about this one. Adds a “mail this to a friend” thing. Do I want this?

Yahoo/MSN Style Smileys 4.4

I confess! I’m a long time Yahoo IM user, and their emoticons are “the” emoticons. Turn up your nose and pooh-pooh all you like. These are teh r00lz!

Live Comment Preview 1.7

Thinking about this one, too. It adds a live preview of your comment as you’re writing it up. This could be very useful for my vast hordes of commentators. Hm.

Ultimate Tag Warrior 3.1

Allows you to more extensively manage tags and links to social tagging utilities (technorati, etc). This plugin may be overkill for what I want. I haven’t decided whether it’s worth the trouble or if I should look for a smaller subset of more focused tag handlers… I do like the cloud that it provides, though.

However, by far the best plugin has been Now Reading 3.3. This is a very well done, very useful plugin that tracks the books you’ve read, are currently reading, and have finished. The books are summarized on your sidebar, plus you can look at individual books (along with any reviews and ratings you care to put in). The graphics are filched from amazon.com, where it does the lookups. I’m having so much fun with this, I’m slightly breaking my rule about keeping this blog work/technical related only. I’ll be putting in most of the books I’m reading and not just technical ones either. Althought I’ll probably refrain from keying in the more, ah, mind-candy type novels :-D

del.icio.us:the best plugin  digg:the best plugin

Comments

Next entries »

Bad Behavior has blocked 752 access attempts in the last 7 days.