Theme creation for phpWebSite 0.9.0
By Matthew McNaney

Version
1.0 First version.
1.1 Revision
    Fixed grammar. Added more explanations. Added default directory information.
1.2 Updated instructions
1.3 Added instructions for using theme.php includes.
1.4 Added information about XHTML compliance and debug theme

Warning: This document contains code samples which will not appear correctly in some browsers.
It is best read in a text program.

Notice: Anytime a module's title or name is mentioned, it is always refering to a module's
mod_title. Look in the modules table or in ModMaker to get that information.

Introduction
------------------------
We welcome your interest in developing themes for phpWebSite 0.9.0. The theme system was designed
with portability and customization in mind. We think you will find the creative process fairly easy.
This document will lead you through creating a theme. For instructions on how to develop a module
using the layout module, please refer to the devdoc.txt file.

I recommmend you open your Default theme while reading the explanations. 


The Files and Directories
--------------------------
All themes belong in the phpwebsite/themes directory. Put you theme files into a directory named
after your theme. For example, you will find the Default theme listed as Default/ in the
phpWebSite theme directory.  Reminder, make sure all of your theme files are in unix format.  There
are windows editors out there that will save files in unix format. (ie. PFE)

Besides any directories you create for your theme, you will need the following for better functionality.

boxstyles/          :  Contains the boxes for your theme. This one is required.
images/             :  Contains the images for modules. Not required.
templates/          :  Most modules present their layout in templates. Theme specific ones would be placed
                       here. Not required.

The files in your theme's directory should be:
theme.tpl     :  The layout of your theme
transfers.tpl :  The structure of your boxes
style.css     :  Your default style sheet

Another file you may see is:
browsers.txt  :  A listing of other browsers for alternate style sheets.


theme.tpl
------------------------------
This file is a layout diagram of sorts and it contains all of the tags required to display your theme.
Tags are displayed with curly braces around them, like so: {TAG_NAME}
The curly braces signify to the program what HTML tags (<>) signify to your browser: follow this command
instead of simply printing the contents. These are not markup tags however. Instead they receive the 
data generated by phpWebSite. 

First, let's consider your special tags. They are:
TITLE          : This tag should appear between the <title> tags. 
METATAGS       : Appears between the <head> tags. Lists admin generated meta tags.
JAVASCRIPT     : Again, appears in the <head> tags. Lists javascript functions called by a module.
STYLE          : Still in the <head> tags. Tells the system which style sheet to use.
DYN_JAVASCRIPT : Dynamic javascript can be placed in the theme by some modules.
DYN_STYLE      : Dynamic style code can be placed in the theme by some modules.

Since they are controlled by the phpWebSite, if you just place them in the theme, you can let the
admin worry about what goes inside them.

You might also see this tag:
THEME_DIRECTORY  :  The html directory of the theme. Very important for portability. Use
                    this instead of hard coding image addresses. It will echo the complete HTML address
		    of your site plus the current theme directory.
		    Usage: <img src="{THEME_DIRECTORY}images/poweredby.jpg" alt="Fallout" border="0" />

NOTE: Currently there is a limitation in PEAR that only allows a tag to be used once. So after
THEME_DIRECTORY is filled with data, all other tags will be ignored. We are working on changing this.
In most cases <img src="themes/myThemeName/images/sample.jpg" /> will work just fine.

Finally you will see one or more of these tags. Note: these are the defaults which ship with phpWebSite.

LEFT_COL_TOP, LEFT_COL_MID, LEFT_COL_BOTTOM
TOP, BODY, BOTTOM
RIGHT_COL_TOP, RIGHT_COL_MID, RIGHT_COL_BOTTOM

Each of these signifies a different theme variable. More on that in a moment.

You will also see HTML comments like the following:
<!-- BEGIN LEFTSIDE -->
<!-- END LEFTSIDE -->
These are IMPORTANT. Don't dismiss them as normal HTML comments as they work with the PEAR templating
system within phpWebSite. The contents between these comments will only appear if one of the theme
variables between them is filled. For example, the default theme contains something like the 
following:

<!-- BEGIN RIGHTSIDE -->
<td width="10%" valign="top" align="center">
    {RIGHT_COL_TOP}
    {RIGHT_COL_MID}
    {RIGHT_COL_BOTTOM}
</td>
<!-- END RIGHTSIDE -->

The comment tags tell phpWebSite that it should try to place content in the three tagged theme
variables. If NONE of the theme variables are filled in, then phpWebSite WILL NOT echo
the last <td> column. So, in this instance, if there wasn't anything to echo in any of the right side
variables, then a final right table column would not be created.

