The Templating System Explained [message #20412] |
Wed, 13 October 2004 03:31 |
Abraxa
Messages: 72 Registered: August 2004 Location: Germany
Karma:
|
Member |
|
|
Okay, so you just downloaded FUDForum, installed it, fiddled around a little and found some stuff you'd like to change using the template system? Welp, then have a nice cup of tea, get comfy and listen carefully.
0. What You Should Know
To make things simpler, I'll use two aliases for the FUDForum paths.
"FUDForum/" will be the Server Root, meaning the path of where the browsable files are stored.
"FUDForumData/" will be the Forum Data Root that contains all the non-browsable files.
Also, I'll use the default template and English language in the example paths.
All set? Then let's go!
1. The Global Perspective
As you probably know, FUDForum uses an advanced templating system that separates the forum internals and the forum design as much as possible. In order to do that, both parts are put into different files. So let's have a look at where's the stuff that we need when developing templates:
FUDForum/theme: This folder contains the compiled themes. Usually you'll only see 'default' in there.
FUDForum/theme/default/: Here you'll find all compiled CSS and PHP files of that theme.
FUDForum/theme/default/help: The help files for that particular theme.
FUDForum/theme/default/images: This directory holds all the images this theme is made of.
FUDForumData/include: In this directory you'll find the pre-built include files used by the forum, whereas in
FUDForumData/include/default you'll find the compiled include files specific for that theme.
FUDForumData/src: This folder has all the uncompiled template php source files - notice that all themes use the same.
FUDForumData/thm/default: The template files that make up the forum's structure/design can be found here.
FUDForumData/thm/default/i18n/en/msg: This is the message file, specific for english.
FUDForumData/thm/default/i18n/en/help: Should be obvious =)
FUDForumData/thm/default/i18n/en/img: Here you can find the images used by that theme which contain text localized to english.
FUDForumData/thm/default/images: This directory contains all images that the theme uses which do NOT require localization.
FUDForumData/thm/default/tmpl: The most important directory for you: the theme's uncompiled template files.
If you just want to make visual changes to the forum then you'll probably only edit the theme's template files and maybe some images here and there.
However if you want to make substantial changes to the way the forum works (e.g. remove COPPA from the source entirely, build a webpage based on FUDForum, or whatever else comes to your mind) then you will also have to edit the source files. That's all fine and dandy but since that awesome fella called Ilia is still working on the forum software, you're going to make updating a lot harder for yourself.
2. Understanding the Templating System
If you look at the FUDForumData/thm/default folder, you'll see tons of .tmpl files. These files determine how the php files are built that the forum will use in the end. Eeach of those template files consists of either only a .tmpl file (i.e. header.tmpl) or have a corresponding template php source file in FUDForumData/src (i.e. post.tmpl / post.php.t). The reason is that the template files themselves only contain so-called sections, which, merged with the template php source file, yield the complete source. But let's have a look at a small example template file first:
curtime.tmpl:
/***************************************************************************
* copyright : (C) 2001-2004 Advanced Internet Designs Inc.
* email : forum(at)prohost(dot)org
* $Id: curtime.tmpl,v 1.7 2004/04/25 20:18:25 hackie Exp $
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
***************************************************************************/
{MAIN_SECTION: curtime Current time indicator}
<br /><div align="center"><div class="curtime"><b>{MSG: current_time}:</b> {DATE: !__request_timestamp__ %a %b %e %H:%M:%S %Z %Y}</div></div>
{MAIN_SECTION: END}
The first thing you'll notice is the file header that has general information about the file, including the file name itself. You don't have to have it but those headers help Ilia with the CVS and make everyone handling these files aware of the legal stuff. Besides that you'll notice that the file defines a MAIN_SECTION called "curtime". The section can also have a description ("Current time indicator" in this case) which makes understanding the purpose of the section easier to understand when you look at it again at a later time.
Inside the section you see some HTML tags, but you'll also notice the {MSG: current_time} and {DATE: ...} template tags. Those tags are the key to the templating system FUDForum uses: the compiler later on replaces those tags with other content, depending on the type of the tag. The manual lists all available types - I'll be focusing on the {TEMPLATE: ...} and {TEMPLATE-DATA: ...} tags mainly.
If you already had a look at the i18n message (FUDForumData/thm/default/i18n/en/msg) you will most likely understand how the {MSG: ...} tag works: here it takes the entry called "current_time" from the message file and puts that message where the {MSG: ...} tag was - in this case it would be "Current Time".
This may seem simple and boring, however if you take the next step and use a tag like {TEMPLATE: ...}, you can replace the tag by other templates, too! =)
Let's have a look at a template file making use of that:
footer.tmpl:
/***************************************************************************
* copyright : (C) 2001-2004 Advanced Internet Designs Inc.
* email : forum(at)prohost(dot)org
* $Id: footer.tmpl,v 1.13 2004/04/25 20:18:25 hackie Exp $
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
***************************************************************************/
{MAIN_SECTION: footer forum's footer}
</td></tr></table><div class="ForumBackground ac foot">
<b>.::</b> <a href="mailto:{GVAR: ADMIN_EMAIL}">{MSG: forum_contact}</a> <b>::</b> <a href="{TEMPLATE: footer_lnk}">{MSG: forum_home}</a> <b>::.</b>
<p>
<span class="SmallText">Powered by: FUDforum {GVAR: FORUM_VERSION}<br />Copyright ©2001-2004 <a href="http://fudforum.org/">FUD Forum Bulletin Board Software</a></span>
</div></body></html>
{MAIN_SECTION: END}
{MAIN_SECTION: footer_plain forum's footer for plain pages such as popups}
</td></tr></table></body></html>
{MAIN_SECTION: END}
{SECTION: footer_lnk}
{ROOT}?t=index&{DEF: _rsid}
{SECTION: END}
Look at the file and try finding out what happens when the file is being compiled. Can you see it?
...yep! The href property inside the hyperlink is filled with the content of the "footer_lnk" section! =)
As you can see the "footer_lnk" section itself also contains template tags which are resolved before the template is being put where it belongs: {ROOT} simply is "index.php" and {DEF: _rsid} is the content of the PHP constant named _rsid (which btw is the session ID).
Click here if that was too fast for you.Ok then.
The template compiler goes through the "footer" section as it's the first one it sees. In there it will find a {GVAR: ...} tag which it resolves (how it does that isn't important here). When that's done it finds the {MSG: forum_contact} tag which it looks up in the msg file: it finds the word "Contact".
So up until here, the content of the "footer" section looks like this: (I highlighted the replaced tags to make it easier to understand)
</td></tr></table><div class="ForumBackground ac foot">
<b>.::</b> <a href="mailto: admin(at)board(dot)org"> Contact:</a> <b>::</b> <a href="
...and then the compiler finds the {TEMPLATE: ...} tag. Since the compiler doesn't know that template yet it goes to find it. It's at the end of the file so the compiler starts evaluating it: {ROOT} always equals "index.php" and the content of _rsid could be "rid=2&S=8d84c151f1d4e28aa968ae5d0ecfb146", for example.
With that, the content of the "footer_lnk" section becomes "index.php?t=index&rid=2&S=8d84c151f1d4e28aa968ae5d0ecfb146". =)
Now that the compiler knows the content of that section it can go back processing the "footer" section and finish its work, seeing how there's only one more {MSG: ...} and {GVAR: ...} tag, whose contents are known to the compiler:
</td></tr></table><div class="ForumBackground ac foot">
<b>.::</b> <a href="mailto: admin(at)board(dot)org"> Contact:</a> <b>::</b> <a href=" index.php?t=index&rid=2&S=8d84c151f1d4e28aa968ae5d0ecfb146"> Home</a> <b>::.</b>
<p>
<span class="SmallText">Powered by: FUDforum 2.6.7RC2<br />Copyright ©2001-2004 <a href=" http://fudforum.org/">FUD Forum Bulletin Board Software</a></span>
</div></body></html>
3. Using Sections From Other Template Files
Now what do you do when you want to use a section defined in a different template file?
The answer is simple: use the {TEMPLATE: ...} tag as always, just tell the compiler that you're making use of another template file:
/***************************************************************************
* copyright : some bogus author
* email : some bogus email
* $Id: somefile.tmpl,v 0.00 2004/09/10 00:00:00 author Exp $
***************************************************************************/
{REF: header.tmpl}
{REF: curtime.tmpl}
{REF: footer.tmpl}
{PAGE: somepage}
{TEMPLATE: header}
{TEMPLATE: curtime}
{TEMPLATE: footer}
{PAGE: END}
Sections inside template files are either starting with {SECTION: ...}, {MAIN_SECTION: ...} - or, as you can see here, {PAGE: ...}. The latter is very important as it defines - you guessed right - a page. =)
Now what can we do with a page section? We can refer to it in a php source file and thus make the compiler generate valid php scripts!
Let's find out how that works in the fourth chapter:
4. Bringing It All Together
As of now we have nice and tidy intructions for the compiler on how to build the sections and what goes in there - but so far we don't have one single line of php code and the compiler doesn't know anything about where to put all the data it gathered either. That's where the template php sources (residing in FUDForumData/src) come into play:
coppa.tmpl:
/***************************************************************************
* copyright : (C) 2001-2004 Advanced Internet Designs Inc.
* email : forum(at)prohost(dot)org
* $Id: coppa.tmpl,v 1.11 2004/04/25 20:18:25 hackie Exp $
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
***************************************************************************/
{PHP_FILE: input: coppa.php.t; output: coppa.php;}
{REF: security.tmpl}
{REF: header.tmpl}
{REF: usercp.tmpl}
{REF: curtime.tmpl}
{REF: footer.tmpl}
{PAGE: COPPA_PAGE determines if a new user is <13 years of age, needed for COPPA compliance}
{TEMPLATE: header}
{TEMPLATE: usercp}
<table cellspacing="1" cellpadding="2" class="ContentTable">
<tr class="RowStyleA GenText ac"><td>
{MSG: coppa_link}<br /><br />
[<a href="{TEMPLATE: COPPA_PAGE_lnk}">{MSG: coppa_before}</a>]
[<a href="{TEMPLATE: COPPA_PAGE_lnk1}">{MSG: coppa_after}</a>]
<hr>
{MSG: coppa}
</td></tr>
</table>
{TEMPLATE: curtime}
{TEMPLATE: footer}
{PAGE: END}
{SECTION: coppa_conf}
{MSG: coppa_conf}
{SECTION: END}
{SECTION: COPPA_PAGE_lnk}
{ROOT}?t=pre_reg&coppa=&{DEF: _rsid}
{SECTION: END}
{SECTION: COPPA_PAGE_lnk1}
{ROOT}?t=pre_reg&coppa=1&{DEF: _rsid}
{SECTION: END}
The first thing you will notice is the {PHP_FILE: ...} tag. You can only have one of it per template file as it tells the compiler which template php source file belongs to that very template file. As you can see here, the resulting file will be a .php file, so there needs to go some php code in there, too. Where does that come from?
You probably guessed that "coppa.php.t" has something to do with it. That's right! Let me show the contents of that file to you:
coppa.tmpl:
<?php
/***************************************************************************
* copyright : (C) 2001-2004 Advanced Internet Designs Inc.
* email : forum(at)prohost(dot)org
* $Id: coppa.php.t,v 1.8 2004/01/04 16:38:26 hackie Exp $
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
***************************************************************************/
/*{PRE_HTML_PHP}*/
$TITLE_EXTRA = ': {TEMPLATE: coppa_conf}';
/*{POST_HTML_PHP}*/
$coppa = __request_timestamp__-409968000;
/*{POST_PAGE_PHP_CODE}*/
?>
{TEMPLATE: COPPA_PAGE}
Don't worry about the special tags inside the php comments for now and have a look at the last line instead:
{TEMPLATE: COPPA_PAGE}
Doesn't that look familiar? It does - and it's because it has been defined in the coppa.tmpl file!
Now it all makes sense: the compiler puts the contents of the "COPPA_PAGE" section at the end of the php file! =)
The reason why this works is because the FUDForum theme compiler resolves template tags inside both the .tmpl and the .t files. With that we can do pretty spiffy stuff, as you can see in the above example: the php code itself contains a reference to the "coppa_conf" section which during the compilation gets replaced by the contents of that very section. The resulting php code for that line thus will look like this:
$TITLE_EXTRA = ': COPPA Confirmation';
(Note: {MSG: coppa_conf} becomes "COPPA Confirmation", which then makes {TEMPLATE: coppa_conf} become the same)
If you now go and have a look at FUDForum/theme/default/coppa.php you can see how everything comes together: the php code from security.inc.t, usercp.inc.t, curtime.inc.t and last but not least coppa.php.t - they all are {REF: ...}'d directly or indirectly by coppa.tmpl and thus need to be included in the resulting php file for things to work properly.
That's how the FUDForum theme compiler basically works: it takes one template file, looks what other template files are needed while it replaces all the template tags and then merges everything into the output file. Simple, but effective! =)
For now that's enough to understand how the templating system works but if you want the full dose and get to know some more advanced tricks, read on.
5. Advanced Mechanisms I
If you had a look at the files in the FUDForumData/thm/default/tmpl directory, you might have noticed that some files have file prefixes in their {PHP_FILE: ...} tag (i.e. admincp.tmpl). Not surprisingly they actually have a meaning:
{PHP_FILE: input: bogus.inc.t; output: 0bogus.inc;}: The content of this include file is inserted where the /*{PRE_HTML_PHP}*/ line in the .php.t file is
{PHP_FILE: input: bogus.inc.t; output: @bogus.inc;}: The content of this include file is inserted where the /*{POST_HTML_PHP}*/ line in the .php.t file is
{PHP_FILE: input: bogus.inc.t; output: !bogus.inc;}: The content of this include file is inserted where the /*{POST_PAGE_PHP_CODE}*/ line in the .php.t file is
Remember the copper.php.t file I posted above? There you can see where those special placeholder lines go.
The need for this mechanism originates in the need to execute some code in a particular order - without this, the order of the code appearing in the resulting php file would be virtually unpredictable.
6. Advanced Mechanisms II
Since the template compiler actually replaces the tags with their evaluated expressions we can save ourselves quite a bit of work sometimes. Imagine a structure where you have a list of 5 items:
{MAIN_SECTION: main}
{TEMPLATE: entry_1}
{TEMPLATE: entry_2}
{TEMPLATE: entry_3}
{TEMPLATE: entry_4}
{TEMPLATE: entry_5}
{MAIN_SECTION: END}
{SECTION: entry_1}
<a href="someURL">someLabel</a><br />
{SECTION: END}
{SECTION: entry_2}
<a href="someURL">someLabel</a><br />
{SECTION: END}
{SECTION: entry_3}
<a href="someURL">someLabel</a><br />
{SECTION: END}
{SECTION: entry_4}
<a href="someURL">someLabel</a><br />
{SECTION: END}
{SECTION: entry_5}
<a href="someURL">someLabel</a><br />
{SECTION: END}
That we can have a lot simpler by using a loop in php to build the structure for us.
In the template file we then have...
{MAIN_SECTION: main}
{TEMPLATE-DATA: entries}
{MAIN_SECTION: END}
{SECTION: single_entry}
<a href="{VAR: entry_url}">{VAR: entry_label}</a><br />
{SECTION: END}
...and in the corresponding template php source file we have...
...some stuff...
for($i=0;$i<5;$i++) {
$entry_url = $someArray[$i];
$entry_label = $someOtherArray[$entry_url];
$entries .= '{TEMPLATE: single_entry}';
}
...some stuff...
The reason why this works is because - as you hopefully know by now - the template compiler replaces the template tags by their evaluated content. Here's what this example would look like after compilation:
...some stuff...
for($i=0;$i<5;$i++) {
$entry_url = $someArray[$i];
$entry_label = $someOtherArray[$entry_url];
$entries .= '<a href="'.$entry_url.'">'.$entry_label.'</a><br />';
}
...some stuff...
Also in this example you can clearly see why using
$entries .= "{TEMPLATE: single_entry}";
would NOT work: the string wouldn't be terminated properly and any quotes inside the referred section would terminate the string instead. That's not what we want at all
If you however need the quotation marks to evaluate some statement inside a template you got a semantic error in your template structure: php and templates should be separated. So the "problem" that you can't use quotes to evaluate states in sections isn't the actual problem - the real problem is that you didn't separate those two.
The solution for this problem is simple, though: just use a {VAR: ...} statement inside the section you tried to evaluate and you're good.
7. Special Files
Ever wondered which template the index.php file in the FUDForum's root directory is built from? The file called root_index.tmpl is in charge of that, if you ever need it. I did. =)
Also you'll notice a file called "messages" inside the FUDForumData/thm/default/tmpl folder. Its purpose apparently is to be a globally available pool of URIs that doesn't need to be included in your template file. So if you have some URIs that you want to have available in all your template files without having to place a {REF: ...} tag to include a particular template file - the "messages" file is where they should go.
8. Complete Template Tag Listing
I'll edit that in tomorrow. I need sleep now... lol =)
9. Conclusion
The last tip I have for you is:
Don't forget to go to your Admin CP and rebuild the theme after you made changes - they won't be in effect before you do that =)
To sum it all up: FUDForum's templating system is very powerful, has no performance penalty at all and provides sheer endless possibilities of modifying the forum in any way you want. The only downside of it that I could find was that templates that merely change the design of the forum might not be compatible with future releases of the forum since changes in the FUDForumData/src directory sometimes also requires changes in the template files also. However it seems every other forum has a similar (or even worse) problem concerning skins/templates so I guess it's not too bad.
I hoped my "little" tutorial helped you on your way to understand the way templates work and I'd love to see more templates being published - if I could do my part in that then I'm glad. =)
Anyway, that's it for now. If you spot any errors or have remarks for me to add, feel free to leave me a note - updates follow as time and experience permit. Hope you found this at least halfway useful and give FUDForum the continued support it deserves!
-Soeren
[Edit: changed a mix-up in chapter 5]
|
|
|