14.3. Modifying the PHP-Nuke theme header

The theme header is constructed in the function themeheader() of the theme in question. You will find this function in the file theme.php, in the folder themes/YourTheme (where YourTheme is the name of your theme, e.g. themes/NukeNews).

14.3.1. How to create a top navigation bar as in NukeNews theme

Figure 14-3. Top navigation bar in the NukeNews theme.

Top navigation bar in the NukeNews theme.

Sometimes, like in the case of the NukeNews theme, the themeheader() function will include the contents of a separate file, written in pure HTML:

    $tmpl_file = "themes/NukeNews/header.html";
    $thefile = implode("", file($tmpl_file));
    $thefile = addslashes($thefile);
    $thefile = "\$r_file=\"".$thefile."\";";
    eval($thefile);
    print $r_file;

The header.html file, which is "evaluated" here, contains HTML code that creates the "top navigation bar", the one with the "Home", "Topics", "Downloads", "Your Account" etc. links (Figure 14-3):

<tr valign="middle" bgcolor="#dedebb"> 
<td width="15%" nowrap><font class="content" color="#363636"> 
<b>$theuser</b></font></td> 
<td align="center" height="20" width="70%"><font class="content"><B> 
<A href="index.php">Home</a> 
·
<A href="modules.php?name=Topics">Topics</a> 
·
<A href="modules.php?name=Downloads">Downloads</a> 
·
<A href="modules.php?name=Your_Account">Your Account</a> 
·
<A href="modules.php?name=Submit_News">Submit News</a> 
·
<A href="modules.php?name=Top">Top 10</a> 
</B></font>
</td>
<td align="right" width="15%"><font class="content"><b> 
<script type="text/javascript"> 
<!--   // Array ofmonth Names 
var monthNames = new Array(
"January","February","March","April","May","June","July","August","September",
"October","November","December"); 
var now = new Date();
thisYear = now.getYear(); 
if(thisYear < 1900) {thisYear += 1900}; // corrections if Y2K display problem 
document.write(monthNames[now.getMonth()] + " " + now.getDate() + ", " + thisYear); 
// -->
</script></b></font></td> 
<td> </td>
</tr>

Thus, if you want to delete or change this top navigation bar, you will have to delete or change the above code to reflect your needs (see How to change the top menu (top navigation bar) of PHP-Nuke and how to remove the search box from the top menu of PHP-Nuke). A similar technique is used in the Odyssey theme, where one uses the contents of themes/Odyssey/left_center.html, additionally to themes/Odyssey/header.html.

14.3.2. How to insert a Search Box as in SlashOcean theme

The SlashOcean theme contains a Welcome message and a Search box in its header, as a close inspection of the code in the themeheader() function of themes/SlashOcean/theme.php reveals:

echo "<br>
<center>
<table cellpadding=0 cellspacing=0 border=0 width=99% align=center><tr><td align=left>
<a href=$nukeurl><img src=themes/SlashOcean/images/logo.gif Alt=\"Welcome to $sitename\"
border=0></a>
</td><td align=right width=100%>
        <form action=modules.php?name=Search&amp;method=post>
        <font class=content><input type=text name=query width=20 size=20 length=20>
        </td>
        <td align=right>&nbsp;&nbsp;<input type=submit value=\""._SEARCH."\"></td>
        </form>";
    echo "</td></tr></table><br>";

You can use this code if you wish to have a search box besides your logo, as in SlashOcean. You will find similar constructs in the other themes, e.g. Kaput or Slash.

14.3.3. How to change the PHP-Nuke header depending on some global feature

In some cases you may need to change the PHP-Nuke header according to some globally available information about the current user. For example, you may want to display a menu that is differently structured if the user's language is, say, french, leaving the standard menu structure untouched otherwise.

The key to such changes is always to declare the globally available feature as being “global” in the themeheader() function in theme.php. Then you can use its value for a simple check that will echo the right HTML incantations if the check succeeds. Let's take for example the above case, where the globally available feature is nothing else but the current language setting:

global $currentlang;
if ($currentlang == "french") {
  echo "<a href=\"/special/link/to/my/services/for/french/users\"><b>"
  ._MESSERVICES."</b></A>\n";
}
else if ($currentlang == "english") {
  echo "<a href=\"/some/default/link/for/other/users\">"
  ._DEFAULTLINK."</a>\n";
}

This code, put in the themeheader() function of theme.php in the aproppriate place (depending on where exacly you want it to appear), will display a special menu link if the user's language is french. Instead of the current language, any user setting that is globally available can be used. The only work you have to do is to find out which variable stores the global setting you need ($currentlang in the above example).

User information is stored in the userinfo array. This array is filled with a call to the getusrinfo() function. Thus a simple way to arrive at some information that is special to the currently logged-in user, is to write somethink like

    global $user, $userinfo;
    if(is_user($user)) {
        getusrinfo($user);      
    }

You have then some user-specific settings at your disposal:

$name = $userinfo['uname'];
$uid = $userinfo['uid'];
$email_real = $userinfo['email'];
$email_fake = $userinfo['femail'];
$url = $userinfo['url'];
$avatar = $userinfo['user_avatar'];
$newsletter = $userinfo['newsletter'];
$icq = $userinfo['user_icq'];
$aim = $userinfo['user_aim'];
$yim = $userinfo['user_yim'];
$msnm = $userinfo['user_msnm'];
$location = $userinfo['user_from'];
$occupation = $userinfo['user_occ'];
$interests = $userinfo['user_intrest'];
$signature = $userinfo['user_sig'];
$biography = $userinfo['user_bio'];

and can use them in the same manner as $currentlang above to build a highly customized header.

14.3.4. How to change the logo in the PHP-Nuke header

One of the first things you will want to change once your PHP-Nuke is up and running, is the site's logo. For this, you only have to replace the logo.gif file that came with the theme you are using. Search for themes/YourTheme/logo.gif. Whatever graphic you put in logo.gif, it will show as the site's logo in the PHP-Nuke header.

If you want to change the way the logo is displayed, perhaps by setting a width and height attribute, or specifying a border, you will have to change the HTML code that displays it in the theme. To do this in a dynamic way, see Section 14.3.5. Here are the relevant code lines for each one of the standard PHP-Nuke themes:

./themes/3D-Fantasy/header.html:<a href="index.php"><img src="themes/3D-Fantasy/images/logo.gif" border="0" 
alt="Welcome to $sitename" align="left"></a>
./themes/ExtraLite/theme.php:        ."<a href=\"index.php\"><img src=\"themes/ExtraLite/images/logo.gif\" 
alt=\"Welcome to $sitename\" title=\"Welcome to $sitename\" border=\"0\"></a>"
./themes/Kaput/theme.php:       ."<a href=\"index.php\"><img src=\"themes/Kaput/images/logo.gif\" border=\"0\" 
alt=\""._WELCOMETO." $sitename\" align=\"left\"></a></td>"
./themes/NukeNews/header.html:<a href="index.php">
<img src="themes/NukeNews/images/logo.gif" align="left" 
alt=""._WELCOMETO." $sitename" border="0" hspace="10"></a></td>
./themes/Odyssey/header.html:<a href="index.php">
<img src="themes/Odyssey/images/logo.gif" 
alt=""._WELCOMETO." $sitename" border="0"></a>
./themes/Slash/theme.php:<a href=$nukeurl>
<img src=themes/Slash/images/logo.gif border=0></a>
./themes/SlashOcean/theme.php:<a href=$nukeurl>
<img src=themes/SlashOcean/images/logo.gif 
Alt=\"Welcome to $sitename\" border=0></a>
./themes/Traditional/theme.php: ."<a href=\"index.php\">
<img src=\"themes/Traditional/images/logo.gif\" 
alt=\""._WELCOMETO." $sitename\" border=\"0\"></a>"
./themes/Anagram/theme.php:     ."<a href=\"index.php\">
<img src=\"themes/Anagram/images/logo.gif\" align=\"left\" 
alt=\""._WELCOMETO." $sitename\" border=\"0\"></a></td>\n"
./themes/Karate/theme.php:      ."<a href=\"index.php\">
<img src=\"themes/Karate/images/logo.gif\" align=\"left\" 
alt=\""._WELCOMETO." $sitename\" border=\"0\"></a></td>\n"
./themes/Milo/theme.php:        ."<a href=\"index.php\">
<img src=\"themes/Milo/images/logo.gif\" align=\"left\" 
alt=\""._WELCOMETO." $sitename\" border=\"0\"></a></td>\n"
./themes/Sunset/theme.php:echo "<a href=$nuke_url>
<img src=themes/Sunset/images/logo.gif 
Alt=\""._WELCOMETO." $sitename\" border=0></a>\n";
./themes/DeepBlue/theme.php:    ."<table border=0 width=100% cellpadding=0
cellspacing=0><tr><td align=\"left\"><a href=\"index.php\">
<img border=\"0\" src=\"themes/DeepBlue/images/logo.gif\" 
alt=\"Welcome to OpenMax!\" hspace=\"20\"></a></td><td align=\"right\">
<img border=\"0\" src=\"themes/DeepBlue/images/logo-graphic.gif\"
width=\"\"></td></tr></table></td></tr>\n"