For furthur clarification, here is the format
<!-- BEGIN some_name -->
... contents {SOME_TAG} ... more contents
<!-- END some_name -->
If SOME_TAG does not contain data, contents and more contents WILL NOT be echoed.

It is important to capitalize the BEGIN and END components and to put spaces in between the
comment markers. Otherwise they will be seen by phpWebSite as normal HTML comments.
You can name the parameter anything you wish but they must match in spelling and capitalization.
Note that you can nest these as well

<!-- BEGIN username -->
<table>
<tr><td>Hello {USERNAME}</td></tr>
<!-- BEGIN logtime -->
<tr><td>You have logged on at: {LOGTIME}</td></tr>
<!-- END logtime -->
<!-- END username -->

In this example, the table will be created if the USERNAME is active. The second row of that table
will print if LOGTIME is active. But if USERNAME was not sent, the table would not be created, EVEN
if LOGTIME was present.

theme.tpl and Theme Variables
-------------------------------
PhpWebSite usually puts data in a box file located in the boxstyle directory.  This box, and others,
are then placed in your theme.tpl file using theme variables. The theme variables are the left_col_top,
right_col_top, etc. tags I referenced earlier. Each variable is considered to be a subsection, which you
will find out about in the transfers section below. When designing a theme, you do not need
to worry about what module will appear where. The admin handles that using the layout module.
You just need to make space for them in your theme.tpl file.

These theme variables can actually contain SEVERAL boxes so don't worry about running out
of space. In fact, it would be a good idea to use our defaults, but don't be scared to experiment.
You can also place them where you wish, but follow the recommendations of the transfers section.

Also, if nothing else, make SURE you have a BODY theme variable. phpWebSite defaults blocks to that
variable if it gets confused.

theme.tpl conclusion
---------------------
That is all for the theme.tpl file. Lets move on to the directories and files that assist it.

style.css
-----------------------
You are using Cascading Style Sheets for theming right? You should. In fact, phpWebSite will 
look kind of goofy without it. Take a look at the Default theme's style.css file. It is 
very basic and it contains some regulars that module developers can tap into. At least use the 
backgrounds (bg_light, bg_medium, bg_dark, black, white) and the text styles (errortext, smalltext, largetext).
The rest is up to you.

Whether you include your boxstyle's style components in this file is up to you
as well. If the box could work with other colors, try to keep the style within the stylesheet. However
if any change in a style would ruin the box, it is best to use inline style components when you
make the box.

You should try to make your theme work with all browsers. However, we are aware that is not always easy.
If you need to have separate style sheets for different browsers, create a browsers.txt file in your
theme's directory. It will look something like this:
<------- start of file ------->
Opera::opera.css
MSIE::explorer.css
Netscape6::netscape.css
<------- end of file --------->

(Ignore the start and end of file comments)

Each line defines a specific style sheet to use. phpWebSite will perform a regular expression check
against the the portion before the '::'. If a match is found, phpWebSite will use the style sheet
after the '::' instead of the default style.css. Notice that you must have the {STYLE} tag in your theme
for this to work.


transfers.tpl
-----------------------
The final required file is transfers.tpl. This file tells phpWebSite how you have structured your layout.
Lets look at Default's:

top:2:1
body:2:2
bottom:2:3
left_col_top:1:1
left_col_mid:1:2
left_col_bottom:1:3
right_col_top:3:1
right_col_mid:3:2
right_col_bottom:3:3

The variables are divided by colons. The first variable is the name of the theme variable.
The second number is the section name. The third is the sub section. This is the table
structure of Default

