Archive for the ‘Plugins’ Category

Timed disabling of Wordpress comments

September 6th, 2006 by daryl

I wrote the other night about my frustration with comments in Wordpress. The anti-spam tools that come with the software are great for squashing spam, but I still occasionally go through periods during which I get a bunch of emails asking me to log in and moderate spam, and that irritates me. Most of these moderation requests are for spam on old posts. So I decided to write a Wordpress plugin that would auto-disable comments and pings on old posts. This allows me to keep comments open for those who read my stuff and would like to comment within a reasonable timeframe but keeps me from having to go back and manually run mysql queries by hand (or, worse yet, manually edit old posts) to turn off comments on individual posts. (The Wordpress options for commenting affect only future posts.)

The plugin is a simple one, providing an option under the “Manage” and “Manage Comments” administrative screens allowing you to set the number of days old a post must be to have its comments disabled. If you post infrequently, this plugin won’t do you much good, as its action is triggered by the saving of a post. If you post every few days as I tend to, though, it’ll do an ok job of keeping old posts from picking up comment spam. The default threshold is 14 days. So any time I add or save a post, Wordpress runs a query that disables comments and pings on all posts created more than 14 days ago. That’s all there is to it.

Download the plugin here if you think you’d find it useful.

Amazon Plugin Ported to WP 1.5

February 24th, 2005 by daryl

I’ve updated the Amazon plugin to work with WordPress 1.5. The plugin uses a class called “Snoopy” to connect to Amazon, and this, it turns out, as been added as a class in the core WordPress code. So when I redefined it in my plugin, it was causing a problem with the Dashboard, which was trying to reinclude the class. The fix (thanks to George for beating me to the punch on diagnosing the problem and sending in a fix) can be downloaded here. The changes included deleting the Snoopy class definition and requiring snoopy-class.php from wp-includes.

Word Press and Del.icio.us; Word Press and Amazon

February 14th, 2005 by daryl

In a post this morning, I went over briefly my inclination to write an audioscrobbler plugin for Word Press. Other things I needed to aggregate for the project I was doing that for included del.icio.us feeds and amazon book lists. Flickr already provides a javascript snippet to display images, and I’m not going to take the time to rewrite that one for now. But I did decide to go ahead and write my own plugins to display del.icio.us and amazon information.

Why not use something that’s already out there, including my own amazon plugin? Well, the existing plugins aren’t as flexible as what I wanted to do. For example, you have to hack your index.php file in order to add the amazon wishlist output to your page unless you want it just automatically appended to your categories listing. Plus the amazon plugin retrieves wishlist info only, and you might want to display books you’re currently reading without risking adding them to your wishlist and getting duplicate copies. Additionally, I’m really digging the smarty engine that Word Press 1.5 uses, and in order to add stuff to templates, it makes pretty good sense to write the plugins as smarty plugins. The del.icio.us plugin doesn’t really require much flexibility and is essentially a duplication of the audioscrobbler plugin, though I’ve added a parameter that allows you easily to limit the number of links displayed. The template code is as follows:



<li>Del.icio.us
<ul>
{delicious feed=”http://del.icio.us/rss/tag/r2″ cache_dir=”/var/www/html/wpmu/wp-inst/cache/” records=”10″}
</ul>
</li>

You pass a feed URL, a writable directory to cache the feed in so we don’t tax the del.icio.us servers, and the maximum number of records to display. Part of the beauty of this plugin (or actually of the API that supports it) is that you can include the smarty tags several times in your template to display different feeds. And because things like the records limit are passed on a per-instance basis, there’s no global or function-scoped setting forcing you to always have X number of links, so you can have 10 blog links and 5 design links and 3 links of some other type, for example. The actual plugin code looks very much like the audioscrobbler code:

[php]
define(”CACHE_EXPIRY”, 60*10); //seconds to cache data for
define(”CACHE_DIR”, “/var/www/html/wpmu/wp-inst/cache/”);//where to cache

//Make this a smarty function by using the API’s naming convention.
function smarty_function_delicious($params, &$this){
//Bust params array into key=value pairs.
extract($params);

if($records==” || !$records || intval($records)==0){
$records=10;
}
//If no username param passed, we can’t very well fetch a feed.
if($feed==” || !$feed){
print “Could not load del.icio.us plugin.”;
}
//Else call the workhorse function and print the resulting output.
else{
$output=show_delicious($feed,$records);
print $output;
}
}

//Function to handle caching/fetching of URL.
function getDeliciousXmlUrl($url) {
$goodToUpdate = true;
$hash = md5($url);
$filename = CACHE_DIR.$hash;

//If we’ve already cached this feed…
if ( file_exists($filename) ) {
$time = filectime($filename);
//Check the time it was last cached based on cache file timestamp.
if ( $time > (time() - CACHE_EXPIRY) ) {
//it was last written less than CACHE_EXPIRY seconds ago
$goodToUpdate = false;
}
//Set $xmlFile to contents of cached file in case we need it.
$xmlFile = file_get_contents($filename);
}

//If we’re not cached or the cache has expired…
if ( $goodToUpdate ) {
//Get the url content. Your php.ini has to allow remote URLs to be opened as files for this to work.
$xmlString = file_get_contents($url);
if(!$xmlString){
//something broke, sliently move on
}
else{
//Write the contents to the cache filename determined above.
$fp=fopen($filename,’w');
fwrite($fp,$xmlString);
fclose($fp);

//Set $xmlFile to the newer data.
$xmlFile = $xmlString;
}

}
return $xmlFile;
}

//This does the real work of the plugin.
function show_delicious($url,$records) {
require_once “XML/Unserializer.php”;

//Get the XML from the passed URL.
$xml=getDeliciousXmlUrl($url);

//PEAR class that does the work invoked here.
$rss =& new XML_Unserializer();
$result= $rss->unserialize($xml,false); //False makes it treat the param as a string rather than as a file.
$feed=$rss->getUnserializedData();

//print “

$feed,1) . "

“;

$output=”";
//If no items in feed, let user know.
if(sizeof($feed["item"]) == 0){
$output .= “n

  • no recent links (” . sizeof($feed["channel"]["item"]) . “)
  • n”;
    }
    //Else iterate over the items and print out title/url.
    else{
    $del_count=1;
    foreach($feed["item"] as $item){
    if($del_count < = $records){
    $output .= "n

  • ” . $item["title"]. “n”;
    }
    else{
    break;
    }
    $del_count++;
    }
    }

    return $output;
    }
    [/php]

    The amazon plugin is a little more involved. Initially, it was very much like the other two plugins I’ve mentioned here, with the output hard-coded, but I wanted to make this one more flexible. For example, I wanted a user to be able to dictate what data fields were displayed and with what CSS selectors attached to them without having to define and hard-code a bunch of selectors and flags to determine what to code. In other words, I didn’t want users to have to type a tag like the following and still be limited as far as layout by some hard-coded values:


    {amazon dev_token="XXXXXXXXXXXX" associate_id="YYYYYYYY" isbn="4770029055,1400043662" cache_dir="/var/www/html/wpmu/wp-inst/cache/" image_class="small_image" show_small_image="1" title_class="amazon_title" show_title="1" price_class="price_class" show_price="1" release_date_class="rd_class" show_release_date="1"}

    Instead, I worked it out so that users can add something like the following to the template:


    <!--Amazon-->
    <li>Amazon
    <ul>
    {amazon dev_token="D3TF1MNM1YQKGD" associate_id="rationalisofeast" isbn="4770029055,1400043662" cache_dir="/var/www/html/wpmu/wp-inst/cache/"}
    {foreach from=$amazon_list key=key item=hits}
    <li><a class="amazon_link" href="{$hits.url}"><img class="amazon_image" src="{$hits.small_image}"><br/><span class="amazon_title">{$hits.title}</span><br/></a><b>Price: </b>{$hits.list_price}</li>
    {/foreach}
    </ul>
    </li>
    <!--End Amazon-->

    In other words, the design and determining what elements to display can be controlled completely through the template so that designers don’t have to go poking through PHP code to try to figure out how to change a style attribute on an image or a title. The key is knowing what parameters are valid to use within the template, and in this case, they’re as follows:

    • isbn
    • title
    • url
    • authors
    • catalog
    • small_image
    • medium_image
    • large_image
    • availability
    • list_price
    • sale_price
    • used_price
    • release_date

    Now for a brief description of how the template parsing works (or, more accurately, what you need to know in order to incorporate these attributes into your template). First, you have to include the line:


    {amazon dev_token="XXXXXXXXXXXXX" associate_id="YYYYYYYY" isbn="4770029055,1400043662" cache_dir="/var/www/html/wpmu/wp-inst/cache/"}

    The dev_token parameter is something you get from amazon, as is the associate_id (which allows you to get monetary credit for books purchased through the link this generates). The cache_dir, as in the other plugins, should represent a Web-server-writable path on your system and is used to help keep load down on the servers we’re connecting to in order to get the data. The isbn parameter contains a comma-separated list of the ISBNs for the books you want to display. Ideally, this can one day be dynamic or based on info pulled from a database and populated through an admin tool, but for now, this does the trick. This line of code causes the data to be grabbed from amazon and stored in the smarty object. Which is where the foreach in the template comes in. The forech block tells smarty to iterate over the variable $amazon_list (which the line above created and populated with an array for each book retrieved) and to store the array in a local variable named “hits.” The values of the array for each iteration can be accessed using dot-syntax, where the piece after the dot corresponds to one of the keys defined in the list above. In other words, we’re iterating over the array returned by the initial line and, for each array within that array, plugging its values in by name where listed within brackets here using the dot-syntax. This allows designers to wrap whatever layout and design tags they wish to around the data and keeps design-retarded coders like me from making stupid design decisions that are hard-coded into the smarty plugin. Within the foreach loop, to get the title for a given book, we’d use {$hits.title}. To get the url, we’d use {$hits.url}. And so on. The code for the plugin itself is as follows:

    [php]
    define(”CACHE_EXPIRY”, 60*10); //seconds to cache data for
    define(”CACHE_DIR”, “/var/www/html/wpmu/wp-inst/cache/”);//where to cache
    define(”BASE_AMAZON_URL”,’http://xml.amazon.com/onca/xml3?page=1&type=lite&locale=us&f=xml’);
    //http://xml.amazon.com/onca/xml3?locale=us&t=rationalistsofeas&dev-t=D3TF1MNM1YQKGD&AsinSearch=4770029055&mode=books&sort=+titlerank&offer=All&type=lite&page=1&f=xml

    //Make this a smarty function by using the API’s naming convention.
    function smarty_function_amazon($params, &$this){
    //Bust params array into key=value pairs.

    extract($params);

    if($dev_token==” || $isbn==”){
    print “Must pass dev_token and isbn as params”;
    exit;
    }
    if($records==” || !$records || intval($records)==0){
    $records=5;
    }
    $feed=BASE_AMAZON_URL . “&dev-t=” . $dev_token . “&t=” . $associate_id . “&AsinSearch=” . $isbn;
    // print $feed; exit;
    $output=show_amazon($this,$feed,$records,$associate_id);
    print $output;
    }

    //Function to handle caching/fetching of URL.
    function getAmazonXmlUrl($url) {
    $goodToUpdate = true;
    $hash = md5($url);
    $filename = CACHE_DIR.$hash;

    //If we’ve already cached this feed…
    if ( file_exists($filename) ) {
    $time = filectime($filename);
    //Check the time it was last cached based on cache file timestamp.
    if ( $time > (time() - CACHE_EXPIRY) ) {
    //it was last written less than CACHE_EXPIRY seconds ago
    $goodToUpdate = false;
    }
    //Set $xmlFile to contents of cached file in case we need it.
    $xmlFile = file_get_contents($filename);
    }

    //If we’re not cached or the cache has expired…
    if ( $goodToUpdate ) {
    //Get the url content. Your php.ini has to allow remote URLs to be opened as files for this to work.
    $xmlString = file_get_contents($url);
    if(!$xmlString){
    //something broke, sliently move on
    }
    else{
    //Write the contents to the cache filename determined above.
    $fp=fopen($filename,’w');
    fwrite($fp,$xmlString);
    fclose($fp);

    //Set $xmlFile to the newer data.
    $xmlFile = $xmlString;
    }

    }
    return $xmlFile;
    }

    //This does the real work of the plugin.
    function show_amazon(&$smarty,$url,$records,$associate_id) {
    require_once “XML/Unserializer.php”;

    //Get the XML from the passed URL.
    $xml=getAmazonXmlUrl($url);

    //PEAR class that does the work invoked here.
    $rss =& new XML_Unserializer();
    $result= $rss->unserialize($xml,false); //False makes it treat the param as a string rather than as a file.
    $feed=$rss->getUnserializedData();

    //print “

    " . print_r($feed,1) . "

    “;

    $output=”";
    //If no items in feed, let user know.
    if(sizeof($feed["Details"]) == 0){
    $output .= “n

  • no products found
  • n”;
    }
    //Else iterate over the items and print out title/url.
    else{
    $am_count=1;
    $items=array();
    foreach($feed["Details"] as $item){
    if($am_count < = $records){
    array_push($items,array(
    "isbn" => $item["Asin"],
    “title” => $item["ProductName"],
    “url” => “http://www.amazon.com/exec/obidos/ISBN%3D” . $item["Asin"] . “/” . $associate_id,
    “authors” => join(”, “,$item["Authors"]),
    “catalog” => $item["Catalog"],
    “small_image” => $item["ImageUrlSmall"],
    “medium_image” => $item["ImageUrlMedium"],
    “large_image” => $item["ImageUrlLarge"],
    “availability” => $item["Availability"],
    “list_price” => $item["ListPrice"],
    “sale_price” => $item["OurPrice"],
    “used_price” => $item["UsedPrice"],
    “release_date” => $item["ReleaseDate"],
    ));
    //$output .= “n


  • ” . $item["ProductName"]. “
  • n”;
    }
    else{
    break;
    }
    $am_count++;
    }
    $smarty->assign(”amazon_list”,$items);
    }

    return $output;
    }
    [/php]

    Word Press and Audioscrobbler

    February 14th, 2005 by daryl

    My new company’s Web site will feature blogs by those of us who have interesting things to say about our industry. In order to make the blogs richer and more personalized, the guy coordinating them wants each blog to have its own del.icio.us feeds, Audioscrobbler feeds, Flickr feeds, etc. Initially, I had settled on using Movable Type because, in addition to providing multiple blogs for multiple users, there were already plugins to do all of these things, and there was a plugin to aggregate all posts into one blog, which blog could be used as the home page. And since each user had his own template, the feeds could all be distinct without the need to hack any code.

    Another guy working on the Web site started pushing Word Press really hard, and with good reason. It’s a great blogging system and is in fact what I use for my blog. Furthermore, it’s written using PHP rather than perl (MT uses perl) and so is much more pleasant for me to maintain. But while it boasts multiple-blogger functionality, there’s no way short of installing a new version of the software for each blogger to let bloggers have different templates. Or I didn’t think there was, at any rate. It turns out that there’s a beta version of a multi-user Word Press. Essentially, it’s a set of hacks that let the application keep redundant data across blogs in some main tables, duplicating tables only for blog-specific info (such as posts). It’s pretty ugly, and one actually probably would have about as easy a time, for smaller blog setups, just installing the software multiple times. Matt Mullenweg, the creator of Word Press, has said as much. Word Press MU is still in beta, after all.

    I took a stab at writing a plugin that would aggregate posts from all blogs into a single blog post listing, and it was a bit of a pain precisely because blogs are stored in different tables rather than in the same table with different ids. I got the base functionality working, but it actually becomes very complex to make it work with any granularity at all. For example, to display a permalink and have it link to the right blog (rather than simply the current one, for which the permalink might not be valid), you have to do all sorts of wizardry. And I didn’t even try to screw with displaying categories on a per-blog basis. I got things to a point at which they’re usable for my purposes, though, and decided to move on to integrating plugins to handle del.icio.us, audioscrobbler, and flickr. Luckily, plugins for these bits of functionality already exist.

    Except that the widely-publicized one for audioscrobbler has been removed. So my fun late last week and this morning included rolling my own. Actually, I found another one, but it assumes that you have PHP5, which I don’t (and don’t want to upgrade right now). So I took pieces of that one and modified it. Further, I turned it into a smarty template plugin that makes it dead simple to use in the MU version of Word Press, which uses smarty to handle templating and template caching. So in order to add an audioscrobbler feed to a template now, I have to add only the following to the template:


    <!--Audioscrobbler-->
    <li>Audioscrobbler
    <ul>
    {audioscrobbler username="factoryjoe" cache_dir="/var/www/html/wpmu/wp-inst/cache/"}
    </ul>
    </li>
    <!--End Audioscrobbler-->

    And actually, only the middle line is essential; the other stuff’s there because that’s what makes the output appear correctly within my template. The username parameter of course represents the audioscrobbler username, and the cache_dir parameter tells the plugin where to cache feed information. Basically, it’s rude and in most cases in violation of a service agreement to fetch a feed for every page load, so my code caches the feed and refreshes the local cache periodically.

    The primary thing the original plugin needed PHP5 for was XML parsing. PHP5 comes with lots of built-in tools for doing that, while PHP4 tends to rely on hand-rolled classes. There are some PEAR classes that’re good for parsing feeds, so I modified the relevant code to use them instead of PHP5’s tools. I also added code to register the code as a smarty template function. Here’s the code:

    [php]
    define(”CACHE_EXPIRY”, 60*10); //seconds to cache data for
    define(”CACHE_DIR”, “/var/www/html/wpmu/wp-inst/cache/”);//where to cache; a default that’s overridden in the template parameters
    define(”BASE_AS_URL”,”http://ws.audioscrobbler.com/rdf/history/”); //Where to look for the feed (will append username)

    //Make this a smarty function by using the API’s naming convention.
    function smarty_function_audioscrobbler($params, &$this){
    //Bust params array into key=value pairs.
    extract($params);

    //If no username param passed, we can’t very well fetch a feed.
    if($username==” || !$username){
    print “Could not load Audioscrobbler plugin.”;
    }
    //Else call the workhorse function and print the resulting output.
    else{
    $output=show_audioscrobbler(BASE_AS_URL . $username);
    print $output;
    }
    }

    //Function to handle caching/fetching of URL.
    function getXmlUrl($url) {
    $goodToUpdate = true;
    $hash = md5($url);
    $filename = CACHE_DIR.$hash;

    //If we’ve already cached this feed…
    if ( file_exists($filename) ) {
    $time = filectime($filename);
    //Check the time it was last cached based on cache file timestamp.
    if ( $time > (time() - CACHE_EXPIRY) ) {
    //it was last written less than CACHE_EXPIRY seconds ago
    $goodToUpdate = false;
    }
    //Set $xmlFile to contents of cached file in case we need it.
    $xmlFile = file_get_contents($filename);
    }

    //If we’re not cached or the cache has expired…
    if ( $goodToUpdate ) {
    //Get the url content. Your php.ini has to allow remote URLs to be opened as files for this to work.
    $xmlString = file_get_contents($url);
    if(!$xmlString){
    //something broke, sliently move on
    }
    else{
    //Write the contents to the cache filename determined above.
    $fp=fopen($filename,’w');
    fwrite($fp,$xmlString);
    fclose($fp);

    //Set $xmlFile to the newer data.
    $xmlFile = $xmlString;
    }

    }
    return $xmlFile;
    }

    //This does the real work of the plugin.
    function show_audioscrobbler($url) {
    require_once “XML/Unserializer.php”;

    //Get the XML from the passed URL.
    $xml=getXmlUrl($url);

    //PEAR class that does the work invoked here.
    $rss =& new XML_Unserializer();
    $result= $rss->unserialize($xml,false); //False makes it treat the param as a string rather than as a file.
    $feed=$rss->getUnserializedData();

    $output=”";
    //If no items in feed, let user know.
    if(sizeof($feed["item"]) == 0){
    $output .= “n

  • no recent tracks (” . sizeof($feed["channel"]["item"]) . “)
  • n”;
    }
    //Else iterate over the items and print out title/url.
    else{
    foreach($feed["item"] as $item){
    $output .= “n

  • ” . $item["description"]. “
  • n”;
    }
    }

    return $output;
    }

    [/php]

    I just added this code to a file called function.audioscrobbler.php in the smarty-plugins directory, added the template code listed above to my template, and — voila — I had an audioscrobbler feed in my sidebar. Pretty nifty.

    Extending MediaWiki

    January 28th, 2005 by daryl

    MediaWiki is the software that drives Wikipedia, a huge online collaborative encyclopedia that is at times at the heart of a fair amount of controvery having to do with matters of the site’s reliability, given that it’s authored by Joe Public. When I’ve installed wikis before, I’ve usually gone with phpwiki, which is very simple and somewhat less intimidating than Mediawiki. My new company decided to use a wiki as the starting point for our intranet, and I decided to take the plunge and try out MediaWiki.

    As it turns out, the software’s a breeze to install and a dream to use. Its interface is crisp and simple to navigate, and it’s got loads of formatting options. Among the things we wanted to add to the wiki to make it more extranet-like was our company del.icio.us feed, which contains links relevant to our plans. Naturally, rather than just showing the raw RSS feed, we wanted to parse the feed and display it as a list of links. Which presented a bit of a problem, as MediaWiki out of the box doesn’t allow parsing of code. So I couldn’t very well just put in a PHP block that’d parse the feed and convert it to a list of links.

    I read around a little and confirmed my suspicion that you can write extensions for MediaWiki. It’s actually very simple. Because MediaWiki’s schtick is to parse tags, the extensions API assumes that you’re going to define a new tag to be parsed, and once you register the extension, any time you use the newly defined html-style tag in an entry, it passes the content between the tags to the extension and prints the return value to the screen in place of the tag and its contents. So for example, you could define a tag “<name>” and have its extension just return your name. Whenever the wiki’s parsing a page and runs across the <name> tag, it’ll substitute your name. In my case, I needed a tag that’d parse a PHP block. The extension I wrote is as follows:

    //Add the hook function call to an array defined earlier in the wiki code execution.
    $wgExtensionFunctions[] = “wfPhpParse”;

    //This is the hook function. It adds the tag to the wiki parser and tells it what callback function to use.
    function wfPhpParse() {
    global $wgParser;
    # register the extension with the WikiText parser
    $wgParser->setHook( “phpcode”, “renderPhpParse” );
    }

    # The callback function for converting the input text to HTML output
    function renderPhpParse( $input ) {
    //Eval the code between the tags.
    return eval($input);
    }

    Once you’ve written the extension, you add a line to LocalSettings.php in the root that includes the extension file. And that’s it. To use the extension within a wiki entry, I’d type something like the following:

    <phpcode>
    $txt="The date is " . date('M d, Y') . ".";
    return $txt;
    </phpcode>
    

    Note that I’m building my text and returning the value. This is because a PHP eval (used in my extension) will execute the code in line unless it finds a return at the end. So if you want the eval to return its value to the extension function to be returned to the main wiki code rather than just executing in line (which will give you weird results), you need to add any output to a variable and return the variable. This extension probably wouldn’t be the best in the world to use for a public wiki because it will indiscriminately execute PHP code submitted by users, and a malicious user could, for example, add to the main page an infinite loop that’d bring your site crashing to its knees. In my case, the wiki I’m administering is for private corporate use, and all users are trusted, so I feel ok about letting them add PHP code if necessary. I provide the example merely to demonstrate how absurdly easy it is to extend an already very cool piece of software.

    Captcha

    September 23rd, 2004 by daryl

    Thanks to this plugin, I’m now able to cut down on the amount of comment spam I have to moderate. Only recently (presumably with an increase in traffic thanks to my affiliation with the Spread Firefox project and my own authorship of a couple of apparently pretty popular Word Press plugins) did I start to get much spam. And even now it’s not that much. But after having to delete four or five spams from the same mouth breather within a few hours today, I figured I’d better look around for a solution that doesn’t require my daily intervention. Here’s hoping this’ll keep some of the automated spam out. Many thanks to Gudlyf for saving me the trouble of writing captcha code.

    Amazon Wishlist Plugin Updated

    September 20th, 2004 by daryl

    Tomi Junnila was kind enough to submit two edits to the Amazon Wishlist plugin. They include the ability to search non-US Amazon stores and an enhancement to the way multiple pages of results are fetched. (Formerly, it had been one page or all pages, with a request sent per batch of ten. So if you had 600 items in your wish list, you were sending 60 requests in order to print a single random item. Tomi’s change allows you to specify the number of pages of results to return, affording you more than the default ten results without blackholing you into request hell. Thanks, Tomi!

    Download from the usual link in the nav bar.

    Amazon Wishlist — Now with CD Artists

    September 3rd, 2004 by daryl

    Courtesy of Ken Scott, the Amazon Wishlist plugin now displays artists for CDs appearing in your wish list. You can download the plugin from the usual place. Thanks for this, Ken.

    Amazon Wishlist Updated Again

    August 17th, 2004 by daryl

    I’ve added some functionality to the Amazon Wishlist plugin that allows the user to define where to display the output. As in the initial version, the output can be displayed immediately after the category listing. This option will be best for those not inclined to edit their templates in any way. The second option is to invoke a function named “get_amazon_wishlist()” within any template to display the information.

    In order to display the book information as a coda to the category listing, one need only edit the plugin’s first line of uncommented code:

    [php]
    $aw_show_after_cats = 0;
    [/php]

    Setting this variable to 1 causes the book to be displayed automatically after the category listing.

    Leaving the variable set to 0 suppresses the automatic display of the book. If you wish to apply the plugin to your templates manually, you’ll need to edit wp-includes/template-functions-general.php to add the following function:

    [php]
    function get_amazon_wishlist(){
    echo amazon_wishlist(”");
    }
    [/php]

    Optionally, you could also just add the following inline within your template:

    [php]
    echo amazon_wishlist(”");
    [/php]

    Both methods simply call the plugin function.

    The revised plugin can be downloaded from the original url, here.

    Amazon Wishlist Updated

    August 16th, 2004 by daryl

    A user reported that the Amazon Wishlist plugin wasn’t returning results from any but the first ten books on her list. Sure enough, I checked, and Amazon’s API returns only ten results at a time. So I’ve extended the functionality. You can now set an option that tells the code whether to check the whole list or whether to check just the first ten books. In order to check beyond the first ten results, multiple requests have to be made. So if your list is 50 pages long (500 books), that’s 50 requests that have to be made to the Amazon Web service in order to display one random book on your site. If you’ve got a lot of books, you might want to opt for selecting from the short list, which I believe will usually represent your most recent additions. In any case, the additional option you can change is at the bottom of all the other variables you can set near the top of the script and looks like this:

    [php]
    $aw_search_all = 0; //Set to 1 to return all wishlist results rather than first 10 (requires additional requests, so longer processing)
    [/php]

    It’s set to 0 by default, just to be safe.

    I’ve also updated a bug that was causing an occasional error when the author block was being displayed. You’ll definitely want to download the new version (same location as the old version) to get this fixed or you’ll have “invalid argument passed to foreach” errors displayed sporadically on your page.

    The next planned update is to allow you to display your book anywhere on the page. Currently, I just piggyback it on top of the category listing. No telling when I’ll get to that update. If there’s any demand, I may also add code that allows you to set a page threshold so that if you have 500 books on your list but want to display from more than the first 10 (but not all 500), you can set a maximum number of requests.