This is also the place to put your change, if you want a second graphic besides your logo, or some other logo customization.

14.3.5. How to change the logo's dimensions dynamically

If you have designed a logo that can be displayed equally well at many resolutions and you wish to be able to change its display dimensions dynamically, according to the display resolution of your visitor's monitor, then you have to use Javascript. This is because PHP is a server-based technology and the web server has no means of knowing the monitor resolution of a client requesting a page. It would have to query that client for the resolution it uses, get an answer, then create the page with the right logo dimensions. But HTTP is a stateless protocol, meaning that, when the server gets an answer, it has no means to relate it to some previous request - not without cookies, URL parameters, sessions and all that extra stuff. This is where Javascript comes into play, obviating the need for a query-and-answer procedure.

Substitute the image logo tag

<img src=themes/YourTheme/images/logo.gif alt=""._WELCOMETO." $sitename" border="0">

of your theme (see Section 14.3.4) with the following:

$mod_log = "images/my_logo.gif";
echo ("<script>\n");
echo ("var swidth='0';\n");
echo ("swidth=screen.width\n");
echo ("if ((swidth<=640)&&(swidth<800)){\n");
echo ("document.write('<img src=$mod_logo width=500 border=0>')");
echo ("}\n");
echo ("else\n");
echo ("if ((swidth>799)&&(swidth<1024)){\n");
echo ("document.write('<img src=$mod_logo width=700 border=0>')");
echo ("}\n");
echo ("else\n");
echo ("if (swidth>=1024){\n");
echo ("document.write('<img src=$mod_logo width=900 border=0>')");
echo ("}\n");
echo ("</script>\n");

Change the location of your logo in the $mod_log variable. The code will echo this Javascript in place of the image tag:

<script>
var swidth='0';
swidth=screen.width
if ((swidth<=640)&&(swidth<800)){
document.write('<img src=$mod_logo width=500 border=0>')");
}
else
if ((swidth>799)&&(swidth<1024)){
document.write('<img src=$mod_logo width=700 border=0>')");
}
else
if (swidth>=1024){
document.write('<img src=$mod_logo width=900 border=0>')");
}
</script>

which will be executed on the client's browser (if the client has Javascript enabled, of course). It will query its resolution (screen width) and write the HTML image tag, with the correct dimensions for the logo image, into the page's HTML code. It may not work though, if the client's security settings do not allow querying the screen's width. See Different themes for different resolutions and banner next to logo for a discussion of the details.

14.3.6. How to change placement of the banner in the PHP-Nuke header

