[How-To] Plugins for Template Edits (Adv. Version) - What your mother didn't tell you
Plugins for Template Edits (Advanced Version) - What your mother didn't tell you about templates
In this tutorial we are going to tackle some of the more mysterious and tricky aspects of using the plugin system to perform automatic edits of templates in vBulletin. I've added the "what your mother didn't tell you about templates" to the title because I figured all this out after a lot of banging my head against the wall. I didn't find any information about this anywhere, so I figured the best thing to do was share what I've learned. Before we start This tutorial is going to build on material I covered in my earlier template tutorial - Using Plugins for Automatic Template Edits. Please read it and understand it before reading this tutorial. Even if you think you know everything, please at least go back and skim-read it. During this tutorial we are also going to use some of the tools and techniques I covered in the tutorial called Debugging Your Plugin - how to save time and frustration. There is an include file on that thread containing some functions that we'll be using. You should also go and read and understand the debugging tutorial before continuing with the current tutorial. Why do we need to know this stuff? Because you want to do automatic template edits, but you learned in the previous tutorial that you have to stay away from any conditional statements in a template, tab characters, new lines. That's not much fun! Maybe you've come to this tutorial because you've been scratching your head trying to wonder why you can't seem to get a conditional statement to work when you change a template with a plugin. You've come to the right place, because we are going to get our hands dirty in this tutorial! What's the main issue here? When you look at a template in the template editor you are not seeing what is really stored in the template, but rather a sanitised version which is easy for you to understand and edit. In reality, the template is converted into PHP code when it is stored or used. Therefore we need to look at the "wiring under the board" if we really want to be successful at using the plugin system to edit templates automatically. You may never look at a template the same way again... So what does a template really look like? OK, you already understand how to use str_replace and you know how to make a hex dump of a template (because you've read and understood the previous two tutorials), so you understand that unless we can correctly identify the exact string to replace and insert code that will actually work, there's little point in attempting this. The first thing we need to do is actually look at a template. We are going to use the dump_hex() function to do this. Since we want to make our life easy, we are probably also going to use the print_log() function to write the data to a log file for us to check. Remember that these functions are not part of PHP or vBulletin - but you already know that from the debugging tutorial and you downloaded the file attached to the debugging tutorial with those functions included. I know you want to look at the template, but first we have to set up our plugin and decide what to look for. Before we start - is your template cached? Remember to consider at which hook your str_replace is going to execute. If you run it at a hook like global_start, was it placed into the $globaltemplates array so that the template in question is put into the template cache? If you are performing a str_replace on built-in vBulletin templates this isn't an issue as they are always cached in the relevant places anyway. However, if you are changing other templates from other mods (or your own) with this method, then it will not work unless your template it is in the cache first! Create your plugin Create a plugin, and execute it at a sensible hook for the template we are going to work on. We will work with two templates, WHOSONLINE and whosonlinebit. Create your plugin at online_start. Our plugin is going to add a new column to our who's online display to display the country where a user is logging on from. The underlying variables used for this won't function (unless you have one of my forthcoming mods installed already), but we should be able to at least create an empty column. You'll remember that we started all our plugins with something like this: Code:
if ($vbulletin->userinfo['userid'] == 1) Examine the template in the editor Now go and load the the WHOSONLINE template via the style manager. We are going to insert the code highlighted in bold. Locate the area around this insertion point and try to figure out which string we should try to match to make the replacement. Code:
<if condition="$show['ip']"><td class="thead">$vbphrase[ip_address]</td></if> Dumping the template with dump_hex() Insert the following code in the middle of the plugin you just created: Code:
printlog(dump_hex($vbulletin->templatecache['WHOSONLINE'])); Code:
0000 24 73 74 79 6c 65 76 61 72 5b 68 74 6d 6c 64 6f $styleva r[htmldo Code:
printlog(dump_hex($vbulletin->templatecache['WHOSONLINE'], true)); Code:
1600 $vbphrase[location_temp]</a> $sortarrow[location]</td>...".(($show['ip']) ? ("<t Code:
printlog(dump_hex($vbulletin->templatecache['WHOSONLINE'], false, 2, 16)); Code:
0660 72 74 61 72 72 6f 77 5b 6c 6f 63 61 74 69 6f 6e 5d 3c 2f 74 64 3e 0d 0a 09 22 2e 28 28 24 73 68 rtarrow[location ]</td>...".(($sh What can you see? You can see that we have a few changes. I'll list some statements that we had in the template, followed by what they actually become when they are stored in the template in green: Code:
<if condition="$show['ip']"> ".(($show['ip']) ? (" The only other thing to note in this output is where you see 0d 0a - this is a new line. Where you see 09, this a tab. Since these are non-printable characters they will appear in the ASCII side as dots. Remember these are hex values, we'll be working with their decimal equivalents in a minute. Constructing the required strings Now we need to build some code to find and replace strings within our template. You'll remember we did the same thing in the first tutorial, but now we are going to get a little more complicated. Let start by entering the following code: Code:
$ifstart = '".(('; // equates to first half of if - <if condition=" Now that we've made a few variables to help us construct the string we are going to find, let's add another line: Code:
$find = $ifstart . '$GLOBALS[\'vbulletin\']->options[\'showimicons\']' . $ifend; Code:
".(($GLOBALS['vbulletin']->options['showimicons']) ? (" Now we can go ahead and built the string we would like to replace: Code:
$replace = $ifstart . '$show[\'country\']' . $ifend . '<td class=\"thead\">$vbphrase[show_country]</td>' . $endif; Code:
$vbulletin->templatecache['WHOSONLINE'] = str_replace($find, $replace . $find, $vbulletin->templatecache['WHOSONLINE']); The final code Let's just review the final code all in one block, without the hex dumps or the additional conditional: Code:
$endif = '") : (""))."'; Using these ideas in your own plugins What we have seen so far has not been an exhaustive list of techniques, but now you can use tools like dump_hex to discover the true variable names and conditional syntax in templates when developing your own plugins. There are many other things inside a template that we didn't list here. What about the <else /> tag? Remember that now you know how to include newlines and tabs in your searches - don't get carried away. If anybody has changed their template by removing or adding tabs or newlines, your search string may not match. Try to find the best possible insertion point by looking for a place where there is less chance of a change being made by someone else. The smallest possible strings, which are still unique, are best. For example, there would be little point in searching and replacing based on <td class= because this appears many times within most templates. The bottom line - use these techniques to employ a more structured and methodical approach to your automatic template edits. By actually checking the results before and afterwards and determining in advance exactly what you need to do, you can save yourself a lot of time by avoiding "trial and error". Alternative methods to see the template Of course there are other methods to look inside the template, I've just listed the ones I use the most. Rather than going to the template cache, you could display it in your log or to screen simply by accessing fetch_template('your_template_name'). You should be aware that this is only good for reading the template, if you want to change it, you'll still have to go directly to the template cache. Remember also that if you try to display the output in a browser it might not work so well since the template contains HTML formatting. If you are outputting to the command line this should be no problem. You could also go and look at the template directly in the database if you like. You'll need the appropriate tools, such as phpmyadmin, but if you look in the table called "template" you'll find two columns - "template" and "template_un". The first is the template as it appears to PHP (and the template cache), the second is the same template, but stored in the "human-readable" form that you see when using the style manager. Be careful though - depending on your tools, you will see newlines and tabs as they appear, rather than they actually are - you'll still need a hex dump to see exactly which non-printable characters have been stored. What's next? The good news is that there is an easier way. However, it is important for you to understand how this process works, which is why this was such a long and boring tutorial. There will be a third and final tutorial in this series which will show you a much easier way to do these automatic edits. |
Helpful. :)
|
Ah, this explains a problem I'm having trying to insert some code right before a conditional. Thanks for the writeup! :cool:
Quote:
|
hardcore tuitorial mfyvie, very helpful - thanks for explaining how to do this, and preparing the useful devtools.php file
|
There are quite a few "Standard" template hooks in the standard templates
For example, I use this to auto insert the itrader template edit into the postbit and postbit_legacy template. It is fired at the postbit_display_complete hook. Code:
eval('$template_hook[\'postbit_userinfo_left\'] .= "' . fetch_template('cg_itrader_postbit_link') . '";'); I went through and pulled the postbit and postbit_legacy and the navbar template hooks along with when they should be fired. Code:
template name="navbar" |
Personally I find this works a bit easier, the catch is any special tags like conditionals need to be properly started and ended:
PHP Code:
|
Quote:
|
All times are GMT. The time now is 12:31 AM. |
Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information | |
---|---|
|
|
More Information | |
Template Usage:
Phrase Groups Available:
|
Included Files:
Hooks Called:
|