Customizing Layout with Themes in PHP-Nuke

Exclusive offer: get 50% off this eBook here
Building Websites with PHP-Nuke

Building Websites with PHP-Nuke — Save 50%

A practical guide to creating and maintaining your own community website with PHP-Nuke

$20.99    $10.50
by Douglas Paterson | March 2010 | MySQL Content Management Open Source PHP

In the previous article of the series by Douglas Paterson, author of Building Websites with PHP-Nuke, we explored the PHP-Nuke Forums module. In this article, which is the ninth article of the article series, we are going to transform the look of the Dinosaur Portal with the help of a new PHP-Nuke theme. A PHP-Nuke theme is a collection of HTML files, CSS styles, images, and PHP code that defines the layout and appearance of your pages, and hence, the look and feel of your site. Through the use of themes, without having to touch the inner workings of PHP-Nuke, you can create a new look for your site, enforced throughout the site. There is even the possibility of allowing the user to choose a personal theme.

Creating a PHP-Nuke theme gives your site its own special look, distinguishing it from other PHP-Nuke-created sites and offers an effective outlet for your creative talents. Creating a theme requires some knowledge of HTML, confidence in working with CSS and PHP, but most important is some imagination and creativity!

Unlike the tasks we have tackled in previous articles, where we have been working exclusively through a web browser to control and configure PHP-Nuke, working with themes is the start of a new era in your PHP-Nuke skills; editing the code files of PHP-Nuke itself. Fortunately, the design of PHP-Nuke means that our theme work won't be tampering with the inner workings of PHP-Nuke. However, becoming confident in handling the mixture of HTML and PHP code that is a PHP-Nuke theme will prepare you for the more advanced work ahead, when we really get to grips with PHP-Nuke at the code level.

In this article, we will look at:

  • Theme management
  • Templates in themes
  • Changing the page header
  • Working with the stylesheet
  • Changing blocks
  • Changing the format of stories

What Does a Theme Control?

Despite the fact that we say 'themes control the look and feel of your site', a theme does not determine every aspect of the page output. PHP-Nuke is an incredibly versatile application, but it cannot produce every website imaginable.

Appearance

First of all, the appearance of the page can be controlled through the use of colors, fonts, font sizes, weights, and so on. This can either be done through the use of CSS styles or HTML. You can also add JavaScript for fancier effects, or even Flash animations, Java applets, or sounds—anything that you can add to a standard HTML page.

Graphical aspects of the page such as the site banner, background images, and so on, are under the care of the theme. There are also some modules that allow their standard graphical icons to be overridden with images from a theme.

Page Layout

Roughly speaking, a PHP-Nuke page consists of three parts; the top bit, the bit in the middle, and the bit at the bottom! The top bit—the header—usually contains a site logo and such things as a horizontal navigation bar for going directly to important parts of your site. The bottom bit—the footer—contains the copyright message.

In between the header and the footer, the output is usually divided into three columns. The left-hand column typically contains blocks, displayed one of top each other, the middle column contains the module output, and the right-hand column contains more blocks. The layout of these columns (their width for example) is controlled by the theme. You may have noticed that the right-hand column is generally only displayed on the homepage of a PHP-Nuke site; this too, is something that is controlled by the theme.

The appearance of the blocks is controlled by the theme; PHP-Nuke provides the title of the block and its content, and the theme will generally 'frame' these to produce the familiar block look.

The theme also determines how the description of stories appears on the homepage. In addition, the theme determines how the full text of the story, its extended text, is displayed.

We've talked about how the theme controls the 'look' of things. The theme also allows you to add other site-related data to your page; for example the name of the site can appear, and the site slogan, and you can even add such things as the user's name with a friendly welcome message.

Theme Management

Basically, a theme is a folder that sits inside the themes folder in your PHP-Nuke installation. Different themes correspond to different folders in the themes folder, and adding or removing a theme is as straightforward as adding or removing the relevant folder from the themes folder.

By default, you will find around 14 themes in a standard PHP-Nuke installation. DeepBlue is the default theme.

Themes can be chosen in one of two ways:

  • By the administrator: You can simply select the required theme from the General Site Info panel of the Site Preferences administration menu and save the changes. The theme selected by the administrator is the default theme for the site and will be seen by all users of the site, registered or unregistered.
  • By the user: Users can override the default theme set by the administrator from the Themes option of the Your Account module. This sets a new, personal, theme that will be displayed to that user. Note that this isn't a theme especially customized for that user; it is just one chosen from the list of standard themes installed on your site.

Unregistered visitors do not have an option to choose a theme; they have to become registered users.

Theme File Structure

Let's start with the default theme, DeepBlue. If you open up the DeepBlue folder within the themes folder in the root of your PHP-Nuke installation, you will find three folders and two files. The three folders are:

  • forums: This folder contains the theme for the Forums module. This is not strictly a requirement of a PHP-Nuke theme, and not every PHP-Nuke theme has a forums theme. The Forums module (otherwise known as phpBB) has its own theme 'engine'. The purpose of including a theme for the forums is that you have consistency between the rest of your PHP-Nuke display and the phpBB display.
  • images: This folder contains the image files used by your theme. These include the site logo, background images, and graphics for blocks among others. As mentioned earlier, within this folder can be other folders containing images to override the standard icons.
  • style: This folder contains the CSS files for your theme. Usually, there is one CSS file in the style folder, style.css. Each theme will make use of its style.css file, and this is the file into which we will add our style definitions when the time comes.

Of the two files, index.html is simply there to prevent people browsing to your themes folder and seeing what it contains; visiting this page in a browser simply produces a blank page. It is a very simple security measure.

The themes.php file is a PHP code file, and is where all the action happens. This file must always exist within a theme folder. We will concentrate on this file later when we customize the theme.

In other themes you will find more files; we will look at these later.

Installing a New Theme

Installing and uninstalling themes comes down to adding or removing folders from the themes folder, and whenever a list of available themes is presented, either in the Site Preferences menu or the Your Accounts module, PHP-Nuke refreshes this list by getting the names of the folders in the themes folder.

You will find a huge range of themes on the Web. For example, there is a gallery of themes at:

http://nukecops.com/modules.php?set_albumName=packs&op=modload&name=Gallery& 
file=index&include=view_album.php

Many of these are themes written for older versions of PHP-Nuke, but most are still compatible with the newer releases.

There is also a live demonstration of some themes at:

http://www.portedmods.com/styles/

On this page you can select the new theme and see it applied immediately, before you download it.

Removing an Existing Theme

To remove a theme from your PHP-Nuke site you simply remove the corresponding folder from the themes folder, and it will no longer be available to PHP-Nuke.

However, you should be careful when removing themes—what if somebody is actually using that theme?

  • If a user has that theme selected as their personal theme, and you remove that theme, then that user's personal theme will revert to the default theme selected in Site Preferences.
  • If you remove the site's default theme, then you will break your site!

Deleting the site's default theme will produce either a blank screen or messages like the following when you attempt to view your site.

Warning: head(themes/NonExistentTheme/theme.php)
[function.head]: failed to create stream:
No such file or directory in c:\nuke\html\header.php on line 31

The only people who can continue to use your site in this situation are those who have selected a personal theme for themselves—and only if that theme is still installed.

To correct such a faux pas, make a copy of one of the other themes in your themes folder (unless you happen to have a copy of the theme you just deleted elsewhere), and rename it to the name of the theme you just deleted.

In conclusion, removing themes should only be a problem if you somehow manage to remove your site's default theme. For users who have selected the theme you just removed, their theme will revert to the default theme and life goes on for them.

A final caveat about the names of theme folders; do not use spaces in the names of the folders in the themes folder—this can lead to strange behavior when the list of themes is displayed in the drop-down menus for users to select from.

From an Existing Theme to a New Theme

We'll create a new theme for the Dinosaur Portal by making changes to an existing theme. This will not only make you feel like the theme master, but it will also serve to illustrate the nature of the theme-customization problem. We'll be making changes all over the place—adding and replacing things in HTML and PHP files—but it will be worth it. Another thing to bear in mind is that we're creating a completely different looking site without making any changes to the inner parts of PHP-Nuke. At this point, all we are changing is the theme definition.

The theme for the Dinosaur Portal will have a warm, tropical feel to it to evoke the atmosphere of a steaming, tropical, prehistoric jungle, and will use lots of orange color on the page.

First of all, we need a theme on which to conduct our experiments. We'll work on the 3D-Fantasy theme.

Starting Off

The first thing we will do is to create a new theme folder, which will be a copy of the 3D-Fantasy theme.

Open up the themes folder in your file explorer, and create a copy of the 3D-Fantasy folder. Rename this copy as TheDinosaurPortal.

Now log into your site as testuser, and from the Your Account module, select TheDinosaurPortal as the theme. Your site will immediately switch to this theme, but it will look exactly like 3D-Fantasy, because, at the moment, it is!

You will also need some images from the code download for this article; you will find them in the SiteImages folder of this article's code.

Replacing Traces of the Old Theme

The theme that we are about to work on has many occurrences of 3D-Fantasy in a number of files, such as references to images. We will have to remove these first of all, or else our new theme will be looking in the wrong folder for images and other resources.