Sometimes the banner will appear at a position that you would feel is unfavourable for your theme and overall appearence of your site (of course, only if you enabled the banner functionality in the administration panel, see Section 7.1). The code that controls whether the banner will appear or not, is a few lines long:

if ($banners == 1) {
include("banners.php");
}

and is found in the themeheader() function of the theme.php file. You don't need to bother about the included file, banners.php, that actually does all the job of selecting and displaying the appropriate banner, keeping banner statistics up-to-date and all that stuff. All you need is find out where to place those 3 lines in order to achieve the desired banner placement. As this is a highly theme dependent topic, there are no general recipes. Just move the 3-liner around in themeheader() to get a feeling of the various elements and their positions, then experiment a little to find the right one for you. You might, for example, choose to include it in a table layout and echo it directly after the HTML <body> line:

echo "<body bgcolor=\"#ffffff\" topmargin=\"0\" 
leftmargin=\"0\" marginheight=\"0\" marginwidth=\"0\">\n\n"
."<table cellpadding=\"0\" cellspacing=\"0\" 
 width=\"100%\" border=\"0\" bgcolor=\"#6487dc\"><tr>\n"
."<td bgcolor=\"#6487dc\" align=\"left\" 
 valign=\"top\" width=\"20%\"><br>
<a href=\"index.php\"><img src=\"themes/subSilver/images/logo.gif\" 
 align=\"left\" alt=\""._WELCOMETO
." $sitename\" border=\"0\"></a><br></td>\n"
."</td><td bgcolor=\"#6487dc\" align=\"right\">";
if ($banners) {
  echo "<br>";
  include("banners.php");
  echo "<br>";
}

See Banner placement and banner next to logo for a discussion of banner placement in PHP-Nuke.

14.3.7. How to display a watermark background image

It may sound inconsistent (actually, it is inconsistent!), but in order to display a static background image (i.e. one that does not scroll down when you scroll), like a watermark, in PHP-Nuke, you must change the theheader() function in the theme.php file of your theme.

The code you will need for this nice effect should be placed in the body part of the page's HTML code (the part delimited by the <body> and </body> HTML tags). The reason we need this in the body part, is that in the header it will produce an error (at least in Mozilla):

Error: document.body has no properties

This is probably because the document body does not exist at the time the header is loading.

Our code is a small Javascript, so you might think it belongs to the javascript.php file under the includes folder (see Section 21.9.1). Unfortunately, whatever is in that javascript.php file, will be included in the HTML header of the page, i.e. the part of the HTML code delimited by the <head> and </head> tags (see Chapter 15), so this will not serve our purpose. What we actually need is a file for code that belongs to the HTML body and comes preferably immediately after the <body> tag - but such a file does not exist in PHP-Nuke yet.

Thus, the next best place to insert our Javascript is in the theme.php file of our theme. This is because the <body> tag is echoed precisely in this file, as Table 14-1 demonstrates[1].

Table 14-1. <body> tags in theme.php of various themes

theme.php file

PHP code that echoes the <body> tag for the theme

themes/3D-Fantasy/theme.php

echo "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#363636\" vlink=\"#363636\" alink=\"#d5ae83\"><br>\n\n\n";

themes/Anagram/theme.php

echo "<body bgcolor=\"#ffffff\" text=\"#000000\">\n";

themes/DeepBlue/theme.php

echo "<body bgcolor=\"#0E3259\" text=\"#000000\" link=\"0000ff\">"

themes/ExtraLite/theme.php

echo "<body text=\"000000\" link=\"0000ff\" vlink=\"0000ff\">"

themes/Kaput/theme.php

echo "<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#363636\" vlink=\"#363636\" alink=\"#d5ae83\">\n"

themes/Karate/theme.php

echo "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#363636\" vlink=\"#363636\" alink=\"#d5ae83\">\n"

themes/Milo/theme.php

echo "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#363636\" vlink=\"#363636\" alink=\"#d5ae83\">\n"

themes/NukeNews/theme.php

echo "<body bgcolor=\"#505050\" text=\"#000000\" link=\"#363636\" vlink=\"#363636\" alink=\"#d5ae83\">";

