Modify an SMF theme for Joomla and Mambo

Introduction to using an SMF theme with Joomla or Mambo

Welcome to my tutorial on modifying a theme for SMF to work with Joomla or Mambo. (Themes are the SMF equivilent of a Joomla/Mambo template, though really it is a collection of templates.) If you would like to see this tutorial in Portuguese, buf posted a translation here. There are several ways to go about doing this, but I think this method is the best.  It will allow your theme to be used when accessed wrapped in Joomla or Mambo, as well as still be functional when accessed unwrapped or stand alone.  It will remove the usual conflicting CSS when wrapped, as well as excess headers or sidebars.

The key to achieving this is a conditional statement that Kindred on the forums showed me:
Code:
if (empty($_REQUEST['option'])){
}
What this does is check to see if a the global variable $_REQUEST['option'] has been set, which is something Mambo or Joomla will do.  This might work for some other CMSs, too, that use this method, though I haven't tested any others.

Occasionally, you might want to do the opposite, and have something show up only when you have the forum wrapped - for instance, in one theme I was working on, I needed it to have a "colspan=2" only when wrapped, because of some things I removed. In that situation, you would use this code:
Code:
if (!empty($_REQUEST['option'])){
}

Basically, the same thing, but saying if it is NOT empty.

Preliminary information

To demonstrate this, I am going to use the SMF default theme for SMF 1.1 RC1, (in SMF 1.1 RC2, this is now known as the Babylon theme, but the tutorial should still apply. If you just want a modified version of the RC2 default theme, check the downloads section.)  While doing this, I believe the best practice to be to extract the theme locally to work on, and test your modifications as you go.  If you would like to keep your original theme separate (which I highly recommend), you will want to re-archive your new theme with a different filename, and edit the theme_info.xml file and edit the <name></name> setting.  That way it will install in to a different directory, and show up with a different name than the original.
Side Note
There are really only two files you should need to edit, index.template.php and style.css.  However, we are copying the entire theme so that you are able to release it stand-alone to those who may not have the original.  If you really want to do this with the default theme, you can use the "Create a copy of Default named:" option in the theme installer, and just work with the files that it makes.

Preparing to edit

First, extract or copy the original version of the theme to a local directory where you can do the editing.  You probably want this directory name to be something different from the name of the file the theme is distributed in - for instance, if the original theme is distributed in foo.zip, don't extract it to a directory named foo, instead, use a directory named foo-joomla.  This is to help differentiate it from the original, which by default will be installed on your server in a directory that is the same name as the file.  For our demo we will be copying the entire "/Themes/default/" directory in to a directory named "/Themes/default-joomla/".

Removing the excess tags

The first editing we do will be to remove the extra <html> <head> and <body> tags, as well as the excess header information.  This will allow us to have a valid W3C XHTML web site.

Open up index.template.php in your favorite text editor (I use Source Edit).  Look for:
function template_main_above()
In the default theme it is on line 51.  This is the function that displays the top part of the forum.

Look for any decalarations underneath it.  In the default theme we have one "global" line on line 53.  After that, it starts to display the forum page headers, so that's the part we will want to cut out.  Before line 55, add the following code:
Side Note
To keep your code clean, anything you are putting between these If statements (lines 57-137 in the demo) should be indented, but that's by no means critical.  I won't mention this every time - do it if you like from here on out.

Code:
    // check to see if the forum is running wrapped in mambo or standalone...
    if (empty($_REQUEST['option'])){
Scroll down until you find the line that says (it should be line 137 after adding the two lines above):
Code:
<body>';
Before the next line, add:
Code:
} // end of check if forum is wrapped
so now it looks like:
Code:
<body>';
} // end of check if forum is wrapped
Please note, in some themes you may not have the '; at the end of the body line.  This is necessary to close the echo command.  If this is the case, you will need to add those in, and then add a line that says:
Code:
echo '
to the next line after your "} // end of check if forum is wrapped" line

There are some critical items in the headers you need, so, instead of the normal adjustment to the Joomla or Mambo template that we ask people to post (if you are using one of Orstio's bridges, version 1.1.14 or later, this isn't needed any more, so ignore this!), we'll be asking them to post this instead (just before the </head> statement in the Joomla or Mambo template):
Code:
<?php
global $sc, $context, $settings;

if (!
defined('SMF')){
  require (
"administrator/components/com_smf/config.smf.php");
  require (
$smf_path."/SSI.php");
}

$sc = &$context['session_id'];
$_SESSION['USER_AGENT'] = $_SERVER['HTTP_USER_AGENT'];

mysql_select_db($mosConfig_db);