Open each of the files below in your text editor, and replace every occurrence of 3D-Fantasy with TheDinosaurPortal in a text editor, we'll use Wordpad. "You can use the replace functionality of your editor to do this. For example, in Wordpad, select Edit | Replace; enter the text to be replaced, and then click on Replace All to replace all the occurrences in the open file. After making all the changes, save each file:

  • blocks.html
  • footer.html
  • header.html
  • story_home.html
  • story_page.html
  • theme.php
  • tables.php

Templates and PHP Files

We've just encountered two types of file in the theme folder—PHP code files (theme.php and tables.php) and HTML files (blocks.html, footer.html, and so on). Before we go any further, we need to have a quick discussion of what roles these types of file play in the theme construction.

PHP Files

The PHP files do the main work of the theme. These files contain the definitions of some functions that handle the display of the page header and how an individual block or article is formatted, among other tasks. These functions are called from other parts of PHP-Nuke when required. We'll talk about them when they are required later in the article. Part of our customization work will be to make some changes to these functions and have them act in a different way when called.

Historically, the code for a PHP-Nuke theme consisted of a single PHP file, theme.php. One major drawback of this was the difficulty you would have in editing this file in the 'design' view of an HTML editor. Instead of seeing the HTML that you wished to edit, you probably wouldn't see anything in the 'design' view of most HTML editors, since the HTML was inextricably intertwined with the PHP code. This made creating a new theme, or even editing an existing theme, not something for the faint-hearted—you had to be confident with your PHP coding to make sure you were changing the right places, and in the right way.

The theme.php file consists of a number of functions that are called from other parts of PHP-Nuke when required. These functions are how the theme does its work.