themes/Odyssey/theme.php

echo "<body bgcolor=\"#004080\" text=\"#000000\" link=\"#004080\" vlink=\"#004080\" alink=\"#004080\">";

themes/Sand_Journey/theme.php

echo "<body bgcolor=\"$bgcolor1\">";

themes/Slash/theme.php

echo "<body bgcolor=DDDDDD text=222222 link=660000 vlink=222222>

themes/SlashOcean/theme.php

echo "<body bgcolor=FFFFFF text=000000 link=101070 vlink=101070>

themes/Sunset/theme.php

echo "<body bgcolor=\"#FFC53A\" text=\"#000000\" link=\"#035D8A\" vlink=\"#035D8A\">";

themes/Traditional/theme.php

echo "<body bgcolor=\"#FFFFFF\" text=\"#000000\" link=\"#000000\" vlink=\"#000000\">"

Find the line that echoes the <body> tag in your theme.php (look for the themeheader() function or consult Table 14-1) and insert the following lines after it (if the line does not contain a semicolon at its end, you have of course to append these lines after the next most close line that contains it, otherwise you will mess up the code and get errors):

    echo "\n";
    echo "<script language=\"JavaScript1.2\">\n";
    echo "<!--\n";
    echo "if (document.all||document.getElementById) \n";
    echo "document.body.style.background=
          \"url('http://www.yoursite.com/images/watermark.gif') 
          white center no-repeat fixed\"\n";
    echo "//-->\n";
    echo "</script>  \n";

