Ferodynamics Network

popular: profile privacy, mobile privacy

September 22, 2008

In my last post I wrote about the concept of desiging dual use themes, that is themes that will work across multiple platforms. I don’t mean themes that are ported to another platform, but one single theme that will work on both. That is what I am doing for my re-theme of this site, and in this post I will explain how I have gone about it.

There are enough similarities between the WordPress theme system and the Habari, rawPHP theme engine that it is fairly easy to switch between the two. Despite this there are also some very significant differences.

WordPress uses PHP functions as template tags. These functions use the GLOBAL keyword to access the data in the main classes. Habari outputs the information straight from the classes.

[php]
//WordPress

//Habari
title_out; ?>

The different approaches also mean the loops work differently. The WordPress loop uses a function to change the post class to the next post. Habari uses a foreach loop because the classes can be accessed directly:

[php]
//WordPress

//post content

//Habari

//post content

The important point about these differences is that it creates several possible methods of making the theme work.

Option 1 – IF

It is easy to determine whether the theme is running on WordPress or Habari. There are a lot of constants and classes that are unique. I chose to test the $theme object to make sure it extends the Theme class.

[php]
if ( isset( $theme ) && is_subclass_of( $theme , 'theme' ) ) {
define('WORDPRESS',0);
define('HABARI',1);
} else {
define('WORDPRESS',1);
define('HABARI',0);
}

I’ve also set constants for both WordPress and Habari so the code can be a bit clearer as to what platform is being tested against.

The problem with using IF statements to test these constants is it means adding a great deal of complexity to the code, and duplicating large chuncks of HTML. Not Ideal.

Option 2 – Emulate

Emulating either of the platforms seems like a good idea, but doing it within the theme itself is likely to bring difficulties. The theme engines load the content in different ways, so scope things in different ways, and this is likely to add a lot of extra work.

Option 3 – The third way

Option 3 is to let go of the way themes work on both platforms and create a new set of controls to act as a translator between the two. This is the method I decided to use.

The method

First things first, I needed a way to run code independently for each platform. Thankfully WordPress themes look for and include functions.php automatically, and Habari themes look for theme.php. Each platform ignores the file of the other so adding platform independent code is no problem.

Habari looks for an instantiates the class in this file as the variable $theme, so it seemed logical to group all the functions inside this class, and do the same for WordPress. Using this method, I could then convert every theme function call to a public method of $theme. I just need to make sure the methods are named the same in both classes.

To make things a little easier I also used a hook in the WordPress version to get the $post and $posts variables.

For example, The WordPress title tag method now looks like this:

[php]
public function post_title(){
return apply_filters( 'the_title', $this->post->post_title );
}

The class defined in theme.php that Habari will load looks like this:

[php]
public function post_title(){
return $this->post->title_out;
}

In both cases I am simply returning a value, so the theme uses:

[php]
echo $theme->post_title();

Note that in the WordPress version I added a hook to collect the global $post and $posts object and bring them into the class so that there is no need to use global in each function.

The loop

Obviously this is all fine until we come to multiple posts. The WordPress loop and Habari loop operate in very different ways to each other. Habari uses a simple foreach loop on the $posts object to return each $post object, and WordPress uses a function in a while loop to test if there is a next post. To make them both work together I needed to use the same loop for each. It seemed most logical to use something closer to the WordPress model:

[php]
while ( $theme->next_post() ) {
//post data here
}

The code in both classes is exactly the same:

[php]
public function next_post(){
$current = current($this->posts);
if ( $current == false ){
reset($this->posts);
return false;
} else {
$this->post = $current;
next($this->posts);
return true;
}
}

Template Hierarchy

To deal with the differences in template hierarchy I simple decided to go with the Habari version. Rather than mess about with the template system and rewrite it I have simply added an include statement into the WordPress files. index.php includes home.php; although WordPress will use home anyway but won’t work without an index.php file. archive.php includes multiple.php and so on.

Complexity

Of course the whole theme is more complicated than what you see here, and I still have some way to go. I have written a menu builder, a lot more replacement theme tags, and a stylesheet that outputs different colours and graphics links depending on platform, but hopefully this peek should give you the gist of it.

If you have any questions let me know and I will add to this post as needed. For the technically minded I have attached the header.php, multiple.php, theme.php and functions.php files to download: Sample code for cross compatible themes

Post Image The Easy Peasy Way
26 comments
page 1065
Quick N Dirty Admin Login Screen
no comment
page 128
Wordpress Chat
one comment
page 1308
Html 5 Gallery
6 comments
page 1305
Html 5 Gallery
6 comments
page 1305
Silence Is Golden
3 comments
page 213
Questions About Habari For Wordpress Users
6 comments
page 424
Theming Habari Vs Wordpress
13 comments
page 440
My Experience Of Flexx
4 comments
page 1026
Plugin Update Fun With Photo Data 2
one comment
page 815
Post Image The Easy Peasy Way
26 comments
page 1065
Categories Vs Tags Either Neither Or Both
12 comments
page 7
Gaining Benefits From Plugins
8 comments
page 1167
Fun With Theme Widgets
24 comments
page 867
Beware Wp Cache
8 comments
page 1310
Six Million Ways To Die Choose One
14 comments
page 1128
Post Image The Easy Peasy Way
26 comments
page 1065
Post Image The Easy Peasy Way
26 comments
page 1065
Wordpress Chat
one comment
page 1308
Post Image The Easy Peasy Way
26 comments
page 1065
Wordpress Chat
one comment
page 1308
Beware Wp Cache
8 comments
page 1310
Wp Polls Reviewed
one comment
page 58
Fun With Photo Data
12 comments
page 330
Fun With Sidebar Tabs Styling
2 comments
page 336
Html 5 Gallery
6 comments
page 1305
Using Your Own Url Shortener
4 comments
page 1190
Html 5 Gallery
6 comments
page 1305
My Experience Of Flexx
4 comments
page 1026
Fun With Sidebar Tabs
193 comments
page 57
Html 5 Gallery
6 comments
page 1305
  updated 1 seconds ago
Tuesday, 11pm
Andrew Rickmann

I understand why you would say that Ptah, but where is the fun in just doing it twice?

I just really like the idea of running them both of exactly the same files.

Tuesday, 7pm
Ptah Dunbar

Choice number three seemed most logical compared to the others but why not simply build two of the same themes for both platforms?

I’ve been playing with habari’s theme system too and found that the differnces between habari and wordpress differ enough to separate the two and build each theme accordingly. K2 did the same. The benefits of having one universal theme work with all sounds great, but sports too many cons IMO.