One of the neat appearances in recent versions of PHP-Nuke is the use of a 'mini-templating' engine for themes. Not all themes make use of this method (DeepBlue is one theme that doesn't), and that is one of the reasons we are working with 3D-Fantasy as our base theme, since it does follow the 'templating' model.

Templates

The HTML files that we modified above are the theme templates. They consist of HTML, without any PHP code. Each template is responsible for a particular part of the page, and is called into action by the functions of the theme when required.

One advantage of using these templates is that they can be easily edited in visual HTML editors, such as Macromedia's Dreamweaver, without any PHP code to interfere with the page design.

Another advantage of using these templates is to separate logic from presentation. The idea of a template is that it should determine how something is displayed (its presentation). The template makes use of some data supplied to it, but acquiring and choosing this data (the logic) is not done in the template. The template is processed or evaluated by the 'template engine', and output is generated. The template engine in this case is the theme.php file.

To see how the template and PHP-Nuke 'communicate', let's look at an extract from the header.html file in the 3D-Fantasy folder:

<a href="index.php">
<img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="themes/3D-Fantasy/images/logo.gif" border="0"
alt="Welcome to $sitename" align="left">
</a>

The $sitename text (shown highlighted) is an example of what we'll call a placeholder. There is a correspondence between these placeholders and PHP variables that have the same name as the placeholder text. Themes that make use of this templating process more or less replace any text beginning with $ in the template by the value of the corresponding PHP variable.

This means that you can make use of variables from PHP-Nuke itself in your themes; these could be the name of your site ($sitename), your site slogan, or even information about the user. In fact, you can add your own PHP code to create a new variable, which you can then display from within one of the templates.

To complete the discussion, we will look at how the templates are processed in PHP-Nuke. The code below is a snippet from one of the themeheader() function in the theme.php file. This particular snippet is taken from the 3D-Fantasy theme.

function themeheader()
{
global $user, $banners, $sitename, $slogan, $cookie, $prefix,
$anonymous, $db;
... code continues ....

$tmpl_file = "themes/3D-Fantasy/header.html";
$thefile = implode("", file($tmpl_file));
$thefile = addslashes($thefile);
$thefile = "\$r_file=\"".$thefile."\";";
eval($thefile);
print $r_file;
... code continues ....

The processing starts with the line where the $tmpl_file variable is defined. This variable is set to the file name of the template to be processed, in this case header.html. The next line grabs the content of the file as a string. Let's suppose the header.html file contained the text You're welcomed to $sitename, thanks for coming!. Then, continuing in the code above, the $thefile variable would eventually hold this:

\$r_file = \" You\'re welcomed to $sitename, thanks for coming!\";

This looks very much like a PHP statement, and that is exactly what PHP-Nuke is attempting to create. The eval() function executes the statement; it defines the variable $r_file as above. This is equivalent to putting this line straight into the code:

$r_file = " You\'re welcomed to $sitename, thanks for coming!";

If this line were in the PHP code, the value of the $sitename variable will be inserted into the string, and this is exactly how the placeholders in the templates are replaced with the values of the corresponding PHP variables.

This means that the placeholders in templates can only use variables accessible at the point in the code where the template is processed with the eval() function. This means any parameters passed to the function at the time—global variables that have been announced with the global statement or any variables local to the function that have been defined before the line with the eval() function. This does mean that you will have to study the function processing the template to see what variables are available. In the examples in this article we'll look at the most relevant variables.

The templates do not allow for any form of 'computation' within them; you cannot use loops or call PHP functions. You do your computations 'outside' the template in the theme.php file, and the results are 'pulled' into the template and displayed from there.

Now that we're familiar with what we're going to be working with, let's get started.

Changing the Page Header

The first port of call will be creating a new version of the page header. We will make these customizations:

  • Changing the site logo graphic
  • Changing the layout of the page header
  • Adding a welcome message to the user, and displaying the user's avatar
  • Adding a drop-down list of topics to the header
  • Creating a navigation bar

Time For Action—Changing the Site Logo Graphic

  1. Grab the <>ilogo.gif file from the SiteImages folder in the code download.
  2. Copy it to the themes/TheDinosaurPortal/images folder, overwriting the existing logo.gif file.
  3. Refresh the page in your browser. The logo will have changed!

Building Websites with PHP-Nuke

What Just Happened?

The logo.gif file in the images folder is the site logo. We replaced it with a new banner, and immediately the change came into effect.

Time For Action—Changing the Site Header Layout

  1. In the theme folder is a file called header.html. Open up this file in a text editor, we'll use Wordpad.
  2. Replace all the code in this file with the following:
  3. <!-- Time For Action—Changing the Site Header Layout -->
    <table border="0" cellspacing="0" cellpadding="6" width="100%"
    bgcolor="#FFCC33">
    <tr valign="middle">
    <td width="60%" align="right" rowspan="2">
    <a href="index.php"><img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="themes/$GLOBALS[ThemeSel]/images/logo.gif"
    border="1" alt="Welcome to $sitename">
    </a></td>
    <td width="40%" colspan="2">
    <p align="center"><b>WELCOME TO $sitename!</b></td>
    </tr>
    <tr>
    <td width="20%">GAP</td>
    <td width="20%">GAP</td>
    </tr>
    </table>
    <!-- End of Time for Action -->
    $public_msg<br>
    <table cellpadding="0" cellspacing="0" width="99%" border="0"
    align="center" bgcolor="#ffffff">
    <tr><td bgcolor="#ffffff" valign="top">
  4. Save the header.html file.
  5. Refresh your browser. The site header now looks like this:

Building Websites with PHP-Nuke

What Just Happened?

The header.html file is the template responsible for formatting the site header. Changing this file will change the format of your site header.

We simply created a table that displays the site logo in the left-hand column, a welcome message in the right-hand column, and under that, two GAPs that we will add more to in a moment. We set the background color of the table to an orange color (#FFCC33). We used the $sitename placeholder to display the name of the site from the template.

Note that everything after the line:

<!-- End of Time for Action -->

in our new header.html file is from the original file. (The <!-- ... --> characters here denote an HTML comment that is not displayed in the browser). This is because the end of the header.html file starts a new table that will continue in other templates. If we had removed these lines, the page output would have been broken.

There was another interesting thing we used in the template, the $GLOBALS[ThemeSel] placeholder:

<a href="index.php"><img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="themes/$GLOBALS[ThemeSel]/images/logo.gif"

ThemeSel is a global variable that holds the name of the current theme—it's either the default site theme or the user's chosen theme. Although it's a global variable, using just $ThemeSel in the template would give a blank, this is because it has not been declared as global by the function in PHP-Nuke that consumes the header.html template. However, all the global variables can be accessed through the $GLOBALS array, and using $GLOBALS[ThemeSel] accesses this particular global variable. Note that this syntax is different from the way you may usually access elements of the $GLOBALS array in PHP. You might use $GLOBALS['ThemeSel'] or $GLOBALS["ThemeSel"]. Neither of these work in the template so we have to use the form without the ' or ".

Time For Action—Fixing and Adding the Topics List

Next we'll add the list of topics as a drop-down box to the page header. The visitor will be able to select one of the topics from the box, and then the list of stories from that topic will be displayed to them through the News module. Also, the current topic will be selected in the drop-down box to avoid confusion.

This task involves fixing some bugs in the current version of the 3D-Fantasy theme.

  1. First of all, open the theme.php file and find the following line in the themeheader() function definition:
  2. $topics_list = "<select name=\"topic\" onChange='submit()'>\n";
  3. Replace this line with these two lines:
  4. global $new_topic;
    $topics_list = "<select name=\"new_topic\" onChange='submit()'>\n";
  5. If you move a few lines down in the themeheader() function, you will find this line:
  6. if ($topicid==$topic) { $sel = "selected "; }
  7. Replace $topic with $new_topic in this line to get:
  8. if ($topicid==$new_topic) { $sel = "selected "; }
  9. Save the theme.php file.
  10. Open the header.html file in your text editor, and where the second GAP is, make the modifications as shown below:
  11. <td width="20%">GAP</td>
    <td width="20%"><form action="modules.php?name=News&new_topic" method="post">
    Select a Topic:<br>$topics_list</select></form></td>
    </tr>
    </table>
    <!-- End of Time for Action -->
  12. Save the header.html file.
  13. Refresh your browser. You will see the new drop-down box in your page header:

Building Websites with PHP-Nuke

What just Happened?

The themeheader() function is the function in theme.php responsible for processing the header.html template, and outputting the page header.

The $topics_list variable has already been created for us in the themeheader() function, and can be used from the header.html template. It is a string of HTML that defines an HTML select drop-down list consisting of the topic titles.

However, the first few steps require us to make a change to the $topics_list variable, correcting the name of the select element and also using the correct variable to ensure the current topic (if any) is selected in the drop-down box. The select element needs to have the name of new_topic, so that the News module is able to identify which topic we're after.

This is all done with the changes to the theme.php file. First, we add the global statement to access the $new_topic variable, before correcting the name of the select element:

global $new_topic;
$topics_list = "<select name=\"new_topic\" onChange='submit()'>\n";

The next change we made is to make sure we are looking for the $new_topic variable, not the $topic variable, which isn't even defined:

if ($topicid==$new_topic) { $sel = "selected "; }

Now the $topics_list variable is corrected, all we have to do is add a placeholder for this variable to the header.html template, and some more HTML around it. We added the placeholder for $topics_list to display the drop-down list, and a message to go with it encouraging the reader to select a topic into one of the GAP table cells we created in the new-look header.

The list of topics will be contained in a form tag, and when the user selects a topic, the form will be posted back to the server to the News module, and the stories in the selected topic will be displayed. (The extra HTML that handles submitting the form is contained with the $topics_list variable.)

<form action="modules.php?name=News" method="post">
Select a Topic:<br>$topics_list

All that remains now is to close the select tag—the tag was opened in the $topics_list variable but not closed—and then close the form tag:

</select></form>

When the page is displayed, this is the HTML that PHP-Nuke produces for the topics drop-down list:

<form action="modules.php?name=News&new_topic" method="post">
Select a Topic:<br><select name="topic" onChange='submit()'>
<option value="">All Topics</option>
<option value="1">The Dinosaur Portal</option>
<option value="2">Dinosuar Hunting</option>
</select></form>
Building Websites with PHP-Nuke A practical guide to creating and maintaining your own community website with PHP-Nuke
Published: November 2005
eBook Price: $20.99
Book Price: $29.99
See more
Select your format and quantity:

Time For Action—Adding a Welcome Message to the User

We will add some more information the page header; a friendly message to salute our visitors:

  1. Open the theme.php file in your text editor, and inside the themeheader() function definition, find the following line:
    $theuser = "&nbsp;&nbsp;Welcome $username!";
  2. Change that line to the following:
    $theuser = "&nbsp;&nbsp;Hi $username!, how you doing?";
  3. Save the theme.php file.
  4. Open the header.html file, and modify the remaining GAP as shown below:
    <td width="20%">$theuser</td>
    <td width="20%"><form action="modules.php?name=News"
    method="post">
    Select a Topic:<br>$topics_list</select></form></td>
    </tr></table>
    </div>
    <!-- End of Time for Action -->
  5. Save the header.html file.
  6. Refresh the browser. A polite welcome is displayed to the user:
  7. Building Websites with PHP-Nuke

What Just Happened?

The $theuser variable already contained a message of the form Welcome <username>! However, we wanted a friendlier greeting, so we edited the definition of the $theuser variable in theme.php. The $username variable, used to define $theuser, holds the name of the user, and had been set up earlier in the themeheader() function definition.

After that was done, all we had to do was add a placeholder for the $theuser variable into our template, and we were away.

The introductory Hi was added to the $theuser string because if the user is not logged in, a link to Create an Account is displayed instead. If we had put Hi in the template instead of the variable, it would say Hi Create An Account to a new visitor, which could be rather confusing.

Time For Action—Adding the User Avatar

We've said hello to our user, now let's show the user their face—well, their avatar at least. We will display their avatar underneath the welcome message:

  1. In the theme.php file, add the following code immediately after the line we just modified (shown highlighted—it's in the themeheader() function definition if you have lost track):
    $theuser = "Hi $username!, how you doing?";
    $profile = getusrinfo($user);
    $avatar = $profile['user_avatar'];
    if ($avatar)
    {
    $theuser .= "<br><center>
    <img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original=\"modules/Forums/images/avatars/$avatar\"
    alt=\"Your Face!\"></center>\n";
    }
  2. Save the theme.php file.
  3. Refresh your browser to see the avatar.
  4. Building Websites with PHP-Nuke

What Just Happened?

Extended information about the user is obtained through a call to the getusrinfo() function, passing in the $user variable. The $user global variable holds a limited amount of information about the user, including the username and password, which is used to identify the user and retrieve their profile. This is all done in the getusrinfo() function in the mainfile.php file. This function returns an array of data to us, which we store in an array we call $profile.

The exciting bit of data for us is the avatar entry in our $profile array (accessed through $profile['avatar']). This contains the filename of the user avatar image, and all we have to do is add the path to the avatar images in the Forums module and we have a picture.

If the user isn't logged in, this bit of code won't even be executed, so there is no need to worry about not finding an avatar image for a non-existent user.

Time For Action—Adding a Horizontal Navigation Bar

Now we'll take the first steps towards adding a horizontal navigation bar. These first steps will not produce a very exciting result; we will put the finishing touches to this when we use CSS in the next section.

  1. Open the header.html file, and add the highlighted code as shown below:
    Select a Topic:<br>$topics_list</select></form></td>
    </tr>
    <tr>
    <td colspan="3" >
    <div id="navBar">
    <a href="index.php">Home</a>
    <a href="modules.php?name=Downloads">Downloads</a>
    <a href="modules.php?name=Encyclopedia">Encyclopedia</a>
    <a href="modules.php?name=Your_Account">Your Account</a>
    <a href="modules.php?name=Submit_News">Submit News</a>
    </div>
    </td>
    </tr>
    </table>
    <!-- End of Time for Action -->
  2. Save the file.
  3. Refresh your browser, and your navigation bar will be there:
  4. Building Websites with PHP-Nuke

What Just Happened?

All that we did here was to insert an extra row into the page header table, and then add a couple of links to that row. We had to set the colspan for the td element to 3, since there are three columns in the table, and our row was to have only one column that spans the entire width of the table.

Time For Action—Changing Some Background Colors

There are a couple of global variables defined by the theme that can be used by various modules of PHP-Nuke. Two of these are $bgcolor1 and $bgcolor2. These define background colors, and are used, for example, by the comments navigation bar:

Building Websites with PHP-Nuke

  1. Open the theme.php file in your text editor.
  2. Find the definition of the $bgcolor1 and $bgcolor2 variables:
    $bgcolor1 = "#d5d5d5";
    $bgcolor2 = "#7b91ac";
  3. Change them to the following:
    $bgcolor1 = "#FFCC33";
    $bgcolor2 = "#FFCC99";
  4. Save the theme.php file.

Now view one of the stories on your site, and have a look at the comments navigation bar; the dark and light shades of blue have been replaced by dark and light shades of orange:

Building Websites with PHP-Nuke

What Just Happened?

We set new values for the $bgcolor1 and $bgcolor2 global variables. We set $bgcolor2 to a dark orange and $bgcolor1 to a lighter orange. After making the change, we had a look at the comments navigation bar, which is one place where these background colors are actually used. These variables are also used in the Downloads, News, Statistics, and Web Links modules among others, and are used to control the 'shading' or background color of a number of elements.

Working with the Stylesheet

Now it's time to start making changes to the theme's Cascading Style Sheet (CSS) file, the stylesheet. Using the stylesheet will allow us to move formatting details out of the theme's HTML templates (and PHP code).

However, to prepare the way for using the stylesheet we will sometimes find ourselves having to remove some hardcoded HTML attributes from the templates (or PHP code). We will need to do this because these HTML attributes will override our settings in the CSS file, and our changes to the stylesheet won't be seen. We will also find that, as we move the formatting from the templates and PHP code into the stylesheet, we get greater control over the formatting of our elements. As we make further customizations to our theme in this article, we will move the formatting responsibility to the stylesheet and out of the templates.

Time For Action—Background Image with Style

The first thing we're going to do is set the background image of the page from the CSS file.

  1. Grab the background.jpg file from the SiteImages folder in the code download, and copy it to the themes/TheDinosaurPortal/images folder.
  2. Open the theme.php file in your text editor.
  3. Inside the themeheader() function definition, find the following line:
    echo "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#363636\"
    vlink=\"#363636\" alink=\"#d5ae83\"><br>\n\n\n";
  4. Remove all the attributes after <body, and then remove the <br>, to produce the following:
    echo "<body>\n\n\n";
  5. Save the file.
  6. In the style folder of the theme you will find the style.css file; open this file in your text editor.
  7. Delete the following line:
    BODY        {FONT-FAMILY: Verdana,Helvetica; FONT-SIZE: 10px}
  8. Move your cursor to the end of this file (you may have to move to the right-hand end of the last line in the file and press Enter to create a new line).
  9. Enter the following into the file:
    body {
    color:#000000;
    background-image: url(../images/background.jpg);
    font-family: arial, helvetica, sans-serif;
    font-size: 1em;
    }
  10. Save the style.css file.
  11. Refresh your browser—nothing should have changed!

What Just Happened?

The first three steps were preparing the way for using CSS—we removed the hardcoded HTML attributes from the body tag. We could have set the background image from the line in the themeheader() function with the background attribute of the body tag, but controlling the format of the body tag from the stylesheet will offer us greater flexibility.

Every theme has its own stylesheet, style.css, located in the style subfolder of its folder. To add any CSS information, we make changes there. That's what the remainder of the steps do.

Once we are in style.css, we remove the existing style information for the body tag (step 4). This leaves us a clean slate for creating new style information for this tag.

The new style information—known as properties in CSS parlance—is added in step 9. First of all, we added properties for the body tag:

body {
color:#000000;
background-image: url(../images/background.jpg);
font-family: arial, helvetica, sans-serif;
font-size: 1em;
}

The color property specifies the color of the text used in the body of the document—here we've gone for black (#000000). The background-image property specifies the image used for the body background. The font-family and font-size properties are simple enough. The font-size has been specified using the em units, setting the font-size in relative units.

The path to the background-image property is interesting:

url(../images/background.jpg)

This path is relative to the stylesheet, unlike the path to images used from the templates in the theme, which are relative to the root of our PHP-Nuke installation (like /themes/TheDinosaurPortal/images/logo.gif for example).

To get from the stylesheet (in TheDinosaurPortal/style/style.css) you have to go up a folder (../) bringing you to the TheDinosuarPortal folder, and then into the images folder. Specifying background images using CSS in this way means that you bypass the need for including the name of the theme.

When you view the new page, you will see that much of our background image is obscured by large blocks of white on the page. We need to look into the header.html to find what is responsible for this. In the last few lines of the header.html file you will find:

<table cellpadding="0" cellspacing="0" width="99%" border="0"
align="center"
bgcolor="#ffffff">
<tr><td bgcolor="#ffffff" valign="top">

We need to remove the two bgcolor="#fffff" instances to get:

<table cellpadding="0" cellspacing="0" width="99%" border="0"
align="center" >
<tr><td valign="top">

Then we can resave the header.html file. When you refresh your browser, the background image should be more clearly visible. The bgcolor="#ffffff" attributes we just removed were setting the background color of the main part of the page to white. The table starting at the end of header.html contains the block and module output, and the background image was being hidden by the white background color of this table, which will fill up most of the page when the page is finished.

Time For Action—Changing the Links

In the last task we also removed the definitions for displaying links from the body tag. Now we will add these to the stylesheet:

  1. Open the style.css file in your text editor.
  2. Delete the following four lines (only the first line is shown in full, the other lines contain the same text between the braces):
    A:link          {BACKGROUND: none; COLOR: #000000; FONT-SIZE: 11px; FONT-
    FAMILY: Verdana, Helvetica; TEXT-DECORATION: underline}
    A:active {...}
    A:visited {...}
    A:hover {...}
  3. Move your cursor to the end of this file, and add these lines:
    a {text-decoration:none; color:red; font-weight:bold;}
  4. Save the style.css file, and refresh your browser.

What Just Happened?

We specified a new definition for links in the CSS stylesheet. We removed the line under the link with the text-decoration:none setting, and set the color of a link to red, and made it bold.

Note that we removed four link definitions and replaced them with one. The color of a standard link is defined by a:link, and a:visited takes care of links that have been visited. The behavior of a link as you click on it is determined by a:active. These settings correspond to the values of the link, alink, and vlink HTML attributes we removed from the body tag in theme.php.

The a:hover definition comes into play when you move your mouse cursor over a link and takes care of that link's format. We will make use of that in a moment. For our settings here, we have simply set all links to look the same—using a in the stylesheet rather than a:link, a:active, and so on, means the definition will apply to all links, regardless of whether the visitor is hovering their mouse cursor over the link, or if they have already clicked on that link.

Time For Action—Changing the OpenTable() Function

The OpenTable() and CloseTable() functions defined in tables.php are used to enclose elements on the page, and they are used throughout PHP-Nuke.

  1. In the TheDinosaurPortal folder is a file called tables.php. Open it in your text editor.
  2. Select all the text in this file and delete it.
  3. Add the following text to this file:
    <?php
    function OpenTable()
    {
    echo "\n<table class=\"openTable\"
    cellspacing=\"0\" cellpadding=\"0\" width=\"100%\">
    <tr>
    <td>";
    }
    function CloseTable()
    {
    echo "\n</td>
    </tr></table>
    <br>";
    }
    function OpenTable2()
    {
    echo "\n<table class=\"openTable\"
    cellspacing=\"0\" cellpadding=\"0\" width=\"100%\">
    <tr>
    <td>";
    }
    function CloseTable2()
    {
    echo "\n</td>
    </tr></table>
    <br>";
    }
    ?>
  4. Save the tables.php file.
  5. Open the style.css file and add the following to the end of the file:
    table.openTable {
    border:1px black solid;
    background-color:white;
    padding-top:8px;padding-bottom:8px;
    padding-left:4px;padding-right:4px;
    }
  6. Save the style.css file, view the homepage of your site, and have a look at the message at the top of the middle column:

Building Websites with PHP-Nuke

What Just Happened?

The OpenTable() and CloseTable() functions are used throughout PHP-Nuke to define how elements in the main body of the page are enclosed. The OpenTable() function starts the element, usually a table, and the CloseTable() function finishes it. For our example here, we simply removed all the existing code and started from scratch with the definitions; all we had to do was to define these functions, as well as OpenTable2() and CloseTable2(), which are used less frequently but still need a definition. Note that we have just used the same code for the definition of this pair of functions as we did for the first pair.

OpenTable() starts a new table. This table only needs one column because of its simple design; the table will just hold content; it won't do anything fancy since we already have enough striking elements on our page.

function OpenTable()
{
echo "\n<table class=\"openTable\"
cellspacing=\"0\" cellpadding=\"0\" width=\"100%\">
<tr>
<td>";
}

We mark the table with the openTable class, which we will define in the stylesheet, so we can basically forget about these functions now. We begin the output with a newline \n character, to aid readability of the HTML source.

The CloseTable() function is simple—all it has to do is close the single td element, and then close off the table:

function CloseTable()
{
echo "\n</td>
</tr></table>
<br>";
}

The final step is to create the openTable class in the stylesheet:

table.openTable {
border:1px black solid;
background-color:white;
padding-top:8px;padding-bottom:8px;
padding-left:4px;padding-right:4px;
}

We specified a thin border for the table, (a one-pixel solid-black border), some padding to move the text away from the edge of the table, and a background color of white for the element. Note that specifying the border like this in the stylesheet, rather than using the border attribute of the table tag, gives us a border only around the outside of the table, rather than borders around the cells of the table.

Time For Action—Styling the Navigation Bar

Now we can make our navigation bar actually look good. So far, it just looks like a group of links. A few additions to the stylesheet and it will be transformed.

  1. Open the style.css file in your text editor.
  2. Add the following to the end of the file:
    div#navBar {
    text-align:center; margin:4px;
    font-family:Arial; font-weight:bold;
    }

    div#navBar a {
    color:#000000;
    padding: 5px 4px 5px 5px;
    border: 2px solid #808080;
    background: #cccccc;
    text-decoration: none;
    }

    div#navBar a:hover {
    border-color: #000000;
    color: #ffffff;
    background: #336699;
    }
  3. Save the file, and refresh your browser. The image below shows the mouse being hovered over the Encyclopedia link:
  4. Building Websites with PHP-Nuke

  5. Open the header.html file in your text editor, and make the highlighted change shown below:
    <td colspan="3"
    class="navBarRow">
    <div id="navBar">
  6. Save the header.html file, open the style.css file again, and add this to the end:
    td.navBarRow {
    padding: 6px;
    background-color: #2F5376;
    color: #FFFFFF;
    font-size:14pt;
    font-weight:bold;
    font-family:arial, helvetica, sans-serif;
    margin-left:8px;
    margin-right:8px;
    line-height: 1.5em;
    }
  7. Save the file and refresh your browser.

What Just Happened?

You may recall that when we created the navigation bar, it was wrapped in a div element with an id attribute:

<div id="navBar">

We can use the id of the element so that styles can be applied only to things within it:

div#navBar {
text-align:center; margin:4px;
font-family:Arial; font-weight:bold;
}