Adapt the URL in the script (http://www.yoursite.com/images/watermark.gif) to reflect the full URL to your watermark image. That's all, if your theme does not define any background colours for tables!

In practice, however, your theme will define at least two table background colours, those in the OpenTable() and OpenTable2() functions, as shown in this example, taken from the ExtraLite theme:

function OpenTable() {
    global $bgcolor1, $bgcolor2;
    echo "<table width=\"100%\" border=\"0\" 
          cellspacing=\"1\" cellpadding=\"0\" 
          bgcolor=\"$bgcolor2\"><tr><td>\n";
    echo "<table width=\"100%\" border=\"0\" 
          cellspacing=\"1\" cellpadding=\"8\" 
          bgcolor=\"$bgcolor1\"><tr><td>\n";
}
function OpenTable2() {
    global $bgcolor1, $bgcolor2;
    echo "<table border=\"0\" 
          cellspacing=\"1\" cellpadding=\"0\" 
          bgcolor=\"$bgcolor2\" align=\"center\"><tr><td>\n";
    echo "<table border=\"0\" 
          cellspacing=\"1\" cellpadding=\"8\" 
          bgcolor=\"$bgcolor1\"><tr><td>\n";
}

You must delete those bgcolor attributes completely for this method to work! In fact, this will not be enough: you will have to delete every other table bgcolor attribute that appears in your theme.php[2]. Contrary to what is implied in Static Background Image, where this method is described in detail, deleting only the bgcolor attributes for the above two OpenTable functions will not be enough.

TipAlternative solution
 

An alternative solution would be to add the background and bgproperties attributes directly in the <body> tags of the lines in Table 14-1, as in this example for the ExtraLite theme:

echo "<body background=\"images/watermark.gif\" bgproperties=\"fixed\" 
text=\"000000\" link=\"0000ff\" vlink=\"0000ff\">"

bgproperties will also create a "watermark" on the page, a background image which does not scroll with the rest of the page (see bgproperties attribute. The only value it can attain is “fixed” and it must be used in conjunction with the background attribute. It is an MSIE extension, so use it, but don't rely on it. You will again have to delete all background colour attributes of the tables in theme.php. Contrary to the first method, however, there is no way to specify a no-repeat property, so that if your image does not fill the whole background space available (which depends on the client's monitor resolution), it will be repeated horizontally as well as vertically.

14.3.8. How to display a Flash object in the PHP-Nuke header

To show Flash in the PHP-Nuke header, you simply have to echo the appropriate HTML code. Since the HTML code for a Flash object is something like

<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"
codebase=\"http://download.macromedia.com/pub/shockwave/cabs/
flash/swflash.cab#version=6,0,29,0\" width=\"350\" height=\"100\">
<param name=\"movie\" value=\"yourMovie.swf\">
<param name=quality value=high>
<embed src=\"yourMovie.swf\" quality=high pluginspage=\"http://www.macromedia.com/shockwave/download/
index.cgi?P1_Prod_Version=ShockwaveFlash\" type=\"application/x-shockwave-flash\"
width=\"350\" height=\"100\"></embed>
</object>

the PHP-Nuke header code should contain something like

echo "<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/
flash/swflash.cab#version=6,0,29,0\" width=\"350\" height=\"100\"> "
."<param name=\"movie\" value=\"yourMovie.swf\"> "
."<param name=quality value=high> "
."<embed src=\"yourMovie.swf\" quality=high pluginspage=\"http://www.macromedia.com/shockwave/download/
index.cgi?P1_Prod_Version=ShockwaveFlash\" type=\"application/x-shockwave-flash\"
width=\"350\" height=\"100\"></embed>"
."</object>";

You can put the above code in the themes/YourTheme/theme.php file, in the themeheader() function, after the call to the banners code:

if ($banners == 1) {
    include("banners.php");
}
...put Flash code ("echo") here...

The Flash object will be displayed after the banner, if you have one. See Section 20.6 on how to show Flash in a PHP-Nuke block.

14.3.9. How to hide the left blocks

For some esoteric reason, you may want to hide the column with the left blocks, although it contains some crucial blocks, like the modules block (Figure 17-1), for example. To accomplish this, you have to edit the themeheader() function in the theme.php file of your theme (in the themes/YourTheme folder) and replace the line:

blocks(left);

with

if ($name=='Forums') {
  /* Don't display it. */
}
else {
  blocks(left);
}

Here, we check if the module is the Forums module and suppress the call to blocks(left) if it is. This will hide the left column blocks in the Forums. It is easy to include more modules, as in the following example (see Hide left blocks when viewing Forum or ANY module, Como eliminar los bloques de la izquierda, Left Blocks on Index Page only):

if ($name=='Forums' || $name=='Members_List' || $name=='Private_Messages') {
  /* Don't display it. */
} else {
  blocks(left);
}

Don't forget to add $name to the list of global variables in themeheader():

global $user, $banners, $sitename, $slogan, $cookie, $prefix, $dbi, $name;

Of course, if you don't find the call to blocks(left), your theme already suppresses the left column of blocks.

TipHow to hide the right blocks
 

Most of the time, if you want to hide any blocks, they will be the blocks in the right column, not the blocks in the left. See Section 18.1.1 on how to hide the right blocks.

From a theme design point of view, the above solution does not look satisfactory: you have to hardcode the names of the modules that should not display the left blocks into the code of the theme. Since you don't know in advance which ones these are, you create a dependency relation to all existing and future modules.

A cleaner, alternative way is to declare the global $hideleft variable in themeheader() and check its value instead:

global $hideleft;
...
if($hideleft == 1){
  /* Don't display it. */
} else {
  blocks(left);
}

Now, for every module that you want to hide the left blocks, insert the lines

global $hideleft;
$hideleft =1;

at the beginning of its code. As you see, with this method, the selection of the modules that hide the left blocks has become the job the modules' authors. The theme code can work with any module, present or future one, without changes - as any theme should.

TipMore flexibility with the Block Modificator
 

With Chris Sengers' Simple Blocks Manipulator for left blocks you can put any block left or right differently with any module. You can even use inactive blocks and also change the theme according to the module (we show how to do this yourself in Section 14.11).

Notes

[1]

Of course, this also means that our change has to be applied for every theme and after every upgrade anew.

[2]

That is at least the way I managed to get it to work with the ExtraLight theme. Since everyt heme is different, you will have to experiment here.