Back to Programming Articles

Using PHPINCLUDE_START. (Last Lesson - #7 - Added 12-16-4)
by Michael Morris 03 Nov 2004

This is a tutorial on the use of the PHPINCLUDE_START template. In the process of writing an 800+ line monster into the boards I help administrate I learned a few things about this template I'd like to share. In this tutorial you'll be applying several hacks as an excersize, though some you may wish to keep as an enduring part of your boards.

This tutorial assumes you know next to nothing about PHP, but it does assume you know a little about XML/HTML.

The examples used in this tutorial are based upon a clean install of vbulletin. If you've made changes you'll need to adjust appropriately.

Ready to begin? GREAT!

Some basics
If you've done any editting of your forum's styleset you've seen the PHPINCLUDE_START template and it's brother the PHPINCLUDE_END template (which is touched upon occassionally but not covered exhaustively here). These templates provide a means for you to inject you're own php code into vbulletin WITHOUT voiding your Jelsoft User Support eligability. PHPINCLUDE_START executes before any other templates are parsed, and PHPINCLUDE_END executes after all other templates are parsed.

By the time vbulletin reaches the PHPINCLUDE_START template it has done the following
  1. Loaded the user's information
  2. Loaded the forum information
  3. Cached all phrases due for use on the page.
  4. Loaded the CSS and the style variables for the current style.
  5. Cached (but not parsed) all templates due to be called on the page.
  6. Defined all common functions used in vbulletin.

Hence you can at this point reset any and all of this information, but be warned that you can cause interesting things to happen.

$phpinclude_output
PHPINCLUDE_START is parsed under an object buffering mask. This means that statements that normally print things to the screen of the browser (echo, print statements) don't affect the browser. Instead the results of these statements is put into the $phpinclude_output variable (NOT $_phpinclude_output as listed in the header templates of vb 3.0.3. This is one of the surviving bugs in vb3).

By default $phpinclude_output is contained within your header template (Again, under the eronous $_phpinclude_output). But since we're not planning to just include an html header we need to do something else with it. Note that you don't want to get rid of it entirely - if you're script has a non-fatal error the results of the error message go into $phpinclude_output and you'll need that for debugging.

So let's move it somewhere useful - the footer.

Open your footer template and append the following code to the very end.

HTML Code:
<if condition="is_member_of($bbuserinfo, 6)">
$phpinclude_output
</if>
Now if you haven't already go to your header template, find $_phpinclude_output and remove it. The above code makes the $phpinclude_output data display at the end of your pages where it's unlikely to affect the layout. The conditional insures that only administrators get to see the output.

Why would we want to limit this to admins? Well, for one, do we really want users seeing error statements? Not really. For another it allows us to use echo and print statements to debug our scripts.

Let's test this code. Clear out your PHPINCLUDE_START template's entire code (if you're on a fresh install) and type in the following

PHP Code:
echo 'Hello World'
Now reload your home page. At the bottom you should see "Hello World." Log out. The message should dissappear. Log back in. Now let's do something useful. Clear out the PHPINCLUDE_START template again and put this in.

PHP Code:
print_r($bbuserinfo); 
At the bottom of you're page you'll see something like this:

Code:
Array ( [userid] => 1 [temp] => [field1] => [field2] => [field3] => [field4] => [subfolders] => [pmfolders] => [buddylist] => [ignorelist] => [signature] => [searchprefs] => [usergroupid] => 6 [membergroupids] => [displaygroupid] => 6 [username] => Michael [password] =>
And so on. All that stuff is the contents of $bbuserinfo. $bbuserinfo is an array which means it's a multipart variable. The stuff in [] are the elements to the array. The stuff to the right of the => are the values each element currently contains. Hence $bbuserinfo['userid'] contains the value of "1" (This output is from my test server where I'm the primary and only user).

That concludes today's lesson. Tomorrow I'll append one of my hacks, the System announcement system, and go over it in detail to explain how and why it works.

Lesson Two - An Announcment System in templates - Part 1

Today we're going to begin to build an announcment system and explore a couple of the functions unique to vbulletin in the process. The hack by itself is here,

Spoiler (click to open)


Ack, missed a parenthesis. Correction

PHP Code:
$globaltemplates array_merge($globaltemplates
        array( 
            
'announcement_all'
            
'announcement_guest'
            
'announcement_pending'
            
'announcement_staff'
            
'announcement_noposts'
            
'announcement_noposts14days'
            
'announcement_registered' 
               

); 

Close
and over the course of the next few lessons we will arrive at that code.

Before we start playing around with PHPINCLUDE_START template in depth though it's advisable to build a style specifically for your tests with it. This way you can iron the bugs out on your experiments without crashing vital you're boards (which is possible - Fatal errors in PHPINCLUDE_START can bring the whole thing down in a hurry).

Now, let's start our announcment system. The first part is defining output that will be displayed in the template. The system does this already for our echo and print statements by plugging them into the $phpinclude_output variable. That isn't the only variable we can use though. We can define any varaible we like and be able to post it into most templates. Templates that are used in functions, such as forumdisplay_nopost_level1, require a little creative cheating which will be discussed another day.

To be effective announcements need to be in a prominent place, and few templates are as prominently placed as the header. So at the very end of your header put the following in

HTML Code:
$announcement
Clear out PHPINCLUDE_START and plug this in.

PHP Code:
$announcement 'Hello World'
Reload your page. "Hello World" should be displayed in place of the $announcement variable.

Rules for variables
PHP, like all other programming languages, uses variables extensively, and PHP also has a particular love of array variables with over 40 functions devoted to their manipulation. Unlike some languages like C++ you don't have to declare your variables at the start of your program, though it's good practice to do this. One reason is security

Security Warning: If you don't initialize a variable properly PHP might take it's value off of the browser line. For instance in the URL somewhere.php?file=lazy PHP will start the script with the variable $file already set to 'lazy.' Depending on that variable's role in your script the result of hackers putting variables on the browser line can range from annoying to catastrophic. Vbulletin initializes it's variables to guard against this threat and you should get in the habit of doing it as well in case you ever write PHP code intended to be ran outside of vbulletin.

Variables in php always start with $ and contain no spaces. A few variables are reserved - if you use a PHP context editor such as Dreamweaver you'll be alerted to this when the text changes color.

More info on variables can be found at http://www.php.net

Ok, back to our variable, $announcement. Let's set it to something more interesting than "Hello World"

PHP Code:
$announcement 'Welcome to my forums <br />'
        
'Please enjoy your stay.'
Note the . This is an append. You can do this multiple times so that you can get a feel for what the text is going to look like on the screen. Just make sure that only the final line has the ending ; character or you'll get a parse error.

Now while this is all interesting it isn't particularly useful. What can make things interesting is putting a conditional in - if.

Two faces of "IF"
The if statement is the the most common control structure across all programming languages. Even Commodore BASIC had if statements. These statements allow you to execute code according the a condition. Let's try a very basic conditional for our announcement which limits it to us.

PHP Code:
if ($bbuserinfo['userid']=='1')
    {
    
$announcement 'I am User 1, the primary admin';
    }
else
    {
    
$announcement 'Hello Guest';
    } 
Save and reload your page. You should see the first message if you are the founding member of your board. Now log out. You should see the other message.

Now, with a single ! we can turn this whole thing around. Putting ! at the start of a condition is the same as saying "NOT" Try this

PHP Code:
if (!$bbuserinfo['userid']=='1')
    {
    
$announcement 'Hello Users!';
    }
else
    {
    
$announcement 'Hello Me';
    } 
You can do this within the templates as well, though the format is slightly different.

PHP Code:
<if condition="$bbuserinfo['userid']==1">Hello Me
<else />Hello Users
</if> 
But note that not all the possible conditionals are avaiable in templates.

Well, that's enough for today methinks. Next lesson will begin to cover some serious ground by actually setting announcement to a useful value.

Lesson Three - An Announcment System in templates - Part 2

Today we'll finish up our announcement system. With knowledge of conditionals we can build the thing entirely in the PHPINCLUDE_START template, but defining the variable on all those conditions can be painstaking and hard to edit. Wouldn't it be easier to put it all in a custom template? That way we can simply edit each of our announcements individually without worrying about affecting our code. This is also useful if you have a co-admin or a client that knows nothing about PHP and isn't willing to learn, yet they want to be able to type up announcements to be displayed in their header.

Well, yes it is easier, and possible, but we gotta go fetch.

The fetch_template and eval functions.
When you make a custom template you can't simply plug it into other templates. Indeed, the ability to define you're own templates wouldn't be terribly useful if you couldn't call them back. The fetch_template function accomplishes this.

The format of this function, by itself, is:

PHP Code:
fetch_template('TEMPLATE_NAME'
We can assign a template to a variable by doing the following:

PHP Code:
$announcement fetch_template('announcement'); 
Try it and see. Create a custom template called announcment and save it, then put the above statement in and reload your page. Pretty cool eh? But something's not quite right. If you read through the vbulletin sourcecode you'll almost never see the above, but you will see this:

PHP Code:
eval('$announcement = "' fetch_template('announcement') . '";'); 
eval? What's that about. Well, try this. Open your announcement and plug in the following.

HTML Code:
Hello $bbuserinfo[username]
You'll get back exactly, "Hello $bbuserinfo[username]." This brings us to our next function. eval is a PHP defined function (meaning it's always available in PHP whether you're using vbulletin or not) that evaluates a string. Eval pulls variables and template conditionals out of our templates and, well, "evaluates" them.

Now, time to build

Now that we understand the tools let's go ahead and build our announcement system. First let's pretty up our announcment in the header.

HTML Code:
<if condition="!empty($announcement)">
<table class="tborder" cellpadding="$stylevar[cellpadding]" cellspacing="$stylevar[cellspacing]" width="$stylevar[outertablewidth]" align="center">
	<tr><td align="center">$announcement</td></tr>
</table>
</if>
That frames the announcement in a table with the style definitions given for table borders in the current style - meaning it will look like a forum rules box.

Now we'll define six announcements, as follows
  1. A general announcement for all members, when necessary (like "Hey, I'll be shutting the boards down for awhile at a certain time, get you're post with done by then")
  2. An invitational announcement for guests, similar to the default one given on the forum home page but appearing instead on all pages.
  3. A message for users who need to complete their registration via email.
  4. A message for the moderators, supermoderators, and staff.
  5. A message for users who've never posted
  6. A message for users who've not posted in the last 14 days
  7. And a message for all other users.

The names for these custom templates should be, in the same order:
  1. announcement
  2. announcement_guest
  3. announcement_pending
  4. announcement_staff
  5. announcement_noposts
  6. announcement_noposts14days
  7. announcement_registered

Now, clear out the PHPINCLUDE_START template and plug in the following:

PHP Code:
// #####################################################
// #####            START ANNOUNCMENTS             #####
// ##################################################### 
All that stuff is commentary text. The computer ignores anything that follows a double backslash ("//"). It's useful for writing notes to ourselves about what the code is doing (or supposed to be doing). Lot's of commentary text makes the code easier for others to understand. It has next to no effect on performance, so use it and use it often.

PHP Code:
eval('$announcement = "' fetch_template('announcement_all') . '";');

if (empty(
$announcement)) //If it's empty we'll get our usergroup announcements
    
{
    if (
is_member_of($bbuserinfo1))  // Guests 
To review, the $is_member_of function checks to see if the user ($bbuserinfo)belongs to the usergroup stated.

PHP Code:
        {
        eval(
'$announcement = "' fetch_template('announcement_guest') . '";');
        }
    else if (
is_member_of($bbuserinfo3)) // Pending Registrant
        
{
        eval(
'$announcement = "' fetch_template('announcement_pending') . '";');
        }
    else if (
is_member_of($bbuserinfo4// Mods
        
OR is_member_of($bbuserinfo5// Supermods
        
OR is_member_of($bbuserinfo6)) // Admins
        
{
        eval(
'$announcement = "' fetch_template('announcement_staff') . '";');
        } 
Usergroups must be checked one at a time. If you use "is_member_of($bbuserinfo, '4, 5, 6') the function only returns users beloning to ALL THREE of those groups.

PHP Code:
    else if ($bbuserinfo['posts'] == 0// User has never posted. Encourage them.
        
{
        eval(
'$announcement = "' fetch_template('announcement_noposts') . '";');
        }
    else if (
TIMENOW $bbuserinfo['lastpost'] > 1209600// User hasn't posted in 14 days. 
TIMENOW is a defined constant that holds the Unix timestamp value of the current time. Vbulletin stores all dates and times by their Unix timestamps, which is simply the number of seconds that have passed since Midnight on January 1, 1970 in the Greenwich time zone (Trust me, it's a lot of seconds). 1209600 is 14 days worth of seconds.

PHP Code:
        {
        eval(
'$announcement = "' fetch_template('announcement_noposts14days') . '";');
        }
    else 
// All others
        
{
        eval(
'$announcement = "' fetch_template('announcement_registered') . '";');
        }  
    } 
And that's it. From here you should now have the knowledge necessary to create additional announcements and link them to your custom usergroups.

Next lesson we're going to start playing with user profile fields and using them to create user controls on the vbulletin display.

Lesson Four - Power to the People #1 - User Selectable Postbit

Start a thread on your boards about the layout and you'll a list of things folks don't like. Worse, often the thing one user detests will be something other users enjoy. Wouldn't it be nice if you could please everyone? Well, in vbulletin you can allow them to customize the layout to their tastes.

Layout customization requires use of the User profile fields and most of the time it requires one or more template edits. We'll start with a simple one - letting the users choose the postbit layout (Note: This hack was originally discovered by Boofo, one of our moderators).

As you know, vbulletin has two layout schemes - postbit (used over at http://www.vbulletin.com) and postbit_legacy (used here). The existing switch for these is in the vbulletin options panel. The setting is stored in $vboptions['legacypostbit']. If it's set to 1 (true) then we use it, otherwise we don't.

Since you probably want to keep the announcement system we'll slide our next bit of code in front of it (This is one of the reasons why we used the header to clearly mark the start). We'll give it a header too. But first we need to go to user profile fields and create a new one. Choose to create a Single Selection drop down menu with the options of "Default - Vb3 style" and "Classic - Vb2 style" Put it in the thread viewing options. Note the field # that vbulletin assigns to it and plug it in for X below where you see "fieldX"

PHP Code:
// #####################################################
// #####            START USER OPTIONS             #####
// #####################################################

if ($bbuserinfo['userid'])
    {
    
// #### Set Postbit ##########################
        
if (strstr($bbuserinfo['fieldX'], 'Classic'))
            {
                
$vboptions['legacypostbit'] = 1;
            }
        else
            {
                
$vboptions['legacypostbit'] = 0;
            }
    } 
The way this query works is that first we check if a userid is present. If this isn't true we can go ahead and skip all the user settings because we're dealing with a guest.

Only then do we check for the field. Note the use of a new inbuilt function - strstr. strstr has the following format:

PHP Code:
strstr($haystack$needle
The $haystack is the string we're going to search, in the above example $bbuserinfo['fieldX']. The needle is the string we're looking for - 'Classic'. This allows you to create very long drop down menu options without having to quote them back in the phpinclude_start script - all you have to remember is the keyphrase.

Incidently, strstr is case sensitive. It has a brother, stristr, that is case insensitive.

This concludes this lesson. Next time we'll deal with some more template editting intensive features.

Lesson Five - Power to the People #2 - Bold / Not so Bold; Italics / Rather not

By default vbulletin displays New threads since the last visit in bold. Suppose a user doesn't want that. Well, we can do that. Another user would like his subscribed threads to be displayed in italics so they're easier to spot. We can do that too.

Open the threadbit template and search for this code:

HTML Code:
<a href="showthread.php?$session[sessionurl]t=$thread[threadid]$thread[highlight]"><if condition="$show['gotonewpost']"><strong>$thread[threadtitle]</strong><else />$thread[threadtitle]</if></a>
Replace it with this doozy of a chain conditional:

HTML Code:
<if condition="$show['gotonewpost'] AND $show['new_bold'] AND $show['subscribed'] AND $show['subscribed_italics']">
				<a href="showthread.php?$session[sessionurl]t=$thread[threadid]$thread[highlight]"><i><b>$thread[threadtitle]</b></i></a>
			<else />
			<if condition="$show['gotonewpost'] AND $show['new_bold']">
				<a href="showthread.php?$session[sessionurl]t=$thread[threadid]$thread[highlight]"><b>$thread[threadtitle]</b></a>
			<else />
			<if condition="$show['subscribed'] AND $show['subscribed_italics']">
				<a href="showthread.php?$session[sessionurl]t=$thread[threadid]$thread[highlight]"><i>$thread[threadtitle]</i></a>
			<else />
				<a href="showthread.php?$session[sessionurl]t=$thread[threadid]$thread[highlight]">$thread[threadtitle]</a>
			</if></if></if>
Now, create two new user profile fields that are single selection radio buttons. The selections should be yes or no, and the questions should be whether the user wants new threads in bold and subscribed threads in italics.

Now let's open our PHPINCLUDE_START template. Since we want these items to be displayed by default we need to set their defaults, so at the very top

PHP Code:
// #####################################################
// #####            SET DEFAULTS             #####
// #####################################################

$show['subscribed_italics'] = true;
$show['new_bold'] = true
Now we'll nest in our two new options into the user options below. This should all go after the //Set Postbit conditional but before the $bbuserinfo conditional is closed.

PHP Code:
    // #### Set New Posts Bold ##########################
        
if ($bbuserinfo['fieldX'], 'No'))
            {
                
$show['new_bold'] = false;
            }
    
// #### Set Subscribed Italics ##########################
        
if ($bbuserinfo['fieldX'], 'No'))
            {
                
$show['subscribed italics'] = false;
            } 
Else statments aren't necessary here because there are only two possibilities and we've already set the alternate.

Homework!!

Now, it's time to apply what you've learned. As you're probably aware, when you move your mouse over a thread's cell you will get a preview. Create a switch like the ones above that turns the thread previews on or off.

Hint 1: The thread preview is in the thread bit template.

Hint 2: Specifically, it's here (Don't look if you want to hunt for it...)

HTML Code:
<td class="alt1Active" id="t$thread[threadid]" title="$thread[preview]">
PM me if you need more help.

This concludes the basics of template based switches to control the user layout. In the next lesson we'll move onto something a bit more complex

Lesson Six - Power to the People #3 - My Links Dropdown System

Look around any boards and you're likely to note that some users use their sigs to display board related links to their favorite threads or outside sites. Some users also use their favorite boards as homepages. Wouldn't it be nice for these users if they could put some of their links in an easy find location

Say, the navbar dropdowns is a useful spot.

To begin this project create a user profile field that is multiple text lines and has a character limit of at least 2000. The user is then going to put links in this profile field using the standard url related tags - url, post, and thread.

Once you do that crack into your navbar and look for this code:

HTML Code:
			<!-- nav buttons bar -->
				<div align="center">
					<table class="thead" cellpadding="0" cellspacing="0" border="0" width="100%" align="center">
						<tr align="center">
							<if condition="$show['popups']">
Immediately after add.

HTML Code:
								<if condition="!empty($mylinks)">
									<td id="mylinks" class="vbmenu_control"><a href="#mylinks">My Links</a> <script type="text/javascript"> vbmenu_register("mylinks"); </script></td>		
								</if>
Next look for this code in the navbar

HTML Code:
	<!-- / NAVBAR POPUP MENUS -->
Immediately above it insert the following code

HTML Code:
<if condition="!empty($mylinks)">
<!-- My Links Menu -->
	<div class="vbmenu_popup" id="mylinks_menu" style="display:none"> 
 		<table cellpadding="4" cellspacing="1" border="0"> 
			$mylinks
		</table> 
	</div>
<!-- /My Links -->
</if>
Now we go back into our phpinclude_start template and insert this code alongside the other user options we created in lesson 5

PHP Code:
if (!empty($bbuserinfo['field14']))
    {
    require_once(
'./includes/functions_bbcodeparse.php');
    
$mylinks parse_bbcode2($bbuserinfo['field14'], 0001);
    
$mylinks str_replace('<br />'''$mylinks);
    
$mylinks str_replace('</a>''</a></td></tr>'$mylinks);
    
$mylinks str_replace('<a''<tr><td class="vbmenu_option"><a'$mylinks);    
    } 
As before, you need to plug the correct user profile field # into the spot occupied by "field14" above.

As to what this code does, line by line:

PHP Code:
    require_once('./includes/functions_bbcodeparse.php'); 
We need to use a function that isn't normally called by the time vbulletin parses the phpinclude_start library but resides in this function library. If we don't do this we'll get a fatal error - function not defined - on the next line. We use require_once in case the bbcode parse library has already been included - if it has there's no need to include it again.

PHP Code:
$mylinks parse_bbcode2($bbuserinfo['field14'], 0001); 
This parses the code. $bbuserinfo['field14'] is the user's links. The 0, 0, 0, 1 are the parsing options: In order they are - HTML off, Smilies off, Automatically parse URL's off, bbcode On.

PHP Code:
$mylinks str_replace('<br />'''$mylinks); 
The parser puts breaks in on the carriage returns. We don't want these so we strip them back out.

PHP Code:
    $mylinks str_replace('</a>''</a></td></tr>'$mylinks);
    
$mylinks str_replace('<a''<tr><td class="vbmenu_option"><a'$mylinks); 
These place each url on their own table row so that the navbar dropdown displays correctly.

Lesson Seven - Navbar Games #1: Avatar in the Navbar

The navbar is one of the most powerful templates in vbulletin. It is quite literally the heart of you're poster's browsing of your boards. While it has a lot if information in it, you can certainly cram in some more.

Let's take a look at this template because the next several lessons are going to involve changes to it and it's useful to have a good understanding on how its built before cutting into it.

HTML Code:
<script type="text/javascript">
<!--
function log_out()
{
	ht = document.getElementsByTagName("html");
	ht[0].style.filter = "progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)";
	if (confirm('$vbphrase[sure_you_want_to_log_out]'))
	{
		return true;
	}
	else
	{
		ht[0].style.filter = "";
		return false;
	}
}
//-->
</script>
This script turns the screen gray on IE (uses Microsoft's proprietary browser commands so I'd be surprised to see it work elsewhere). It also launches the "Are you sure you want to log out?" button. We shouldn't need to mess with this, ever - but if you move the dropdowns elsewhere (say, into the header template) then you might want to move this with them.

HTML Code:
<br />
This single break establishes the default distance between the navbar and the top of the page. Omitting this will cause the navbar to be at the exact top of the page and, presumably, right up against the header. There are times when you want this though, and I've omitted it quite often for the various Wizards of the Coast templates I built.

HTML Code:
<!-- breadcrumb, login, pm info -->
<table class="tborder" cellpadding="$stylevar[cellpadding]" cellspacing="$stylevar[cellspacing]" border="0" width="100%" align="center">
<tr>
This starts the navbar proper. The first section that is the breadcrumbs...

HTML Code:
	<td class="alt1" width="100%">
		<if condition="is_array($navbits)">
			<table cellpadding="0" cellspacing="0" border="0">
			<tr valign="bottom">
				<td><a href="#" onclick="history.back(1)"><img src="$stylevar[imgdir_misc]/navbits_start.gif" alt="$vbphrase[go_back]" border="0" /></a></td>
				<td>&nbsp;</td>
				<td width="100%"><span class="navbar"><a href="$vboptions[forumhome].php?$session[sessionurl]" accesskey="1">$vboptions[bbtitle]</a></span> $navbits[breadcrumb]</td>
			</tr>
			<tr>
				<td class="navbar" style="font-size:10pt; padding-top:1px" colspan="3"><a href="$scriptpath"><img class="inlineimg" src="$stylevar[imgdir_misc]/navbits_finallink.gif" alt="$vbphrase[reload_this_page]" border="0" /></a> <strong>$navbits[lastelement]</strong></td>
			</tr>
			</table>			
		<else />
			<div class="navbar" style="font-size:10pt"><a href="$vboptions[forumhome].php?$session[sessionurl]" accesskey="1"><img class="inlineimg" src="$stylevar[imgdir_misc]/navbits_start.gif" alt="" border="0" /></a> <strong>$vboptions[bbtitle]</strong></div>
		</if>
	</td>	
The one conditional above is concerns whether or not there exists and "navbits" Navbits always have a second line to indicate the current page, so they have an alternate formatting.

Note that you can trade all of the above with the table below to switch the order of the user information and the breadcrumbs on your page if you want.

HTML Code:
	<if condition="$bbuserinfo['userid']">
This is checking to see if the current user has a userid (and if so, they aren't guest and the are logged in). If true we present the user a welcome block with their name et all.

HTML Code:
		<td class="alt2" valign="top" nowrap="nowrap">
		<div class="smallfont">
			<!--<span style="float:$stylevar[right]">[<a href="login.php?$session[sessionurl]do=logout&amp;u=$bbuserinfo[userid]" onclick="return log_out()">$vbphrase[log_out]</a>]</span>-->
			<strong><phrase 1="$bbuserinfo[username]">$vbphrase[welcome_x]</phrase></strong><br />
			<phrase 1="$pmbox[lastvisitdate]" 2="$pmbox[lastvisittime]">$vbphrase[last_visited_x_at_y]</phrase>
			<if condition="$show['pmstats']"><br /><phrase 1="$vbphrase[unread_x_nav_compiled]" 2="$vbphrase[total_x_nav_compiled]" 3="$session[sessionurl]">$vbphrase[private_messages_nav]</phrase></if>
		</div>
		</td>
If false we present the login block below.

HTML Code:
	<else />
		<td class="alt2" nowrap="nowrap" style="padding:0px">
		<!-- login form -->
		<form action="login.php" method="post" onsubmit="md5hash(vb_login_password,vb_login_md5password,vb_login_md5password_utf)">
		<script type="text/javascript" src="clientscript/vbulletin_md5.js"></script>
		<table cellpadding="0" cellspacing="$stylevar[formspacer]" border="0">
		<tr>
			<td class="smallfont">$vbphrase[username]</td>
			<td><input type="text" class="button" name="vb_login_username" id="navbar_username" size="10" accesskey="u" tabindex="1" value="$vbphrase[username]" onfocus="if (this.value == '$vbphrase[username]') this.value = '';" /></td>
			<td class="smallfont" colspan="2" nowrap="nowrap"><label for="cb_cookieuser_navbar"><input type="checkbox" name="cookieuser" value="1" tabindex="3" id="cb_cookieuser_navbar" accesskey="c" checked="checked" />$vbphrase[remember_me]</label></td>
		</tr>
		<tr>
			<td class="smallfont">$vbphrase[password]</td>
			<td><input type="password" class="button" name="vb_login_password" size="10" accesskey="p" tabindex="2" /></td>
			<td><input type="submit" class="button" value="$vbphrase[log_in]" tabindex="4" title="$vbphrase[enter_username_to_login_or_register]" accesskey="s" /></td>
		</tr>
		</table>
		<input type="hidden" name="s" value="$session[sessionhash]" />
		<input type="hidden" name="do" value="login" />
		<input type="hidden" name="forceredirect" value="1" />			
		<input type="hidden" name="vb_login_md5password" />
		<input type="hidden" name="vb_login_md5password_utf" />
		</form>
		<!-- / login form -->
		</td>
	</if>	
</tr>
</table>
<!-- / breadcrumb, login, pm info -->
That's the first major part of the navbar. The second part is the drop down menus. They are split in two: One creates the buttons on the bar, and the second part has the drop down menus.

HTML Code:
<!-- nav buttons bar -->
<div align="center">
	<table class="tborder" cellpadding="$stylevar[cellpadding]" cellspacing="0" border="0" width="100%" align="center" style="border-top-width:0px">
	<tr align="center">	
		<!--<td class="vbmenu_control"><a href="$vboptions[forumhome].php?$session[sessionurl]">Home</a></td>-->
		<if condition="$show['member']">
			<td class="vbmenu_control"><a href="usercp.php?$session[sessionurl]">$vbphrase[user_cp]</a></td>
		</if>
		<if condition="$show['registerbutton']">
			<td class="vbmenu_control"><a href="register.php?$session[sessionurl]">$vbphrase[register]</a></td>
		</if>
		<td class="vbmenu_control"><a href="faq.php?$session[sessionurl]" accesskey="5">$vbphrase[faq]</a></td>
		<td class="vbmenu_control"><a href="memberlist.php?$session[sessionurl]">$vbphrase[members_list]</a></td>
		<td class="vbmenu_control"><a href="calendar.php?$session[sessionurl]">$vbphrase[calendar]</a></td>
		<if condition="$show['popups']">		
			<if condition="$show['searchbuttons']">
				<if condition="$show['member']">
				<td class="vbmenu_control"><a href="search.php?$session[sessionurl]do=getnew" accesskey="2">$vbphrase[new_posts_nav]</a></td>
				<else />
				<td class="vbmenu_control"><a href="search.php?$session[sessionurl]do=getdaily" accesskey="2">$vbphrase[todays_posts]</a></td>
				</if>
				<td id="navbar_search" class="vbmenu_control"><a href="search.php?$session[sessionurl]" accesskey="4">$vbphrase[search]</a> <script type="text/javascript"> vbmenu_register("navbar_search"); </script></td>
			</if>
			<if condition="$bbuserinfo['userid']">
				<td id="usercptools" class="vbmenu_control"><a href="#usercptools">$vbphrase[quick_links]</a> <script type="text/javascript"> vbmenu_register("usercptools"); </script></td>		
			</if>
		<else />		
			<if condition="$show['searchbuttons']">
				<td class="vbmenu_control"><a href="search.php?$session[sessionurl]" accesskey="4">$vbphrase[search]</a></td>
				<if condition="$show['member']">
				<td class="vbmenu_control"><a href="search.php?$session[sessionurl]do=getnew" accesskey="2">$vbphrase[new_posts_nav]</a></td>
				<else />
				<td class="vbmenu_control"><a href="search.php?$session[sessionurl]do=getdaily" accesskey="2">$vbphrase[todays_posts]</a></td>
				</if>
			</if>
			<td class="vbmenu_control"><a href="forumdisplay.php?$session[sessionurl]do=markread">$vbphrase[mark_forums_read]</a></td>
			<if condition="$bbuserinfo['userid']">			
				<td class="vbmenu_control"><a href="#" onclick="window.open('misc.php?$session[sessionurl]do=buddylist&amp;focus=1','buddylist','statusbar=no,menubar=no,toolbar=no,scrollbars=yes,resizable=yes,width=250,height=300'); return false;">$vbphrase[open_buddy_list]</a></td>			
			</if>			
		</if>
		<if condition="$bbuserinfo['userid']">
			<td class="vbmenu_control"><a href="login.php?$session[sessionurl]do=logout&amp;u=$bbuserinfo[userid]" onclick="return log_out()">$vbphrase[log_out]</a></td>
		</if>
	</tr>
	</table>
</div>
<!-- / nav buttons bar -->
There's the buttons

HTML Code:
<br />
<br />
These breaks control the spacing between the navbar and the body of the page. Again, you can alter this if you want to change this spacing.

HTML Code:
<if condition="$show['popups']">
<!-- NAVBAR POPUP MENUS -->
	<if condition="$show['searchbuttons']">
	<!-- header quick search form -->
	<div class="vbmenu_popup" id="navbar_search_menu" style="display:none">
		<table cellpadding="4" cellspacing="1" border="0">
		<tr>
			<td class="thead">$vbphrase[search_forums]</td>
		</tr>
		<tr>
			<td class="vbmenu_option" title="nohilite">
			<form action="search.php" method="post">
				<input type="hidden" name="do" value="process" />
				<input type="hidden" name="showposts" value="0" />
				<input type="text" class="bginput" name="query" size="20" />$gobutton<br />
			</form>
			</td>
		</tr>
		<tr>
			<td class="vbmenu_option"><a href="search.php?$session[sessionurl]" accesskey="4">$vbphrase[advanced_search]</a></td>
		</tr>
		</table>
	</div>
	<!-- / header quick search form -->
	</if>
	<if condition="$show['member']">
	<!-- user cp tools menu -->
	<div class="vbmenu_popup" id="usercptools_menu" style="display:none">
		<table cellpadding="4" cellspacing="1" border="0">
		<tr><td class="thead">$vbphrase[quick_links]</td></tr>		
		<if condition="$vboptions['enablesearches']"><tr><td class="vbmenu_option"><a href="search.php?$session[sessionurl]do=getnew">$vbphrase[new_posts_nav]</a></td></tr></if>
		<tr><td class="vbmenu_option"><a href="forumdisplay.php?$session[sessionurl]do=markread">$vbphrase[mark_forums_read]</a></td></tr>
		<tr><td class="vbmenu_option"><a href="#" onclick="window.open('misc.php?$session[sessionurl]do=buddylist&amp;focus=1','buddylist','statusbar=no,menubar=no,toolbar=no,scrollbars=yes,resizable=yes,width=250,height=300'); return false;">$vbphrase[open_buddy_list]</a></td></tr>
		<tr><td class="thead"><a href="usercp.php?$session[sessionurl]">$vbphrase[user_control_panel]</a></td></tr>
		<if condition="$show['siglink']"><tr><td class="vbmenu_option"><a href="profile.php?$session[sessionurl]do=editsignature">$vbphrase[edit_signature]</a></td></tr></if>
		<if condition="$show['avatarlink']"><tr><td class="vbmenu_option"><a href="profile.php?$session[sessionurl]do=editavatar">$vbphrase[edit_avatar]</a></td></tr></if>
		<tr><td class="vbmenu_option"><a href="profile.php?$session[sessionurl]do=editprofile">$vbphrase[edit_profile]</a></td></tr>
		<tr><td class="vbmenu_option"><a href="profile.php?$session[sessionurl]do=editoptions">$vbphrase[edit_options]</a></td></tr>
		<tr><td class="thead">$vbphrase[miscellaneous]</td></tr>
		<if condition="$show['pmstats']"><tr><td class="vbmenu_option"><a href="private.php?$session[sessionurl]">$vbphrase[private_messages]</a></td></tr></if>
		<tr><td class="vbmenu_option"><a href="subscription.php?$session[sessionurl]">$vbphrase[subscribed_threads]</a></td></tr>
		<tr><td class="vbmenu_option"><a href="member.php?$session[sessionurl]u=$bbuserinfo[userid]">$vbphrase[my_profile]</a></td></tr>
		<if condition="$show['wollink']"><tr><td class="vbmenu_option"><a href="online.php?$session[sessionurl]">$vbphrase[whos_online]</a></td></tr></if>
		</table>
	</div>
	<!-- / user cp tools menu -->
	</if>
<!-- / NAVBAR POPUP MENUS -->
</if>
And there's the menus. Follow the commentary text (the stuff between the <!-- and --> marks.

Time to get down to business.

Ok, so much for the review, let's do something fun - put the logged in user's avatar into the navbar. This is useful on boards where a log of people use multiple user accounts - it lets them know who they are logged in at a glance (assuming the avatars are distinct).

This is actually pretty straightforward. First we fetch the user's avatar. In your PHPINCLUDE_START template plug in this code at the end.

PHP Code:
// #### Fetch avatar ######################
        
if ($bbuserinfo['userid'])
            {
                
// Fetch Avatar for Forumhome display
                
require_once('./includes/functions_user.php');
                
$bbuseravatarurl fetch_avatar_url($bbuserinfo['userid']);
    
                if (!
$bbuseravatarurl
                    {
                        
$bbuseravatarurl $stylevar['imgdir_misc'] . '/noavatar.gif';
                    }
            } 
For those users that don't have avatars, you need to create a "noavatar.gif" image for them. If you already have one (say, from vba_cmps) then just make sure it's in the misc directory.

Now, going back to the navbar let's plug this in like so... Find this code in the navbar

HTML Code:
	<!-- / login form -->
		</td>
	</if>	
And add this code below:

HTML Code:
<if condition="$bbuseravatarurl"><td><a href="profile.php?do=editavatar$sessionurl"><img src="$bbuseravatarurl" title="Click to Edit" border="0"></a></td></if>
Unless your forum uses small avatars, you'll probably want to modify the code some more to get the formatting to look nice, but the hard part is over at this point.

This concludes lesson 7. Expect to see more of these in the coming few days as I have more spare time now that the Christmas break has began.

vblts.ru supports vBulletin®, 2022-2024