Posts tagged ‘WordPress’

Seamless WordPress bbPress Integration

If you’ve ever installed bbPress you know that it supports several different levels of integration with an existing WordPress blog. By default you can integrate cookies, users, and even have access to WordPress functions. After all of this, however, the user will still experience two independent applications. Most likely the themes you are using were not made with each other in mind. This doesn’t have to be the case, and if you’re willing to get your hands dirty you can get your bbPress installation to look and feel as if it is entirely a part of WordPress. Here is an example of what this looks like: Example.

To begin, you will need to install (or modify) bbPress with full WordPress integration. This means cookie, database, and functional integration (add require_once(‘path/to/wp-blog-header.php’); to your bb-config.php for functional integration). I did this with WordPress 2.7.1 and bbPress 1.0 alpha, however, if you prefer to use the stable version of bbPress, you can find information on how to do this Here.

Once everything is installed its time to get your hands dirty. To go further we’re going to have to make a few changes to the code. Locate your theme directory. I used the default Kakumei theme. Keep in mind that a large portion of your bbPress theme is going to be stripped out (header, footer, sidebar) so don’t spend to much time selecting a theme. After you locate the directory of your current theme, you’ll need to do a search and replace through every .php file in your theme. There are several files so I suggest you use a program to do this for you; Notepad++ allows you to search and replace across multiple files.

You’ll need to do two searches:

Find:

bb_get_header();

Replace with:

global $is_bb; $is_bb = true; get_header();

get_header(); will cause bbPress to use WordPress’ header as opposed to its own. I added the additional code global $is_bb; $is_bb = true; you’ll see why later. You’ll need to do the same thing for the footer as well.

Find:

bb_get_footer();

Replace with:

get_footer();

Now that that’s done, upload the files and take a look at your forum. You should see the body of your forum embedded inside your wordpress theme. You should also notice that your forum looks pretty terrible. Don’t worry we’ll fix this in the next step.

What we need to do next is tell your wordpress theme to use your bbPress stylesheet if we are viewing the forum. This is where that additional code I added comes in. In your WordPress theme’s header file add the following lines before the first stylesheet is linked (ie before the first <link rel=”stylesheet”…):

<?php global $is_bb; if($is_bb) : ?>
	<link rel="stylesheet" href="[path to bbPress theme stylesheet]" type="text/css" media="screen" />
	//add additional stylesheets if needed
<?php endif; ?>

Make sure to replace [path to bbPress theme stylesheet] with the path to your current bbPress theme’s stylesheet.

If you look at your forum now, you’ll probably see a terrible mess. This is because your WordPress style sheets and your bbPress style sheets conflict. If you didn’t use the default theme you’re on your own for altering your bbPress stylesheet. Make sure you remove any elements that are directly conflicting with those in your WordPress theme (ie header, sidebar, footer elements). You’ll also want to look out for any position, and float attributes. You may also need to remove the width attribute for your forum body.

If you did use the default theme or the blue version of the default theme, you can use the stylesheets that I’ve already altered. I don’t promise that they are bug free, but they’re working well for me so far.

Kakumei
Kakumei Blue

Make sure to rename them to style.css.

Now that you’ve altered your stylesheet, everything should look good. You arn’t done yet, however. Most likely all of your bbPress navigation (ie login, admin panel, logout) buttons are gone. If you correctly integrated WordPress cookies login and logout shouldn’t be a problem. To replace any links that were lost, code them directly into your WordPress theme, using the $is_bb variable to only display them on the forum.

Good Luck!

Plugin Compatibility

For various reasons, there are some people out that who have chosen to hang onto older versions of WordPress. Personally I do not recommend this behavior, but as a plugin developer, you might not want to exclude these people from using your plugin. Does this mean you should refrain from using features that were implemented in later versions for the benefit of those who have not upgraded? Absolutely not. One thing you can do, however, is to emulate or implement the newer features your plugin relies on for older versions.

This is actually very simple to do considering you can simply take the code directly from the latest version of WordPress. In order to do this properly, you should make use of PHP’s function_exists function. For example: the function admin_url was not part of WordPress until version 2.6. Normally, if you were to use this function, users with older version of WordPress would not be able to use it. You can, however, define it yourself:

if(!function_exists('admin_url'))
{
	function admin_url($path = '') {
	$url = site_url('wp-admin/', 'admin');

	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
		$url .= ltrim($path, '/');

	return $url;
	}
}

Notice that the function declaration is inside the if(!function_exists(‘admin_url’)) block. If you simply defined the function as you normally would users with WordPress 2.6+ would receive an error.

Another thing to notice is that the code for admin_url contains a call to a function site_url. This function also was not defined until WordPress 2.6 so you’ll have to do the same thing for this function. For some functions it will be the case that you will have to do this for many functions, and in some cases you won’t be able to do this at all due to more significant differences between older and newer versions.

Here is a file I’m using called compat.php that defines several functions and constants that do not exist in earlier versions of WordPress.

//These functions replicate Wordpress functionality
//Used in cases where a Wordpress function is not
//available (ie a version that does not have that function)
if(!function_exists('is_ssl'))
{
	function is_ssl() {
		return ( isset($_SERVER['HTTPS']) && 'on' == strtolower($_SERVER['HTTPS']) ) ? true : false;
	}
}

if(!function_exists('force_ssl_admin'))
{
	function force_ssl_admin($force = '') {
		static $forced;

		if ( '' != $force ) {
			$old_forced = $forced;
			$forced = $force;
			return $old_forced;
		}

		return $forced;
	}
}

if(!function_exists('force_ssl_login'))
{
	function force_ssl_login($force = '') {
		static $forced;

		if ( '' != $force ) {
			$old_forced = $forced;
			$forced = $force;
			return $old_forced;
		}

		return $forced;
	}
}

if(!function_exists('site_url'))
{
	function site_url($path = '', $scheme = null) {
	// should the list of allowed schemes be maintained elsewhere?
	$orig_scheme = $scheme;
	if ( !in_array($scheme, array('http', 'https')) ) {
		if ( ('login_post' == $scheme) && ( force_ssl_login() || force_ssl_admin() ) )
			$scheme = 'https';
		elseif ( ('login' == $scheme) && ( force_ssl_admin() ) )
			$scheme = 'https';
		elseif ( ('admin' == $scheme) && force_ssl_admin() )
			$scheme = 'https';
		else
			$scheme = ( is_ssl() ? 'https' : 'http' );
	}

	$url = str_replace( 'http://', "{$scheme}://", get_option('siteurl') );

	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
		$url .= '/' . ltrim($path, '/');

	return apply_filters('site_url', $url, $path, $orig_scheme);
	}
}

if(!function_exists('admin_url'))
{
	function admin_url($path = '') {
	$url = site_url('wp-admin/', 'admin');

	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
		$url .= ltrim($path, '/');

	return $url;
	}
}

if ( !defined('WP_CONTENT_URL') )
	define( 'WP_CONTENT_URL', get_option('siteurl') . '/wp-content'); // full url - WP_CONTENT_DIR is defined further up

if ( !defined('WP_PLUGIN_URL') )
	define( 'WP_PLUGIN_URL', WP_CONTENT_URL . '/plugins' );

if(!function_exists('plugins_url'))
{
	function plugins_url($path = '')
	{
	$scheme = ( is_ssl() ? 'https' : 'http' );
	$url = WP_PLUGIN_URL;
	if ( 0 === strpos($url, 'http') ) {
		if ( is_ssl() )
			$url = str_replace( 'http://', "{$scheme}://", $url );
	}

	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
		$url .= '/' . ltrim($path, '/');

	return $url;
	}
}

WordPress Plugins: Using Subversion

This article is meant to supplement WordPress’ Using Subversion Guide. Whenever I mention the guide I am referring to this.

So you’ve written a WordPress plugin and its now time to upload it to the WordPress plugin repository. Your first step will be requesting that your plugin be hosted on WordPress’ Plugin Directory. Sometime later your request will be accepted (provided it doesn’t drop all of the tables in the database or something like that) and you’ll be given access to the Subversion Repository.

If this is your first time making a WordPress plugin you might have no clue what subversion is, much less how to use it. WordPress provides some good Documentation on this subject, but I think there are a few things they left out that could be useful to someone using doing this for the first time.

Reading through WordPress’ Using Subversion guide will probably give you a pretty good idea of what subversion is, but by the time they get to actually using subversion you might be a little lost. I’ll pick up at the point I think it begins to get a little fuzzy:

Task 1: Starting from scratch with your brand new plugin repository

