Hefta-Gaub Development Blog

June 8, 2007

Crazy Globals Bug in Recent Posts Widget

Filed under: bug, development, recent posts, themes, widgets, Wordpress plugins, WordpressMU — zappoman @ 7:42 am

I’ve just discovered and fixed a small problem in the “Recent Posts” widget.

Basically this widget creates a second “loop” and will side effect several of the post globals (like $id and $post). The result will effect any downstream plugin that thinks it can count on these globals being available. This can also manifest in any theme (like Tarski) that has post related template calls AFTER the side bar widget.

I’ve fixed this problem but saving $post in a local variable and then resetting it after the loop call. I also call setup_postdata() to restore the other globals.

I just checked the latest version of widgets.php from “http://svn.wp-plugins.org/widgets/trunk/” and it still has this issue in it.

Here’s the new function…

function widget_recent_entries($args) {
    // This global $post is side effected by the call to $r->the_post()
    // and so in order to protect any uses of $post after our widget is
    // instantiated, we will save the value of the global and restore
    // it at the end of our function.
    global $post;
    $save_global_post = $post;

	extract($args);
	$title = __('Recent Posts', 'widgets');
	$r = new WP_Query('showposts=10');
	if ($r->have_posts()) :
?>
		<?php echo $before_widget; ?>
			<?php echo $before_title . $title . $after_title; ?>
			<ul>
			<?php  while ($r->have_posts()) : $r->the_post(); ?>
			<li><a href="<?php the_permalink() ?>"><?php if ( get_the_title() ) the_title(); else the_ID(); ?> </a></li>
			<?php endwhile; ?>
			</ul>
		<?php echo $after_widget; ?>
<?php
	endif;
    $post = $save_global_post; // restore the global that was side effected by $r->the_post()
    setup_postdata($post); // and restore the other globals that we also side effected when $r->the_post() called setup_postdata()
}

Advertisement

May 27, 2007

Common Themes Directory for Multiple Instances of WordPress?

Filed under: development, themes, Wordpress plugins, WordpressMU — zappoman @ 7:39 am

I have multiple installs of WordPress and WordPressMU running in the same system, and I want them to share a common Themes. I’ve been diligently updating the same theme in multiple directories… and frankly it sucks. Then I came across this forum post and was blown away!

So, I’ve implemented a plugin that allows you to set an absolute or relative path to a common themes directory.

Installation: Download the code from the link below. Rename the file to common-themes.php and place it in your plugins directory. Activate it.

Download: You can get a copy of the code here.

Usage: Set options in “Options->Theme Root Options”. Enjoy.

May 26, 2007

Improved WordPress to WordPress Importer

I’ve been playing around with importing WordPress blogs from one instance to another, and I’ve been frustrated by some of the default features of the built in WordPress to WordPress importer.

So, I’ve implemented a new version of the importer that has the following features:

  • Attachments – This importer will download and “insert” the actual image files of an attachment record. So for example, if you’ve uploaded images to your WordPress blog, then they will be listed as attachments. The normal importer will store these records but no do anything with the actual image. So you basically end up with dead links. Not anymore. Now if the image is an attachment, the importer will attempt to download it and insert it into the new blog. All of this downloading happens on your server, so you don’t actually have the files download to your client machine.
  • Links – Links to your own blog are remapped. This is particularly important for image links to attachments (obviously) or else the attachment feature described above would be pretty whacked! But it also applies to cross links between your own blog posts. Seems like an obvious feature right? I thought so. This also applies to internal ping backs.
  • Spam Comments – For some reason the default importer decides to import comments tagged as spam. I guess I can imagine a few cases where this might make sense… but nah… I don’t think so. So this importer will discard any comments marked as spam.

Installation: Download the code from the link below. Rename the file to zappo_wordpress.php and place it in your wp-admin/import directory.

Download: You can get a copy of the code here.

Usage: Same as any other importer, go to Manage->Import. Enjoy.

By the way, I really only tested this on WordPressMu, but there isn’t anything about it that I would expect to fail on standalone WordPress. Feel free to report bugs if you see issues.

Hey Zappo – This thing is really chatty, what gives? Do you think you could make it not print out so much noise? – You

No. But you can. Enjoy! – Me

Latest wpmu-topposts plugin

Filed under: development, sql, Wordpress plugins, WordpressMU — zappoman @ 10:14 am

Version 0.42.4 of wpmu-topposts plugin now available…