echo '
<script language="JavaScript" type="text/javascript" src="'
, $settings['default_theme_url'], '/script.js?beta4"></script>
<script language="JavaScript" type="text/javascript"><!-- // --><![CDATA[
var smf_theme_url = "'
, $settings['theme_url'], '";
var smf_images_url = "'
, $settings['images_url'], '";
var smf_scripturl = "'
, $scripturl, '";
var smf_session_id = "'
, $context['session_id'], '";
// ]]></script>'
;

echo
'
<link rel="stylesheet" type="text/css" href="'
, $settings['theme_url'], '/style.css?rc1" />
<link rel="stylesheet" type="text/css" href="'
, $settings['default_theme_url'], '/print.css?beta4" media="print" />
<link rel="help" href="'
, $scripturl, '?action=help" target="_blank" />
<link rel="search" href="'
. $scripturl . '?action=search" />
<link rel="contents" href="'
, $scripturl, '" />';
/* Internet Explorer 4/5 and Opera 6 just don't do font sizes properly. (they are big...)
Thus, in Internet Explorer 4, 5, and Opera 6 this will show fonts one size smaller than usual.
Note that this is affected by whether IE 6 is in standards compliance mode.. if not, it will also be big.
Standards compliance mode happens when you use xhtml... */
if ($context['browser']['needs_size_fix'])
echo '
<link rel="stylesheet" type="text/css" href="'
, $settings['default_theme_url'], '/fonts-compat.css" />';

// Show all the relative links, such as help, search, contents, and the like.
echo '
<link rel="help" href="'
, $scripturl, '?action=help" target="_blank" />
<link rel="search" href="'
. $scripturl . '?action=search" />
<link rel="contents" href="'
, $scripturl, '" />';

// If RSS feeds are enabled, advertise the presence of one.
if (!empty($modSettings['xmlnews_enable']))
echo '
<link rel="alternate" type="application/rss+xml" title="'
, $context['forum_name'], ' - RSS" href="', $scripturl, '?type=rss;action=.xml" />';

// If we're viewing a topic, these should be the previous and next topics, respectively.
if (!empty($context['current_topic']))
echo '
<link rel="prev" href="'
, $scripturl, '?topic=', $context['current_topic'], '.0;prev_next=prev" />
<link rel="next" href="'
, $scripturl, '?topic=', $context['current_topic'], '.0;prev_next=next" />';