This section begins with a short overview of what you will be doing:

  1. Check out the blank repository.
  2. Add your files to the trunk/ directory of your local copy of the repository.
  3. Check in those files back to the central repository.

Then they toss a blob of text at you.

# Create a local directory on your machine to house
# a copy of the repository.

$ mkdir my-local-dir

# Check out the repository

$ svn co http://svn.wp-plugins.org/your-plugin-name my-local-dir
> A	my-local-dir/trunk
> A	my-local-dir/branches
> A	my-local-dir/tags
> Checked out revision 11325.

# As you can see, subversion has added ( "A" for "add" )
# all of the directories from the central repository to
# your local copy.

# Copy the plugin files to the local copy.
# Put everything in the trunk/ directory for now.

$ cd my-local-dir/
my-local-dir/$ cp ~/my-plugin.php trunk/my-plugin.php
my-local-dir/$ cp ~/readme.txt trunk/readme.txt

# Let subversion know you want to add those new files
# back into the central repository.

my-local-dir/$ svn add trunk/*
> A	trunk/my-plugin.php
> A	trunk/readme.txt

# Now check in the changes back to the central repository.
# Give a message to the check in.

my-local-dir/$ svn ci -m 'Adding first version of my plugin'
> Adding	trunk/my-plugin.php
> Adding	trunk/readme.txt
> Transmitting file data .
> Committed revision 11326.

# All done!

There are a few things you should know about the commands above. To begin, these commands should be entered on a unix shell. If you are familiar with unix you already know that text following the # symbol are comments and the text following the > symbol are the shell’s response to the commands. The commands themselves are not preceded by any symbol.

Another thing you should know is that the writers assume that you already have subversion (svn) installed. If you don’t like the idea of using a command line to access and modify the repository, there are a lot of GUI programs out there. You can find a listing of third party clients on the Subversion Website From this point on, however, I (and the writers of the guide I am referring to) will assume you have access to a unix command line with subversion installed.

If you are a windows user and don’t have access to a unix shell, I suggest using cygwin. SVN is part of the cygwin package, but you must explicitly specify that it be downloaded and installed. Read the cygwin documentation for more information. To test whether or not SVN is installed, type svn help in the shell.

Now that you have access to UNIX with SVN installed you should have no trouble running the commands in the guide.

Task 2: Editing a file that is already in the repository

Once you’ve uploaded your initial version, you will almost certainly need to make changes to those files sometime in the future. The guide is pretty clear on how to do this, so I will just provide a brief summary of the commands you will use for this.

svn stat shows you a list of files that differ from those in the repository.

svn ci -m "my message" updates the files in the repository with your local copies. It does not automatically add new files or remove old files. If you have added a new file that did not exist before you will have to use the svn add command to manually add this file. Likewise you will have to remove a file manually with the svn remove command. Documentation on any command can be obtained by using the svn help [command] command, where [command] is replaced by whatever command (ie add, remove, stat) you need documentation on.

Notice that the first command issued before updating any files is cd my-local-dir. It is very important that you are in you plugin directory when using any of these commands.

Task 3: “Tagging” a new version

Tagging refers to assigning a version to your plugin. Whenever you create a new version of your plugin you will need to tag that version. As the guide mentions, you do this by using the svn cp. It is important that you use the svn cp and not the normal cp command to do this. svn cp just doesn’t copy the files, it also adds the files as you would using the add command.

It is important to note that the command svn cp trunk tags/0.1 assumes that the folder 0.1 does not exist in the tags folder. You won’t get the desired result if it already exists.

As the guide mentions, it is important that the readme.txt file in your trunk folder is updated with the proper stable tag BEFORE copying the files.

Some Important Notes

Do not add, remove, move, or copy files with the normal commands (or through a GUI). To do these things you must use the svn [command] (ie svn add, svn move).

Stick to one application for managing your repository. It is not a good idea to use one program to add and remove files and then another to attempt to update the repository.

You can use whatever editor you want to modify your files. The example in the guide is nano trunk/my-plugin.php, but you don’t have to do everything from command line. Personally I use notepad++ to make changes to my files, just refrain from doing anything other than editing from your GUI or third party app.

Wordpress XHTML Validation

Almost immediately after I started my blog I began having difficulties ensuring that my XHTML would validate. Most of the time I could fix it by modifying the code in a plugin that carelessly preventing my XHTML from validating. Almost always it was something trivial (ie using single quotes instead of double quotes or using CAPS in attributes), however one problem I had persisted for quite a while.

These were the errors I was getting:

  • end tag for element “div” which is not open
  • XML Parsing Error: Opening and ending tag mismatch: body
  • XML Parsing Error: Opening and ending tag mismatch: html

After some effort I realized that this error did not appear on the main page or any of the pages. It only appeared when viewing individual posts. After a while I determined that the cause of this was an extra div closing tag. I also realized that the error only occurred when comments were open, which pointed to comments.php as the source of this problem.

After looking through the code my best guess was that these lines were the source of the error:

<?php endif; // If registration required and not logged in ?>
</div>
<?php endif; // if you delete this the sky will fall on your head ?>

Removing the div from the code above seemed to fix the problem in all but one case. Apparently if a page (not a post) has comments enabled, the extra closing tag was needed and not only did validation fail, but it caused the side bar to fall below page. Making the following change seemed to fix all of the errors (as far as I’m aware):

<?php endif; // If registration required and not logged in ?>
<?php if(is_page()) { echo '</div>'; } ?>
<?php endif; // if you delete this the sky will fall on your head ?>

Keeping up with XHTML validation can be tedious, especially when the people who wrote the plugins you are using might not care about validation. Being able to validate your entire site rather than just a page at one time might ease your suffering and it just so happens that such a validator exists: http://htmlhelp.com/tools/validator/

WordPress Scheduling

Should I ever become terminally ill, I plan to make excessive use of the WordPress post scheduling feature so I appear to be blogging from beyond the grave.

By the way…
I wrote this on the 8th, but it wasn’t published until the 13th. I might be dead already. :o

Configuring WP for Code Examples and Execution

Since launching this blog a few days ago I have yet to post and code examples or tutorials. In preperation for this, and having decided that plain text code examples just wouldn’t cut it, I went searching for a plugin to format and highlight my code. Not too long afterward I came across the SyntaxHighlighter plugin. After a simple installation I was able to do things like this:

<?php
//this is php code
echo 'hello world';
?>

How is the feat accomplished you say?The plugin allows you to post your code by surrounding it with the tags [/sourcecode], where lang is equal to one of these supported languages:
<ul>
<li>C++ — <code>cpp</code>, <code>c</code>, <code>c++</code></li>
<li>C# — <code>c#</code>, <code>c-sharp</code>, <code>csharp</code></li>
<li>CSS — <code>css</code></li>
<li>Delphi — <code>delphi</code>, <code>pascal</code></li>
<li>Java — <code>java</code></li>
<li>JavaScript — <code>js</code>, <code>jscript</code>, <code>javascript</code></li>
<li>PHP — <code>php</code></li>
<li>Python — <code>py</code>, <code>python</code></li>
<li>Ruby — <code>rb</code>, <code>ruby</code>, <code>rails</code>, <code>ror</code></li>
<li>SQL — <code>sql</code></li>
<li>VB — <code>vb</code>, <code>vb.net</code></li>
<li>XML/HTML — <code>xml</code>, <code>html</code>, <code>xhtml</code>, <code>xslt</code></li>
</ul>
The words following the — are valid arguments for language corresponding to that particular language, meaning that for python code you can set language equal to ‘py’ or ‘python’. Pretty cool right?

But Wait!

There was one catch in my case when it came to getting this plugin up and running. I had previously installed a plugin called <a href="http://bluesome.net/post/2005/08/18/50/" target="_blank">Exec-PHP</a> that allowed me to insert php code into posts that would be executed rather than displayed (this only works for me and it only works in posts so don’t get any ideas). So now all of my code examples would simply be executed, resulting in whatever the output of that example would be (worse potentially, the execution of that code everytime someone loads that page).

I came up with two possible solutions to this problem. The first being just to not use php tags in any of the code I post (NEVER!!!). The second being that I throw away about an hour of my life, dive into the exec-php plugin code, and set things right. Clearly I chose the second of these options.

So far I’ve only found 1 bug with this modification. I can’t display the code I used to impliment it. Any php code containing the strings [sourcecode language='p h p'] or will most likely break the plugin. Here is the link to download the plugin with the modification, feel free to comment back with error reports or improvements:

Download