(This might not appear in some text readers. It is a 3x3 box in case you can't see it.)


 Section 1             Section 2                  Section 3
-----------------------------------------------------------------
|   left      |                                 |               |
|   col       |                                 |   right       |
|   top       |         top                     |   col         |
|             |                                 |   top         |
|   sub 1     |         sub 1                   |   sub 1       |
-----------------------------------------------------------------
|             |                                 |               |
|   left      |                                 |   right       |
|   col       |         body                    |   col         |
|   mid       |                                 |   mid         |
|             |                                 |               |
|   sub 2     |         sub 2                   |   sub 2       |
-----------------------------------------------------------------
|             |                                 |               |
|   left      |                                 |   right       |
|   col       |        bottom                   |   col         |
|   bottom    |                                 |   bottom      |
|             |                                 |               |
|   sub 3     |        sub 3                    |   sub 3       |
-----------------------------------------------------------------

When boxes are moved up and down (go into Move Box mode in layout to see what I am talking
about), they travel WITHIN their SECTION. They will bounce from one subsection to another
however. If a box travels left to right, they will JUMP to the next SECTION while remaining
in their current subsection (or the closest one to it).

You do not have to make your layout symmetrical like the above, but KEEP THE SECTIONS AND
SUBSECTIONS IN ORDER. If you do not, then the admin will try to move boxes and they
will wind up all over the place.

Remember, several boxes can be in just one theme variable. If the admin were so inclined,
they could put them all in left_col_top. It would look kind of strange, but whatever
floats your boat.

Boxstyles
----------------------

We are done with the theme's root files and are moving on to the different directories
mentioned earlier. Inside the boxstyle directory are small files called boxes. You should
ship your module with three basic files: default_box.tpl, default_pop.tpl, and default_empty.tpl.

default_box.tpl    :  Normal boxes. Used frequently and at least once by all modules.
default_pop.tpl    :  Boxes in boxes. If a developer wants to "pop" another box into their
                      display, they will call the popbox function and it will use this box.
                      Make this simple because, as I said, it usually appears in other boxes.
default_empty.tpl  :  {CONTENT} is usually all you will see in this file. Usually used for numerous
                      popboxes. Not always required as you could just comment out the title in a
                      normal box and use it.

It is important to have default_box and default_pop because if something goes wrong, these
boxes are displayed. If these cannot be found, then the 'Default' theme's default boxes
will be used (yes those ugly orange ones).

Boxes are just small HTML layouts with a few guidelines. When a module developer sends
information to the box, they expect two to three sections: a title, some content and maybe a footer
(which are rare). The box looks like a small version of your theme.tpl and has tags and comment
indicators just like it. Here is the default_box.tpl from the Default theme:

<!-- BEGIN TABLE -->
<table bgcolor="black" cellpadding="5" cellspacing="1" width="100%">
<!-- BEGIN TITLE -->
  <tr>
    <td class="bg_medium"><b>{TITLE}</b></td>
  </tr>
<!-- END TITLE -->
<!-- BEGIN CONTENT -->
  <tr>
    <td bgcolor="white">{CONTENT}</td>
  </tr>
<!-- END CONTENT -->
</table>
<!-- END TABLE -->

See where the {TITLE} and {CONTENT} are? If we wanted to add a footer, we would just create another
<tr><td>{FOOTER}</td></tr> and we would be done. In fact, why not put footer in? You can comment it
out and it won't appear unless someone actually uses it! Might as well make it versatile right?

Notice that this box uses bg_medium. If your box is elegant enough, it could be plugged into
a different theme and use its style sheet for colors. If you aren't hard coding colors, it's a
snap to mix boxes with other themes.

Boxes also have an address tag: BOX_ADDRESS. So if you are using graphics, use BOX_ADDRESS in
your code to make it portable. 
Example from the 'mainsite' theme:
<img src="{BOX_ADDRESS}mainsite_img/trans.gif" alt="" border="0" />

NOTE: As stated above, only one {BOX_ADDRESS} will be translated. Until the PEAR code is changed,
use themes/myTheme/boxstyles/myTheme_img/ or what ever directory you need to access.

If you use graphics with your box, place them in a directory that reflects your box's name. Don't use
just img/ because someone may copy a different box into your theme using the same directory name.
Then your creatively named border.gif file could get overwritten ;->

Defaults directory
---------------------
Sometimes within themes, there will be a directory named "defaults". This directory assists in
assigning boxes to different modules when the theme is switched. If the defaults directory is
not present or empty, then if you changed the theme, all the modules would use default_box.tpl
and default_pop.tpl.

You may not want that however. For certain modules, you may want a specific box. For example,
perhaps you have created graphical box titles and they must match up with the correct module.
Maybe a module has a special class for the title for multiple sizes or colors.  Whatever
the case, here is how to have all the boxes correctly assigned.

First, in the defaults directory, create a file called default.php. Here is what it would look like:
<?php
$default_box = "default_box.tpl";
$default_pop = "default_pop.tpl";
?>

This tells the system to make sure all modules, if not set by another default file, use these
boxes. For example, say we want calendar to use a box named calBox.tpl and a default pop
named superPop.tpl. We would create a file in the defaults/ directory named calendar.php
and enter the following:

<?php
$default_box = "calBox.tpl";
$default_pop = "superPop.tpl";
?>

Now when someone uses my theme, calBox.tpl and superPop.tpl will load instead of default_box
and default_pop. Of course the admin can change this later if they wish.

But what if you wanted even further customization? If you had a module which had several content
boxes sent from it, you can specify a box for each one. The trick is knowing what Content Variables
the module has.

Content Variables are what modules send out to phpWebSite before they are plugged
into theme variables. All you need to know is their name. They are easy to find. Pull up the
layout module and look at the box settings for that module. You should see Content Variable
information. Otherwise, just look in the module code itself for something like the following:
$GLOBALS["CNT_module"]["title"] = "Welcome";
$GLOBALS["CNT_module"]["content"] = "This is the content";


The Content Variables are always arrays and can be identified as constantly having their title
and content indexes set.

In the example above, the content variable is "CNT_module". So to set a default file for that
variable we create a file (again, named after the module's title) and enter the following
information:
<?php
$default_box = "module_box.tpl";
$default_pop = "module_pop.tpl";

$boxstyles["CNT_module"]["default_box"]="special_box.tpl";
$boxstyles["CNT_module"]["default_pop"]="special_pop.tpl";
?>

We would save this file as module_name.tpl. Now when the CNT_module is sent to phpWebSite, it
would use special_pop and special_box. Any other content variables would default to module_box
and module_pop. The rest of the theme would use the default boxes indicated in default.php
unless they had a default file of their own.


Images Directory
----------------------
NOTE: The example contained in this paragraph is no longer in use. It is kept in in case
it is reenabled at a later date.

This could be a storage place for your theme.tpl graphics if you wanted to, but it serves a more
important purpose. If a module developer codes their module to take advantage of image swapping,
then you can easily adapt their module to your theme. All you need to do is copy an identically named
graphic into a directory named the same as the module.

For example, some of the original module icons are hideous (I can say that, I made them ;-), so for
the Default theme, I wanted something more simple. Since the "users" module handles the module
icons, I just placed Default's new, little, orange icons in the themes/Default/images/users/
directory. Voila! Those are used instead of the blocky blue ones.

Not all modules may take advantage of this, but if you ask the module developer, it is easy for
them to support it.

Check the module's documentation for more details.


Templates Directory
------------------------
Many of the modules we code take advantage of templates. These are HTML files like theme.tpl and
the boxstyles. They have tags and commented sections as well. Unlike the aforementioned, the tags
names can vary greatly. They also range in size. Some can be very large, others can be small
and splintered.

For example, for calendar I have a template for each day. Then I put those day templates within
a larger month template. Sometimes these templates intertwine and work with one another.

If you want to change the appearance of a module in your theme, check out that module's directory.
If it has a templates/ directory, you are in luck. Copy the files from that directory into your
theme's template/module_name/ directory (with module_name being the name of the module you copied
it from). Now just edit those files until you get the look you like. The module will check to see
if your theme has those files and will use them instead!

Also look for a README file. Sometimes the templates are kind of difficult to mesh together
without instruction. Plus, a template MAY NOT CONTAIN ALL THE POSSIBLE VARIABLES. Back to the calendar
example, that module could have different tags for date formats, but it ships with only one echoed
to prevent confusion. If you wanted a different date format, you will need to know if it exists.
The README file in the module's templates directory should contain that information.


Injecting PHP Code in Your Theme
--------------------------------
Note: phpWebSite is 'shipped' with the file inclusion ability turned off. You can enable it
by going into your mod/layout/conf/config.php file and changing ALLOW_THEME_PHP_INSERTION to TRUE.
As an administrator, if you decide to turn this on INSPECT EVERY THEME'S THEME.PHP FILE. This could
be a possible place to put malicious code.

Sometimes you may want to include a small piece of php code in your theme. These could be functions
which show the date and time, current weather, a news feed, etc. To do so you will need to create
a theme.php file.

This file will be included when your theme is selected. To make it work, first design your commands
you want to be in your theme. For our example, we will display the date.
date('Ymd');

Next I want to copy that information into the $THEME variable.
$THEME['DATE'] = date('Ymd');

Finally I want to create a theme tag with the same name in my theme.tpl file.
{DATE}

Where ever I placed that tag, the date should now appear.

Don't use tag names like METATAG, STYLE, etc. as they get overwritten.

Making your theme XHTML compliant
---------------------------------
For more information on writing HTML to conform to XHTML standards go to:
http://www.w3.org/MarkUp/

For help debugging your theme check out the debug theme in the docs/developer/
directory.

Conclusion
---------------------
A lot of time has gone into making theme's easier to create and yet flexible enough to give
developers plenty of room to play. We hope you find it as simple.

If you have any questions, comments, or just want to submit a phat theme you have created,
drop me an email at matt@NOSPAM.tux.appstate.edu