// If we're in a board, or a topic for that matter, the index will be the board's index.
if (!empty($context['current_board']))
echo '
<link rel="index" href="'
. $scripturl . '?board=' . $context['current_board'] . '.0" />';
if ($context['user']['popup_messages'] && !empty($options['popup_messages']) && (!isset($_REQUEST['action']) || $_REQUEST['action'] != 'pm'))
{
echo '
<script language="JavaScript" type="text/javascript"><!-- // --><![CDATA[
if (confirm("'
. $txt['show_personal_messages'] . '"))
window.open("'
. $scripturl . '?action=pm");
// ]]></script>'
;
}
?>


OK, we've hit a good spot to test this, so let's take out the extra </body> and </html> tags that we removed the opening tags for.  They are down at line 398 - before that line, enter:
Code:
    // check to see if the forum is running wrapped in mambo or standalone...
    if (empty($_REQUEST['option'])){
Then, after line 402, enter:
Code:
    } // end of check if forum is wrapped
So, now this part looks like this:
Code:
    // check to see if the forum is running wrapped in mambo or standalone...
    if (empty($_REQUEST['option'])){
    echo '
    </body>
    </html>';
    } // end of check if forum is wrapped

With that part done, we should have a useable theme to test.  Save this and upload it to your server.  If you click the W3C XHTML 1.0 check button at the bottom of your forum, you shouldn't have any errors about extra head, body, or html tags, or about anything that should be in the header that is in the body.

Removing extra theme information

Next, we want to remove the logo, login box, and key stats box, as these would be more appropriate as part of Joomla or Mambo.

Find the part that reads (we're not doing this any earlier, because we want to keep some of the stuff in here, namely the search box and main menu):
Code:
   // This part is the logo and forum name.  You should be able to change this to whatever you want...

If you're following along, it should be line 150.  Before that, insert our handy dandy code:
Code:
    // check to see if the forum is running wrapped in mambo or standalone...
    if (empty($_REQUEST['option'])){

OK, we're cutting out code down through the logo and forum name, and the user info boxes.  So, after line 249, we will put in the cloing for our If statement:
Code:
    } // end of check if forum is wrapped
However, we also need to change line 249 to close it's echo statement:
Code:
</div>';
And then, start that echo statement up again on the next line - change line 251 to read (currently a blank line):
Code:
echo '

Feel free to save it, upload it, and test it now.  The logo and user info box should be gone.

Next, we'll remove the random news item and key stats boxes.  Before line 269, add in our code:
Code:
    // check to see if the forum is running wrapped in mambo or standalone...
    if (empty($_REQUEST['option'])){

This is in the middle of an echo statement once again, so we'll need to add in to change line 268 to close out the echo:
Code:
</td>';

And line 271 we'll need to start an echo statement again:
Code:
echo ' <td style="width: 262px; ', !$context['right_to_left'] ? 'padding-left' : 'padding-right', ': 6px;" valign="top">';

OK, we are removing the code down through the key stats box's code, so after line 291 we can add in our closing code:
Code:
    } // end of check if forum is wrapped

Last, we'll get rid of the header upshrink button.  That's this piece of code, which should be on line 299:
Code:
<a href="javascript:void(0);" onclick="shrinkHeader(!current_header); return false;"><img id="upshrink" src="', $settings['images_url'], '/', empty($options['collapse_header']) ? 'upshrink.gif' : 'upshrink2.gif', '" alt="*" title="', $txt['upshrink_description'], '" style="margin: 2px 2ex 2px 0;" border="0" /></a>';

Before it, we put:
Code:
        // check to see if the forum is running wrapped in mambo or standalone...
        if (empty($_REQUEST['option'])){

This one is a little tricker.  Again, it's in an echo statement, so we need to go back and modify line 297 to close the echo statement:
Code:
</table>';

This time, the end of the echo statement is inside of the part we edited, so we will need to change that line (now line 301) to start the echo statement:
Code:
echo '<a href="javascript:void(0);" onclick="shrinkHeader(!current_header); return false;"><img id="upshrink" src="', $settings['images_url'], '/', empty($options['collapse_header']) ? 'upshrink.gif' : 'upshrink2.gif', '" alt="*" title="', $txt['upshrink_description'], '" style="margin: 2px 2ex 2px 0;" border="0" /></a>';


And after that line, we put:
Code:
        } // end of check if forum is wrapped

There we go!  Save, upload, and test.  Try it wrapped in Joomla or Mambo, then try it stand alone.  It should work both ways.

Removing conflicting CSS

Last, but not least, we'll want to remove the CSS from your SMF theme that might conflict with Joomla or Mambo's template.  What we are going to do here, is, remove conflicting CSS from the theme's CSS file, and add it to a new file we will call "style-unwrapped.css".  This will only load when the forum is accessed unwrapped.

Open up your theme's style.css file in your text editor.  The first thing we'll cut out is lines 1-12, which contain the CSS for links, a:link, a:visited, and a:hover:
Code:
/* Normal, standard links. */
a:link
{
color: #000000;
text-decoration: underline;
}
a:visited, a:hover
{
color: #323232;
text-decoration: underline;
}


Paste those in to a new file called "style-unwrapped.css".

Next, we'll cut out the body tags, which should now be on lines 20-35:
Code:
/* By default (td, body..) use Tahoma in black. */
body, td, th
{
color: #000000;
font-size: small;
font-family: tahoma, sans-serif;
}

/* The main body of the entire forum. */
body
{
background-color: white;
margin: 0px;
padding: 0px;
}


Again, paste those in to "style-unwrapped.css".

That should be it for most themes, but you might want to go through and compare it to your Mambo or Joomla template to see if any of the other CSS calls conflict.

One more thing to do.  Going back to our index.template.php file, we need to tell it to load style-unwrapped.css. The best place to do this is right after the line that it loads style.css, which is line 74.  Just after line 74, paste in this line:
Code:
    <link rel="stylesheet" type="text/css" href="', $settings['theme_url'], '/style-unwrapped.css?rc2" />

Now, upload all of these to your theme's directory, and test it out!

Conclusion

Hopefully, at this point, you have a fully functioning theme that does not conflict at all with Joomla or Mambo when wrapped, and looks exactly like the original when unwrapped! Let's review the steps taken.

First, we remove anything from the theme we don't want to show up when wrapped using this code:
Code:
if (empty($_REQUEST['option'])){
}

If we want something to show up only when it is wrapped, we would use the following code:
Code:
if (!empty($_REQUEST['option'])){
}

First we use that code to remove excess <html> and <body> tage, and the <head> section. Then we remove unwanted theme elements (headers, logos, etc.) Then we remove existing CSS, and put it in a separate file that is loaded only when accessed unwrapped.

If you would like copies of the files I edited while working on this tutorial, you can download the index.template.php, style.css, and style-unwrapped.css files here.