The div#navbar syntax means the definition that follows will only be applied to the div element with the id navbar. We do this to center its contents (with text-align:center), set a margin, and define the font.

However, we can continue this syntax to define the style for links contained in the div element:

div#navBar a {
color:#000000;
padding: 5px 4px 5px 5px;
border: 2px solid #808080;
background: #cccccc;
text-decoration: none;
}

This sets the style for a link in our navbar div element. We define the color of the text (black), some padding around the text, a background color (#cccccc, a pale grey), and remove the underlining of links with text-decoration:none;. The other thing we do is set the border for each link. The border is 2 pixel wide, a solid line, and colored #808080, which is a darker grey. This is what gives each link its own little box.

The next definition, div#navBar a:hover, allows the links to behave differently when the mouse cursor hovers over them. This removes the need for any kind of OnMouseOver JavaScript to produce 'roll-over' effects; the stylesheet now takes care of this.

div#navBar a:hover {
border-color: #000000;
color: #ffffff;
background: #336699;
}

Here the definition changes the background colors, text color, and the border color. All the other settings defined by div#navbar a will be 'inherited', so there is no need to specify these settings again.

The final steps added a class attribute to the table column holding the navigation bar, and in the style.css file we set the definition for this class. We added some padding and margins to give the bar some spacing, and set the background color to a dark-blue color (#2F5376).

Changing Blocks

Our next area of customization will be blocks. We will create new blocks in a moment, but first of all we will do some quick customizations to put greater control of the display of blocks into the hands of the theme.

Time For Action—Show Right-Hand Blocks on All Pages

You will notice that the right-hand blocks are not displayed for all modules; they are displayed on the homepage, and also for some modules such as Downloads. Our next change will be to make the right-hand blocks appear on every page, for every module.

  1. Open the theme.php file in your text editor.
  2. Find the themefooter() function definition, and locate the following lines within that piece of code:
    if (defined('INDEX_FILE'))
    {
  3. Change the first line as shown below:
    //if (defined('INDEX_FILE'))
    {
  4. Save the file.
  5. Now open up any module, and your right-hand blocks will be there.

What Just Happened?

The variable INDEX_FILE is set by certain modules when the 'front page' of that module is displayed. The front page is the page displayed when there is no file value in the query string of the URL. On all other pages, INDEX_FILE is not set.

The change we made in the code comments out a check for this value being set. Only if the check is true will the next section of code execute. That section of code is shown below—you will see it contains a call to blocks("right"). This is the function call for displaying the right-hand blocks.

if (defined('INDEX_FILE'))
{
$tmpl_file = "themes/TheDinosaurPortal/center_right.html";
$thefile = implode("", file($tmpl_file));
$thefile = addslashes($thefile);
$thefile = "\$r_file=\"".$thefile."\";";
eval($thefile);
print $r_file;
blocks("right");
}

Since we comment out the check to see if the INDEX_FILE constant is defined, the code enclosed by the braces ({ and }) will always execute, and the blocks will always be displayed.

Time For Action—Hide Right-Hand Blocks For Certain Modules

Now we've got the right-hand blocks on every page. This can be a bit much—the presence of the right-hand blocks can make the page feel rather 'heavy'.

Next we are going to see how to turn off the right-hand blocks for certain modules. For our example, we'll turn off the blocks for the Downloads, Feedback, and Search modules.

  1. Open the theme.php file in your text editor.
  2. Add the highlighted lines of code to the top of the file after the color definitions:
    $textcolor2 = "#000000";
    global $packt_hideRightBlocks;
    $packt_hideRightBlocks = array('Downloads'=>1,'Feedback'=>1,
    'Search'=>1);
    if(file_exists("themes/TheDinosaurPortal/tables.php")){
  3. Find the line we commented out in the previous task in the themefooter() function definition.
  4. Add the following two lines of code between the commented line and the brace:
    // if (defined('INDEX_FILE'))
    global $packt_hideRightBlocks, $module_name;
    if (!$packt_hideRightBlocks[$module_name])
    {
  5. Save the theme.php file.
  6. In your browser, check that the right-hand blocks are displayed on the homepage and on the Topics module page, but not on the Downloads, Search, and Feedback pages.

What Just Happened?

We created a global variable, $packt_hideRightBlocks at the top of the theme.php file. This variable is an array, and contains entries for the names of the modules that we will hide the right-hand blocks for. If we want the right-hand blocks shown for a particular module, we do not include it in the array.

We added the prefix packt_ to the variable name in order to avoid potential clashes with other global variables. The definition of the array shows we want to hide the right-hand blocks for the Downloads, Feedback, and Search modules.

Note that we had to put a global prefix before the definition of the $packt_hideRightBlocks statement to declare it as a global variable. We had to explicitly declare this variable as global because otherwise the variable will be scoped to the function that included the theme.php file, and this is the head() function in the header.php file. (This file is in the root of the PHP-Nuke installation, and is not part of a theme.) We'll talk more about this file later.

The idea now is simple—we need to get the name of the current module, and then see if there is an entry for that in our array. If there is, we won't display the right-hand blocks.

We are able to add code to the themefooter() function at just the point we were working with in the previous task. First we add the global statement, to access the $packt_hideRightBlocks and $module_name global variables from our function. The $module_name global variable is defined by the 'core' of PHP-Nuke, and contains the name of the current module.

Next we check if there is an entry in the $packt_hideRightBlocks array with the name of $module_name.

if (!$packt_hideRightBlocks[$module_name])

In fact, the code actually checks that there isn't such an entry—the ! character in front of the check means 'not'. If there is no such entry, then the code to display the right-hand blocks will be executed. Thus only a module whose name is not in the $packt_hideRightBlocks array will have right-hand blocks displayed.

  • If you want to turn off this feature, and have all the right-hand blocks displayed for all modules, simply comment out the if statement line.
  • If you want to use this feature to only show blocks for certain specified modules, change the check to the following:
    if ($packt_hideRightBlocks[$module_name])

    Now the right-hand blocks will only be shown for modules whose name is in the $packt_hideRightBlocks array.

It is also very easy to apply this method to handle the left-hand blocks. All you'd need is to set up an array called $packt_hideLeftBlocks, similar to our $packt_hideRightBlocks array, and then apply the same code to themeheader() function before the blocks("left") function call. Make sure you have some alternative form of navigation if you turn off the left-hand blocks—you could well have removed the Modules menu block!

Time For Action—Making the Block Titles Uppercase

Let's continue tweaking the block display:

  1. Open the theme.php file in your text editor, and find the themesidebox() function definition.
  2. Add the highlighted line immediately after the first line of the function definition:
    function themesidebox($title, $content) {
    $title = strtoupper($title);
  3. Save the theme.php file.
  4. Refresh your browser, and you will note your block titles are now in uppercase.

What Just Happened?

The themesidebox() function controls the display of blocks. It simply grabs the blocks.html template, processes it, and spits out the result, producing a block. This function is called whenever any part of the application wants a block drawn.

The block title is held in the $title variable, and all we did was use the PHP strtoupper() function to convert the current title into uppercase. After that, the block display carries on as usual.

Time For Action—Creating a New Block

Now we've got blocks all over our page—but they're not 'our' blocks. Well, not yet. Our next job is to create a new block design. Now we will really feel that we are stamping our identity on our site.

  1. You will need to grab the blockTop.gif, blockBottom.gif, and blockBackground.gif files from the SiteImages folder in the code download and copy them to the images folder in the TheDinosaurPortal folder.
  2. In the theme folder, you will find the blocks.html file. Open it in your text editor.
  3. Delete the existing code, and enter this new code:
    <table width="176px" cellspacing=0>
    <tr height="28">
    <td background="themes/TheDinosaurPortal/images/blockTop.gif">
    </td>
    </tr>
    <tr>
    <td background="themes/TheDinosaurPortal/images/blockBackground.gif">
    <div class="blockTitle">$title</div>
    </td>
    </tr>
    <tr>
    <td background="themes/TheDinosaurPortal/images/blockBackground.gif">
    <div class="blockContent">$content</div>
    </td>
    </tr>
    <tr height="28">
    <td background="themes/TheDinosaurPortal/images/blockBottom.gif">
    </td>
    </tr>
    </table>
    <br>
  4. Save the blocks.html file, and refresh your browser. The blocks should have changed:
  5. Building Websites with PHP-Nuke

  6. Now open the style.css file in your text editor.
  7. Add the following style definitions to the end of the file:
    div.blockContent {
    margin-left:8px; margin-right:8px;
    padding-bottom:8px; padding-top:8px;
    padding-left:0px; padding-right:0px;
    }

    div.blockTitle {
    background: #ffffff;
    margin-left:8px; margin-right:8px;
    color:black;
    padding-top:2px; padding-bottom:2px;
    font-size:1.2em; font-weight:bold;
    font-family:arial, verdana;
    text-align:center;
    }
  8. Save the style.css file, and refresh your browser. You'll see this:
  9. Building Websites with PHP-Nuke

Building Websites with PHP-Nuke A practical guide to creating and maintaining your own community website with PHP-Nuke
Published: November 2005
eBook Price: $20.99
Book Price: $29.99
See more
Select your format and quantity:

What Just Happened?

The blocks.html file is the template used for displaying blocks. It uses two placeholders, $title and $content, which contain the title and content of the block respectively.

Our block consists of a single HTML table, set to a width of 176 pixels:

<table width="176px" cellspacing=0>

The cellspacing is set to 0 so that all the rows are right next to each other, and no gaps appear between the rows.

The table consists of four rows, one row for the top (header) image of the block, one row for the block title, one for the block content, and one for the block footer image. Note that the image for the bottom row is the just a vertical flip of the top-row image.

The height of the top row is specified exactly as the height of its background image. This is to make sure that the entire background image is shown, since it must link up with the background image for the middle row.

<tr height="28">
<td background="themes/TheDinosaurPortal/images/blockTop.gif" ></td>
</tr>

The next row shown displays the block title. This will be held in the $title placeholder. Note that we wrap the title in a div element with a class of blockTitle, so we can defer fine tuning of its look to the CSS file.

<tr>
<td background="themes/TheDinosaurPortal/images/blockBackground.gif">
<div class="blockTitle">$title</div>
</td>
</tr>

The next row displays the block content. This will be held in the $content placeholder. Again, we wrap the content in a div to take care of the styling in the CSS file.

<tr>
<td background="themes/TheDinosaurPortal/images/blockBackground.gif">
<div class="blockContent">$content</div>
</td>
</tr>

Finally, the block footer. This is constructed in the same way as the block header.

<tr height="28">
<td background="themes/TheDinosaurPortal/images/blockBottom.gif"></td>
</tr>
</table>

The <br> at the end of the block adds a line break after the block, getting things ready for the next block to be displayed.

The styling for the block title and content is done in the style.css file. For the block content, we are only concerned with some spacing around the edges:

div.blockContent {
margin-left:8x; margin-right:8px;
padding-bottom:8px; padding-top:8px;
padding-left:4px; padding-right:4px;
}

The left- and right-hand margins are set so as to ensure that the text is far enough from the edge of the image, and inside the thick black border of the block.

For the block title, we set its background color to white, and centered the text with the text-align property.

Time For Action—Making Right-Hand Blocks Different from Left-Hand Blocks

At the moment, a block is a block, wherever it is displayed. Here we'll show a simple way to choose a different template for the right-hand blocks, and so give you the opportunity to have the right-hand blocks look different from those on the left-hand side of the page.

For our example we will use the same template as the left-hand blocks, except our background images will be horizontal flips of the existing images.

  1. Grab the files blockBottomRH.gif, blockTopRH.gif, and blockBackgroundRH.gif from the SiteImages folder of the code download and copy them to the images folder of our theme.
  2. Open the blocks.html file in your text editor, and replace the word blockBottom with blockBottomRH, replace blockTop with blockTopRH, and replace blockBackground with blockBackgroundRH.
  3. Save the file as blocks_right.html in the folder of your theme.
  4. Open the theme.php file in your text editor.
  5. Add the highlighted lines to the top of your file:
    define("BLOCKSIDE_LEFT", 0);
    define("BLOCKSIDE_RIGHT", 1);
    global $packt_blockSide;
    $packt_blockSide = BLOCKSIDE_LEFT;
    if(file_exists("themes/TheDinosaurPortal/tables.php")){
    include("themes/TheDinosaurPortal/tables.php");
  6. Go to the themesidebox() function definition.
  7. Change the code as below:
    function themesidebox($title, $content)
    {
    $title = strtoupper($title);
    global $packt_blockSide;
    if ($packt_blockSide==BLOCKSIDE_RIGHT)
    $tmpl_file = "themes/TheDinosaurPortal/blocks_right.html";
    else
    $tmpl_file = "themes/TheDinosaurPortal/blocks.html";
  8. In the themefooter() function, add the highlighted lines above the call to blocks("right"):
    global $packt_blockSide;
    $packt_blockSide = BLOCKSIDE_RIGHT;
    blocks("right");
  9. Save the theme.php file.
  10. Refresh your browser, and compare a left-hand side block with a right-hand side block.

What Just Happened?

To make the left- and right-hand blocks different, first we had to define a new template for the right-hand block. We did this by editing the standard block template, blocks.html, and creating a new file, which we called blocks_right.html. The only difference between those two files is the different background images used; each image used for this block is simply a horizontal flip of the corresponding image for the block we created above.

With our new block template in place, we needed to create a mechanism for switching between left- and right-hand blocks. The global variable $packt_blockSide will be used to do this—a value of 0 means that left-hand block and a value of 1 means right-hand block. We defined two PHP constants, BLOCKSIDE_LEFT with the value 0 and BLOCKSIDE_RIGHT with the value 1:

define("BLOCKSIDE_LEFT", 0);
define("BLOCKSIDE_RIGHT", 1);

This was done for convenience—later in the file we will want to check the value of packt_blockSide, and rather than trying to remember if 0 means left or right, we can use the constants. Before that, we have to set the value of the $packt_blockSide variable:

global $packt_blockSide;
$packt_blockSide = BLOCKSIDE_LEFT;

Now we come to actual switching of the block templates. This goes on in the themesidebox() function:

if ($packt_blockSide==BLOCKSIDE_RIGHT)
$tmpl_file = "themes/TheDinosaurPortal/blocks_right.html";
else
$tmpl_file = "themes/TheDinosaurPortal/blocks.html";

If the $packt_blockSide variable is indicating a right-hand block, the right-hand block template is chosen, otherwise the standard block template is chosen. The template to be processed for the block is determined by the $tmpl_file variable, and simply switching its value like this means a different template will be used.

We're almost there—but we still haven't actually done anything to trigger the change in the $packt_blockSide variable, which will in turn lead to a different template. We'll do this in the themefooter() function. This function manages the display of the right-hand part of the page, including the right-hand blocks. On the line before the function call to display these blocks, we change the value of $packt_sideBlock:

global $packt_blockSide;
$packt_blockSide = BLOCKSIDE_RIGHT;
blocks("right");

Now the processing takes this form—the blocks() function will call the themesidebox() function to display each block. In the themesidebox() function the variable $packt_blockSide is checked, and if it has the value 1 (represented by the BLOCKSIDE_RIGHT constant) the right-hand block template is chosen, processed, and displayed.

We save the file, and we are ready to roll with our two types of blocks!

Changing Story Layout

In this section we will change the formatting of stories. First of all, we will change the format of the story summary that is displayed on the homepage. After that, we will change the format of the extended view of the story, which is viewed when clicking on the Read More... link of the story summary.

Creating a Rounded Box

We're going to take a moment to cover a simple technique for producing a pretty cool effect—an HTML 'box' with rounded corners:

Building Websites with PHP-Nuke

This box can be used to house a block, but we will be using it to decorate the stories on the homepage of our site. We can even use only half of the box to easily create a rounded tab that could be used in a navigation bar!

The technique we will cover here is pretty simple; it will make use of some simple images, and some CSS properties to achieve the effect. You will find several CSS tutorials on the Web that also cover this topic, producing more robust and fancier effects.

The plan is very simple—we color in a table with a background color, and then we 'eat' chunks out of the four corners of the table, thus giving the rounded effect.

The chunks will be 'eaten' by using four tiny 'rounded' images, which we will create first. In fact, we will create only one image, and then through a combination of 'flips', proceed to produce all of the images we need.

Creating the Corner Images

The image below shows the 8x8 image we will use as our corner-removing chunk. It was originally created from cutting out the corner of a rounded box drawn in Photoshop. However, the image is small enough that you could create one like this pixel by pixel!

Since the picture we show here is in black and white, it is worth noting that the unshaded areas in the screenshot are actually the transparent areas of the image. The pixels shown in black in this picture will actually be white in the image.

Building Websites with PHP-Nuke

Now that we have our basic image, we ensure that the unshaded area is set to transparent, and save this file as corner-tl.gif in the images folder of our theme. You should refer to the documentation of your graphics package if you are unsure how to set part of an image as transparent.

We are now ready to generate the three other corner images:

  1. Make sure that the corner-tl.gif file is open in your graphics package.
  2. In your graphics package, flip the image horizontally to produce the top-right corner image. Save this image as corner-tr.gif in the images folder of the theme.
  3. Now flip this image vertically to produce the bottom-right corner image. Save it as corner-br.gif in the images folder of the theme.
  4. Finally, flip this image horizontally to produce the bottom-left corner image, and save it as corner-bl.gif in the images folder of the theme.

Stage one is complete; we have the four corner images.

Creating the HTML

The HTML is not complex, so we will create that next. The guts of this technique are contained in the CSS information, which we will move on to in a moment.

First of all, create a file called rounded_box.html in the theme folder, and enter the following:

<html>
<head>
<link rel="stylesheet" href="style/style.css" type="text/css">
</head>
<body>
<table class="roundedbox" cellspacing=0 cellpadding=0>
<tr><td class="cornertl"></td><td></td><td class="cornertr"></td></tr>
<tr><td></td><td >THIS IS WHERE THE CONTENT GOES!!!</td><td></td></tr>
<tr><td class="cornerbl"></td><td></td><td class="cornerbr"></td></tr>
</table>
</body>
</html>

The HTML is not complex as you can see. For the purposes of our example, we have added a reference to the theme stylesheet in the file with the <link> tag.

The rounded box consists of a table with three rows, with each row having three columns.

The table has a CSS class called roundedbox. We'll look at this in a moment when we tackle the CSS, but all this CSS class will do is set the background color of the table. This will fill in the entire table with a particular color. This sets us up to use our little images to eat the corner chunks out.

The first row in the table will be used for the top-left and top-right corners. The first column of this row is defined like this:

<td class="cornertl"></td>

attribute class and the absence of anything else in the element means that all the work will be done by the CSS class cornertl, which we will see in a moment.

 

The third column in the first row is defined similarly:

<td class="cornertr"></td>

Another class is used here, and from its name, you can see that it will have something to do with the top-right corner. The middle column in the first column is left blank.

The second row is where the body of the box will go. The first column is left blank since that 'belongs' to the top-left and bottom-left corners. The third column is also left blank, since that belongs to the top-right and bottom-right corners. The middle column is where all the action takes place. We've just added some basic text for now.

The last row is similar to the first row, with a CSS class used in the first column and its last column:

<tr><td class="cornerbl"></td><td></td><td class="cornerbr"></td></tr>

The middle column is again left blank.

That's all there is to the block. This HTML does not look at all interesting at the moment; this shot of it in an HTML editor gives you a clearer picture of the layout of the table:

Building Websites with PHP-Nuke

However, there is no sign of corners yet, nor any reference to any of the images we created earlier.

All will now be made clear.

Creating the CSS

The real magic of this technique happens in the CSS definitions. In the HTML we have used four classes, cornertl, cornertr, cornerbr, and cornerbl, and it is clear that in some way these are going to be used to display the images we created above. The answer is the set of CSS background properties. These allow you to control the background color of an element, set an image as the background, repeat a background image vertically or horizontally, or position the background image.

You can read more about the background properties at http://www.w3schools.com/css/ css_background.asp.

Open the style.css file in the styles folder of the theme, and add these lines to the bottom of the file:

td.cornertl {
background-image: url('../images/corner-tl.gif');
background-repeat: no-repeat;
background-position: top left;
width: 8px; height: 8px;
}

This defines our CSS class cornertl. Let's walk through the properties that we have used.

First of all, the background image is set with the background-image property. We will use our top-left image for this background. (It is the image that has the top-left colored in, while the rest of the image is transparent.)

background-image: url('../images/corner-tl.gif');

This image should only be displayed once in this element—if this background image is shown over and over again then it will look rather strange (it will look like a collection of humps), so we use the background-repeat property to ensure that the image is displayed only once:

background-repeat: no-repeat;

The background-position property is used to position the image within the element, its value is obvious:

background-position: top left;

Finally, we set the width and height of the td element to ensure that it does not grow; this would become rather awkward for our design.

width: 8px; height: 8px;

All we have to do now is define cornertr, cornerbr, and cornertl similarly in the file. The definitions are very similar; we have highlighted the different lines:

td.cornertr {
background-image: url('../images/corner-tr.gif');
background-repeat: no-repeat;
background-position: top right;
width: 8px; height: 8px;
}

td.cornerbr{
background-image: url('../images/corner-br.gif');
background-repeat: no-repeat;
background-position: bottom right;
width: 8px; height: 8px;
}

td.cornerbl{
background-image: url('../images/corner-bl.gif');
background-repeat: no-repeat;
background-position: bottom left;
width: 8px; height: 8px;
}

For each class, we simply specify the corresponding corner image with the background-image property, and the background position with the background-position property. The value of the background-position could not be more intuitive!

The final stroke is to add the class to fill the table with a background color:

table.roundedbox { background: #cccccc; }

Now save the file and open the rounded_box.html file in your browser:

Building Websites with PHP-Nuke

This isn't particularly setting the world on fire, but let's apply the technique.

Time For Action—Change the Format of Stories on the Front Page

Changing the way a story is displayed on the front page of the site involves creating a new template. That's exactly what we'll do now.

  1. Open the story_home.html file in your text editor, and delete all the text. Enter the following into the file:
    <table class="storyBack" width="100%" cellspacing=0 cellpadding=0>
    <tr>
    <td class="cornertl"></td><td></td><td class="cornertr" width="10"></td>
    </tr>
    <tr>
    <td></td><td class="storyTitle">$title</td><td></td>
    </tr>
    <tr height=6><td colspan=3></td></tr>
    <tr>
    <td></td>
    <td>
    <table cellSpacing="0" cellPadding="4" border="0" width="100%">
    <tr>
    <td valign=top class="Normal" width="25%" bgcolor="#ff9933">
    <center><img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="$t_image" align="middle" border="1"></center></td>
    <td valign=top class="Normal" width="75%">$posted $content</td>
    </tr>
    <tr valign=top><td colspan="2" align="right"><hr>$morelink</td></tr>
    </table>
    </td>
    <td></td>
    </tr>
    <tr>
    <td class="cornerbl"></td><td></td>
    <td class="cornerbr" width="10"></td>
    </tr>
    </table>
    <br>
  2. Save the file.
  3. Open the style.css file in the style folder, and add the following at the end of the file:
    table.storyBack {
    background: #ffcc33;
    }
    .storyTitle {
    padding-left: 6px; padding-right:6px;
    padding-top:6px; padding-bottom:6px;
    background-color: #2F5376;
    color: #FFFFFF;
    font-size:14pt; font-weight:bold;
    font-family:arial, helvetica, sans-serif;
    margin-left:8px; margin-right:8px;
    line-height: 1.5em;
    }
    .storyCat {
    color: #FFFFFF;
    font-size:14pt;
    font-weight:bold;
    font-family:arial, helvetica, sans-serif;
    }
  4. Save the file.
  5. Return to the homepage of your site. The stories will now look like this:

Building Websites with PHP-Nuke

What Just Happened?

The story_home.html file is the template for stories displayed on the homepage. We removed all of the existing content and replaced it with our new definition. The story_home.html template is processed by the themeindex() function in theme.php, although we did not work with any of the code in this example.

The template we created is based around the HTML we put together in the previous section for the rounded box. We added two rows to that table:

<tr>
<td></td><td class="storyTitle">$title</td><td></td>
</tr>
<tr height=6><td colspan=3></td></tr>
<tr>

The first row will display the story title through the $title placeholder, and the next row is to add a bit of space before the main part of the template. After that, we have an inner table, which is effectively placed where the THIS IS WHERE THE CONTENT GOES!!! text was in the example from the previous section.

The inner table has two columns, one for displaying the topic image and the other for showing the story text:

<table cellSpacing="0" cellPadding="4" border="0" width="100%">
<tr>
<td valign=top class="Normal" width="25%" bgcolor="#ff9933">
<center><img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="$t_image" align="middle" border="1"></center></td>
<td valign=top class="Normal" width="75%">$posted $content</td>
</tr>
<tr valign=top><td colspan="2" align="right"><hr>$morelink</td></tr>
</table>

The $t_image placeholder is used to get the path to the topic image, and the $posted placeholder holds text about who posted the story, and when it was posted. The story text itself is contained in the $content placeholder.

The last line of the table outputs the navigation bar with the Read More... link, the number of comments, and so on. This is all contained in the $morelink placeholder.

After creating the template, we add some styles to the style.css file, storyBack, storyTitle, and storycat. The storycat style is not actually used in the template, it is already part of the $title placeholder. This style holds the definition for the category name that is displayed before the story title. The storyBack style sets the background color of the whole element. The storyTitle style is used to format the title bar, and we specify a dark blue background color (#2F5376), large white text, and plenty of space around the text with the padding settings.

Variables Available in Story Formatting

We saw a couple of the placeholders that can be used in formatting the story output. There are several others that can be used in the story_home.html template by default:

Placeholder

Description

$title

The title of the story.

$thetext

The short description of the story.

$aid

The name of the administrator who posted the story to the site.

$informant

The username of the story creator.

$datetime

The date the story was posted.

$posted

Uses $aid, $time, and $timezone to produce text of the form Posted on <time> <timezone> by <name of administrator>, and also mentions the number of times the story has been read (provided by $counter).

$content

The summary text ($thetext) of the story, prefixed by <name of the story creator> writes, and with any notes for the story attached on the end.

$t_image

The path to the topic image.

$topictext

The full title of the topic.

$counter

The number of times the story has been read.

$notes

Any notes added by the administrator when the story was posted.

This is not a variable passed to the function, but can be accessed with a global statement.

$time

The time the story was posted. The variable $timezone contains the author's timezone.

Changing the Layout of the Story Extended View

To change the layout of a story's extended view, you change the story_page.html template. Our new story_page.html template is below, and it is similar to the story_home.html template. The main differences are shown highlighted:

<table class="storyBack" width="100%" cellspacing=0 cellpadding=0>
<tr>
<td class="cornertl"></td><td></td><td class="cornertr"
width="10"></td>
</tr>
<tr>
<td></td><td class="storyTitle">$title</td>
<td></td>
</tr>
<tr height=6><td colspan=3></td></tr>
<tr>
<td></td>
<td >
<table class="openTable" width="100%">
<tr><td> <span style="float:right;">
<img src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="$t_image" align="middle" border="1"
alt="$topictext"></span>
$content</td>
</tr>
</table>
</td>
<td></td>
</tr>

<tr>
<td class="cornerbl"></td><td></td>
<td class="cornerbr" width="10"></td>
</tr>
</table>

This time, we use to have the topic image positioned on the right of the table, with the text flowing to the side of it.

The story_page.html template is processed by the themearticle() function in theme.php. This function has similar variables to those shown in the table for the themeindex() function, although in themearticle(), the $thetext variable actually contains the story introduction and the story extended text.

You will note that the same placeholder, $content, is used in both the story_home.html and story_page.html templates. In story_home.html, it holds the short description of the story, and in story_page.html, it holds the short description plus the extended text.

There are some lines in themearticle() that are worth noting, since they determine the whether the creator's name is added to the start of the story:

if ("$aid" == "$informant")
{
$content = "$thetext$notes\n";
}
else
{
if($informant != "")
{
$content = ".....";
}
else
{
$content = "$anonymous ";
}
$content .= ""._WRITES." <i>\"$thetext\"</i>$notes\n";
}

If the author who posted the story ($aid) is the same as the user who wrote the story ($informant), then the content of story is just the story description, story extended text, and any notes for the story. There is no mention of the story creator or who posted the story in the $content variable if the story creator is the same as the administrator who posted the story to the site.

If the story was written by someone other than the administrator, the content of the story becomes <username> writes, and then the story description, story extended text, and any notes for the story are enclosed in quotes and are put into italics. If the story was not submitted anonymously, a link to the Your Account details of the story creator is created for the user name. (We have replaced that part of the code with ..... for brevity here.)

If you want to change the way the extended text view of the story is displayed, going beyond what the template can do, these lines in themearticle() are a good place to start.

Changing the Footer

The footer is the last part of the theme. The footer template is the footer.html file, and we will create a new template for it, based on the table that we created for OpenTable(). Here is the new footer template:

</td></tr></table>
<br>
<center>
<table class="openTable" cellspacing="0" cellpadding="0"
width=\"50%\">
<tr>
<td align="center">$footer_message</td>
</tr>
</table>
<center>

The first line closes off the table that was started at the end of header.html; without it, our page would not look right. After that, we create a new table with the openTable class that we defined for the table in the OpenTable() function earlier. This table will be centered in the page, and have a width of 50% of the page:

Building Websites with PHP-Nuke

There is only one placeholder in this template, $footer_message. This contains the copyright message, which must be displayed in order to comply with PHP-Nuke's license.

Our theme is complete!

Adding a Favicon

A Favicon is a small image displayed in the navigation bar of the browser, and also in the list of bookmarks:

Building Websites with PHP-Nuke

The Favicon is not something we can actually control with the theme, but it is the finishing touch for the site, and it does lead us into another interesting area of PHP-Nuke customization. Favicons behave rather strangely in Internet Explorer, and you will find that you need to add a site to your Favorites before the Favicon is displayed.

First of all, the Favicon is an image in a special format, ICO format. The file consists of a couple of copies of the same image at different sizes (16x16 and 32x32 usually). We will need to convert any standard graphical image we plan to use to this format before we continue.

You can download a free command-line tool to convert from PNG files to ICO files here:

http://www.winterdrache.de/freeware/png2ico/

There is an executable version of the application for Windows there, and instructions on how to use it. For other platforms you will have to compile the code yourself.

In the code download, there is a file called favicon.ico in the SiteImages folder that has already been converted. This should be copied to the images folder in the root of your PHP-Nuke installation.

All that remains now is to add a link to this file. This link is not something that is handled by the theme, since it goes between the <head> and </head> tags of the document, which are beyond the control of the theme.

What we need to do is open our text editor, and enter the following code into a blank document:

<?php
echo "<link rel=\"SHORTCUT ICON\" href=\"images/favicon.ico?\">\n";
?>

The output of this file is the HTML required for the browser to download and display the Favicon. The location of the Favicon is indicated by the href attribute.

custom_head.php in the folder includes\custom_files in the root of the PHP-Nuke installation.

 

Now when you refresh your browser, the Favicon will be displayed in the browser bar:

Building Websites with PHP-Nuke

Including Custom Files

The \includes\custom_files folder can hold files with specific names that PHP-Nuke can process at various points. The advantage of this approach is that you can throw your code into the PHP-Nuke core 'mix' without having to hack its inner workings. This folder was new in PHP-Nuke 7.6. In earlier versions, you could use the my_header.php file in the includes folder to achieve similar results, but the custom_files folder in PHP-Nuke 7.6 introduced greater flexibility.

  • Anything output from the custom_head.php file will be added between the <head> and </head> tag of the document.
  • Anything output from a file called custom_header.php will be added to the output from the header.php file. This means it will be output after the </head> tag and before the theme kicks in. Similarly, anything output from the custom_footer.php file will be added to the output from the footer.php file.
  • Any code in a file called custom_mainfile.php will be executed before any of the code in the mainfile.php file.

Page Output from Start to Finish

We've made many changes to customize a theme in this article, and now we are ready for a detailed overview of exactly how the theme controls the appearance of a page.

The theme doesn't start the page output. The page output process is started by the module that is currently in action at that point. Every part of every module that wants to display a standard page will have code like this:

include("header.php");
...
include("footer.php");

Page output actually starts in a function called header(), which is in the header.php file. The module won't call this function directly; within the header.php file is the call to the header() function, and simply including the file will get things started.

First of all, the header() function creates the META tags and TITLE tag, adds links to the required stylesheet (this is by default the style.css file in the style folder of the current theme), and opens the HTML tag.

Now the fun really starts. header() now makes the first call to one of the theme functions, themeheader() in theme.php; and the theme has come into play.

When themeheader() is executed the following happens:

  • The body tag is opened.
  • Any advertising banners are displayed.
  • The header.html template is processed and displayed. Usually the header.html template finishes by starting a new table to hold the main page content, and starts a column in that table.
  • The left-hand blocks are rendered into this column. The themesidebox() function is called to display each block.
  • The left_center.html template is processed. This closes the column started earlier. For some themes, it adds a 'padding' column. Then the column that will hold the module content is started.

Now the module continues with its activities, outputting its content, probably wrapping it with the OpenTable() and CloseTable() functions found in the tables.php file. After it has finished, to close the page up the module includes the footer.php file. In footer.php is a function called footer(). Similar to header.php, the footer() function is called from within the footer.php file.

The footer() function calls the themefooter() function, and the following happens:

  • The center_right.html template is processed. The main column is closed; a padding column is possibly added and a new column is started.
  • The right-hand blocks are rendered. The themesidebox() function is called to display each block.
  • The footer.html template is processed. It closes a column (there will be one column still left open at that point), and then renders the page footer message.

After the call to themefooter(), the final throes of the footer() function are to close the body tag and the page's HTML tag. The body tag was opened in the themeheader() function, but is not actually closed in the theme.

Note that the themeindex() and themearticle() functions in the theme are only involved when the News module is in action, and are not part of the general page output process.

Summary

We have transformed the look of the Dinosaur Portal in this article from a standard looking PHP-Nuke installation to a very distinctive looking site. To do this, we started with the 3D-Fantasy theme and gradually added our new design.

We met the main ingredients of a theme, the PHP code files theme.php and tables.php, and the HTML templates that determine how a particular part of the page will look. We saw how the templates and the PHP code interact, and how they are used to separate the design of the theme from the PHP code that drives it.

We changed the page header, adding a new banner, and then a simple navigation bar. Then we looked at using the CSS stylesheet, the style.css file in the style folder of the theme, to make formatting changes independently of both the template and the PHP files.

After that, we looked at blocks in the theme. In particular, we saw how to create a new block. We saw how to create a rounded box, and put this to use for formatting the stories on the homepage of the site.

The final activity of the article was to add a Favicon to the site, which is not actually part of the theme's responsibility, but it rounds off the customization nicely.

[ 1 | 2 |3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 ]

If you have read this article you may be interested to view :

About the Author :


Douglas Paterson

Douglas Paterson is a full-time acquisition editor and part-time author for Packt Publishing. He is a doctor of Mathematics and has over five years experience of working on programming books across a number of different subjects. He lives in Birmingham, England, with his wife, and his unusually hairy dog, Zak.

Contact Douglas Paterson

Books From Packt

Magento 1.3 Sales Tactics Cookbook
Magento 1.3 Sales Tactics Cookbook

MySQL Admin Cookbook
MySQL Admin Cookbook

PHP 5 E-commerce Development
PHP 5 E-commerce Development

Plone 3.3 Site Administration
Plone 3.3 Site Administration

Grok 1.0 Web Development
Grok 1.0 Web Development

NetBeans Platform 6.8 Developer's Guide
NetBeans Platform 6.8 Developer's Guide

CMS Made Simple 1.6: Beginner's Guide
CMS Made Simple 1.6: Beginner's Guide

Drupal 6 Performance Tips
Drupal 6 Performance Tips

Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software