Lots of changes:

  • Added support for top_blogs(), same calling convention as top_posts() but returns
    top blogs based on total hits to the blog for all posts on the blog.
  • Added a couple new arguments to top_posts() include a new max_per_blog which if set
    to 1 will limit the posts to 1 per blog.
  • Added days_back argument which will limit the stats to a certain number of days
    into the past.
  • Added many new formatting arguments to make it easyer to use the get_*_html functions
    and get the formating you want.
  • Fixed a couple bugs that would cause cache corruption (removed a call to
    update_post_caches() which was definitley corrupting the post cache)
  • Also correctly call switch_to_blog() in the get_*_html functions so that the
    blog template tags actually work properly.

Definitely my favorite new feature is the max_per_blog since it uses cool nested queries in SQL. yummy!

Here are some usage examples:

This will give you top posts in an ORDERED list, with hits included surrounded by square brackets.

zap_top_posts_html('before_list=<ol>&
           after_list=</ol>&max_per_blog=-1&
           before_hits=[&after_hits=]');

This will give you top blogs in an UNORDERED list, without hits included.

zap_get_top_blogs_html('include_hits=0');

As always, get the latest code here

April 26, 2007

New Version of Sub-directory Plugin… now acts more like WordPress

Filed under: development, Wordpress plugins, WordpressMU — zappoman @ 10:47 pm

I’ve updated the subdir-mu-plugins Plugin to behave a little bit more like WordPress’s plugins and a little less like WordPress MU’s plugins. The latest version (0.42.2) can be found here.

Here’s a little background:

WordPress single instance will only load files that have the “Plugin Name:” directive. This is partly related to the fact that WordPress supports disabling plugins through a user interface. WordPressMU supports this feature as well for the plugins placed in the “wp-content/plugins” directory. But these plugins are enabled and disabled on a blog by blog basis. For those plugins in “wp-conten/mu-plugins” it will load all PHP files. So for example, if a plugin has extra support PHP files that aren’t safe to load all the time (but can be loaded at the right time by the plugin for example) these types of plugins don’t work well in WordPressMU.

My original version of this subdirectory plugin was intended to mimic the original WordPressMU behavior of loading all php files. Well, this seemed like a good idea at the time, but really the point of this plugin was to allow you to use more WordPress (non-MU) designed plugins… those that lived in subdirectories. And well, many of those plugins also depend on WordPress’s behavior of not loading PHP files that don’t contain the “Plugin Name:” directive. So I’ve decided this original behavior wasn’t the best idea.

The new version will scan subdirectories and attempt to read the plugin-info from all PHP files and only load those PHP files who have a “Plugin Name” directive.

I’ve now changed the behavior of this subdirectory loading plugin to behave a little more like WordPress. Namely it will only load files from subdirectories that have a “Plugin Name” directive.

April 24, 2007

The Case of the Disappearing TinyMCE

I’ve been having off and on problems with my TinyMCE rich text editor disappearing from WordPress… At first it seemed very random, sometimes it was there sometimes it wasn’t. Then it seemed like the problem went away, as in TinyMCE didn’t go away, and then the problem came back, as in TinyMCE was nowhere to be found.

Well, this weekend I finally figured out at least one thing that would cause this problem to happen.

Apparently one of my plugins was outputting an extra couple lines of non-php at the end of the file. Although this seems like a perfectly innocuous thing it causes big trouble for TinyMCE specifically the gzip support built in to the wordpress/tinyMCE integration.

So imagine this…

<?php
/***************************************
* Example of PHP that does nothing, except
* break TinyMCE.
*
* Notice that after the 'end php tag' there are
* two blank lines.
****************************************/
?>
 
 

These two extra lines will break TinyMCE. I haven’t found a minimal reproduce case yet, but I am sure this is related to the call to ob_start(“ob_gzhandler”); This sort of makes sense in that ob_start() is a relatively sensitive function insofaras you can’t call echo or other functions that output to the main output stream from within a callback function, but we’re not really doing that. I suspect there is some kind of a bug in ob_start() or in the ob_gzhandler handler that doesn’t like these kind of non-PHP outputs in the middle of a PHP stream.

Another case I found which creates this same behavior is…

<?php
/***************************************
* Example of PHP that does nothing, except
* break TinyMCE
*
* Notice that a single space outside of the
* php context.
****************************************/

?> <?php

?>

Anyway, if you see your TinyMCE disappearing on you, then it may be that you have a plugin with a couple extra blank lines at the end of the file outside the context of the PHP script processor.

April 6, 2007

Update to WPMU- Top Posts Plugin

Filed under: development, Wordpress plugins, WordpressMU — zappoman @ 12:51 am

Note, I’ve updated the code to 0.42.1 with the following changes…

  • Small bug fix to ‘maybe_create_table’ behavior. Namely, we used to try to load it if this function wasn’t available, and now we simply check that the function is available.
  • Added blog_id to the posts returned by get_top_posts. This can be useful in forming correct permalinks to your blog posts.
  • Added function zap_setup_post_globals() which in some cases will setup the globals for other wordpressmu templates to work, but this doesn’t always reliably work

You can get the latest code here.

Supporting Subdirectory Plugins in WordPressMU

Filed under: development, Wordpress plugins, WordpressMU — zappoman @ 12:27 am

WordPressMU treats plugins a little differently than standalone wordpress does. Namely it supports two types of plugins. Those loaded and controlled on a per-blog basis (like normal WordPress) which are stored in the wp-content/plugins directory; and those that are loaded for all blogs on all pages, which are stored in the wp-content/mu-plugins directory.

I won’t attempt to explain all the good reasons for why these plugins are segregated, instead this is a quick description of a small feature enhancement to the mu-plugins behavior. Namely, one of the differences between how plugins are loaded from mu-plugins vs. how they are loaded in standalone wordpress or the plugins directory; is that mu-plugins only loads php files in the root directory. (It also happens to include all php files, which is another important difference.)

What if you wanted to cleanup your mu-plugins directory a little and store some plugins in subdirectories. Well, here is a simple mu-only plugin that adds this feature.

Download: here.

Install: Rename this file as .php and place it in your “wp-content/mu-plugins” directory.

Usage:  You can now place mu-plugins into subdirectories of you “wp-content/mu-plugins” directory and they will load like any other mu-plugin.

March 17, 2007

Sitewide tags for WPMU without core changes

Filed under: development, Wordpress plugins, WordpressMU — zappoman @ 7:25 pm

Thanks to the hard work of Dr. Mike, users of WordPressMU have found a solution for implementing site-wide tags and searching without significant changes to the WordPressMU or WordPress core code bases. The basic idea behind the most popular solution is to make an instances of WordPress (classic) that stores a mirror of your WordPressMU sitewide feed. I won’t go into details explaining how this is done, because there is a very clear and well documented process found here in the WordPressMU forums.

I’ve used this solution and it appears to work very well, and is actually very easy to implement. It took me about an hour when I first set it up.

However, in the process of sharpening my wordpress skill, I wanted to learn a little bit more about filters and actions. After seeing what some other people have done with filters, I’m pretty much convinced that if you know the right filter to add, you can probably implement almost anything without making core changes. So, I wanted to try to build a solution that allows you to use Dr. Mike’s cool workaround without making any changes to the wordpress core code. This plugin does that.

Actually, it’s really simply, it just adds a “post_link” filter that returns the $post->guid as the permalink. This is essentially the same thing that was being done by the change to “link-template.php” that Dr. Mike’s instructions say to do for step 6.

Download: You can get a copy of the plugin here.

Install: Standard stuff, rename the file to .php, place it in your plugins directory (in this case on your wordpress install, not on your wordpressmu install) and activate it. After you have it installed you can revert your changes to “link-template.php” back to the original.

Usage: nothing special to do.

March 11, 2007

WPMU- Top Posts Plugin

Filed under: development, Wordpress plugins, WordpressMU — zappoman @ 7:46 am

I’ve hacked together a prototype of a Top Posts plugin for WordPressMU.

The concept is to create a global table that stores the blog_id, post_id, and time for each hit to a post/page, and then allows you to get list of the posts with the most hits. This is an early early version.

You can download it here.

Installation:

Put this php file in your ‘wp-content/mu-plugins’ directory. Sit back and enjoy.

Usage:

The simple version would be to call:

<?php zap_top_posts_html(); ?>

This will return a <ul>…</ul> block of html.

But you can also use this much like you would use get_posts() in any template. For example, the following should also work…

<ul>
 <?php
 $myposts = zap_get_top_posts();
 foreach($myposts as $post) :
 ?>
    <li><a href="<?php echo $post->guid; ?>">
	<?php the_title(); ?></a>
	[<?php zap_the_post_hits(); ?>]</li>
 <?php endforeach; ?>
</ul>

Anyway, this is just a prototype. I haven’t really done that much testing. I have no idea how well it will perform in general. I know there are a couple bugs in there. As I fine tune this, I will post additional updates.

Known issue: You can’t use the get_permalink() and the_permalink() tags becuase they depend on other global variables that are not properly set up with these functions. If you want the link to the post use $post->guid.

Blog at WordPress.com.