Go Back   vb.org Archive > vBulletin Article Depository > Read An Article > vBulletin 4 Articles
FAQ Community Calendar Today's Posts Search

Reply
 
Thread Tools
[HOW TO - vB4] Rendering templates and registering variables - a short guide
cellarius's Avatar
cellarius
Join Date: Aug 2005
Posts: 1,987

 

Show Printable Version Email this Page Subscription
cellarius cellarius is offline 11-15-2009, 10:00 PM

Introduction

Starting with vB4, templates no longer get output using eval:
PHP Code:
eval('$mytemplate = "' fetch_template('mytemplate') . '";'); 
is outdated.
What's more: Variables and arrays from plugins that are executed on a page no longer can automatically be accessed in the templates of that page. They need to be registered first.
.
Basic functionality to render templates and register all variables/arrays you want to use inside

PHP Code:
/* Some Code, setting variables, (multidimensional) array */
$my_var "abc";
$my_array = array(
        
'key1' => 'value1',
        
'key2' => array(
                '
key21' => 'value21',
                '
key22' => 'value22'
        '
)
    );

/* render template and register variables */
$templater vB_Template::create('mytemplate');
    
$templater->register('my_var'$my_var);
    
$templater->register('my_array'$my_array);
$templater->render(); 
  • The first line provides the template that is to be rendered, using the new vB_Template class (vB_Template::create). The method gets passed the name of the template as an argument.
  • The following two lines register a variable and an array that we want to use in our template. Arguments passed are 1. the name you want to use to access the variable, and 2. the variable from the code you want to register. You can register as many variables/arrays as you want. Just remember you have to register every variable and array that you want to use in your custom template in this way. If you don't register them, they will not be available.
  • The fourth line renders the template ($templater->render()).
In the template you know will be able to use the registered variables/arrays in this way:
HTML Code:
{vb:raw my_var}
{vb:raw my_array.key1}
{vb:raw my_array.key2.key21}
Note the last one: multidimensional arrays are perfectly possible.
.
.
.
Now, with the result of the rendering we can do several things:
.
Output template directly - custom pages


PHP Code:
$templater vB_Template::create('mytemplate');
    
$templater->register_page_templates(); 
    
$templater->register('my_var'$my_var);
    
$templater->register('my_array'$my_array);
print_output($templater->render()); 
This immediatly outputs the template. Use this if you have created your own page, for example.
Note the second line, which is special for this type of use:
PHP Code:
$templater->register_page_templates(); 
This auto-registers the page level templates header, footer and headinclude that you will use in the template of your custom page.
.
Use a template hook


PHP Code:
$templater vB_Template::create('mytemplate');
    
$templater->register('my_var'$my_var);
    
$templater->register('my_array'$my_array);
$template_hook[forumhome_wgo_pos2] .= $templater->render(); 
The template will be shown using the choosen template hook (for example: $template_hook[forumhome_wgo_pos2]). See the dot before the = in the last line? The hook may be used by other modifications, too, so we don't want to overwrite it, but rather append our code to it, conserving everything that might already be there.
.
Save into a variable for later use in custom template
PHP Code:
$templater vB_Template::create('mytemplate');
    
$templater->register('my_var'$my_var);
    
$templater->register('my_array'$my_array);
$mytemplate_rendered $templater->render(); 
Now we have saved the rendered template into a variable. This variable in turn we can later on register in another template, if we want:
PHP Code:
$templater vB_Template::create('my_other_template');
     
$templater->register('my_template_rendered'$my_template_rendered);
 
print_output($templater->render()); 
Again, inside my_other_template we now could call
HTML Code:
{vb:raw my_template_rendered}
If you're running the first template call inside a loop, you may want to use .= instead of = in the last line, so that the results of every loop get added instead of overwriting the existing. But that depends, of course.
.
Save into an array and preregister to use in an existing/stock template

PHP Code:
$templater vB_Template::create('mytemplate');
    
$templater->register('my_var'$my_var);
    
$templater->register('my_array'$my_array);
$templatevalues['my_insertvar'] = $templater->render();
vB_Template::preRegister('FORUMHOME'$templatevalues); 
  • This is another, more flexible method to save the rendered template into a variable for future use in an already existing template. In this example, we want to show our own rendered template on forumhome.
  • Problem is: We have no direct way to register variables for already existing templates like FORUMHOME. It's created and rendered in the files, and we don't want to mess there.
  • To help with this, a new method was created for vB_Template class, called preRegister. Using this, we can pass our data to FORUMHOME before it is rendered. Note that the data needs to be saved into an array ($templatevalues['my_insertvar']), a simple variable will throw an error. In the last line the array is preregistered; you need to pass as arguments 1. the name of the existing template and 2. the array that contains the data. Again, this can be done for as many arrays as needed.
  • Of course, the preRegister functionality can be used for any kind of variables or arrays, no matter whether you have saved a rendered template (like in our example) into it or it contains just a simple boolean true/false statement.
To access the data inside the template it was preregistered for use:
HTML Code:
{vb:raw my_insertvar}
Note: it is not {vb:raw templatevalues.my_insertvar}!

Essentially the same as what I put for preRegister would be the following two lines. They could replace the last two lines in the above php codebox:
PHP Code:
$my_insertvar $templater->render();
vB_Template::preRegister('FORUMHOME',array('my_insertvar ' => $my_insertvar)); 
Of course you could add further pairs to that array if you need to preregister more than one variable.
.
.
Bonus track: ...whatever you do, cache your templates!

Now you know how to get your templates on screen - once you succeeded in doing that, make sure to do it in a fast and ressource saving manner: make use of vB's template cache. To see whether your templates are cached or not, activate debug mode by adding $config['Misc']['debug'] = true;to your config.php (don't ever use that on your live site!). Among the debug info is a list of all templates called, and non-cached templates will show up in red.

To cache your templates, add a plugin at hook cache_templates with the following code:
PHP Code:
// for a single template
$cache[] = 'mytemplate'

// for more than one templates in one step
$cache array_merge((array)$cache,array(
    
'mytemplate',
    
'myothertemplate',
    
'mythirdtemplate'
)); 
.
.
Hope this helps!
-cel

----
Addendum - There are now two blog posts on vb.com related to this topic:
http://www.vbulletin.com/forum/entry...in-4-templates
http://www.vbulletin.com/forum/entry...-4-based-files
Reply With Quote
  #232  
Old 05-15-2012, 09:36 AM
Seductor Seductor is offline
 
Join Date: May 2011
Posts: 128
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Oh, and is there any way to show all my array cells If I don't know which size is the array?

Edited: I suspect that it is done in this way.
Code:
<vb:each from="my_array" key="key1" value="my_result">
    {vb:var my_result}
</vb:each>
I am doing something wrong. I have this:
resource(46) of type (mysql result)

And each row is:
Code:
array(21) { ["id"]=> string(2) "18" ["name"]=> string(5) "ABRIR" ["description"]=> string(23) "Iniciar la interacci?n." ["userid"]=> string(4) "2858" ["username"]=> string(20) "Seducci?n Cient?fica" ["dateline"]=> string(10) "1311875182" ["lastupdate"]=> string(10) "1311933838" ["categoryid"]=> string(1) "1" ["status"]=> string(1) "1" ["ipaddress"]=> string(13) "81.202.205.41" ["attach"]=> string(1) "0" ["threadid"]=> string(1) "0" ["lastupdater"]=> string(20) "Seducci?n Cient?fica" ["lastupdaterid"]=> string(4) "2858" ["tags"]=> string(16) "abrir,escalada 1" ["popup"]=> string(23) "Iniciar la interacci?n." ["views"]=> string(1) "0" ["votenum"]=> string(1) "0" ["votetotal"]=> string(1) "0" ["linkurl"]=> string(7) "http://" ["banner"]=> string(7) "http://" }
I'm doing this in my template:
Code:
<vb:each from="my_query" value="sentence">
   Test {vb:raw sentence.name}
</vb:each>
Notice this: Test {vb:raw sentence.name}

But It doesn't show nothing, as if the each is not being executed. I expected to show, at least, 46 Test words.
Reply With Quote
  #233  
Old 05-15-2012, 12:52 PM
kh99 kh99 is offline
 
Join Date: Aug 2009
Location: Maine
Posts: 13,185
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by Seductor View Post
I am doing something wrong. I have this:
resource(46) of type (mysql result)

You are registering the return from one of the query functions. You need to call fetch_array() to get an array for each row, like:

Code:
$results = $db->query_read("some sql");
while ($row = $db->fetch_array($results))
{
    // do something with $row
}

Of course each row is an array (even if you only selected one column). If you are selecting one column from a number of matching rows, you won't get an array with all the matching values, you still get an array for each row. If you want an array with all the matching values you'd have to build that yourself.

Note also that you don't *have* to register an array to your template and use vb:each - you could format your own html string in the while loop above, then just register the string.
Reply With Quote
  #234  
Old 05-26-2012, 07:20 PM
tbworld tbworld is offline
 
Join Date: Oct 2008
Posts: 2,126
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

[QUOTE=Boofo;2287132]Try this in the parse_templates hook:

Boofo, I was working on specialized routine and trying to use some of the vb-ojects to solve my problem when I came across the code you posted here. This redirected me to the right vb routines. Thanks so much for sharing!
Reply With Quote
  #235  
Old 05-26-2012, 08:11 PM
Dave-ahfb Dave-ahfb is offline
 
Join Date: Mar 2002
Posts: 117
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

I have a problem on a page. I can use the variable {vb:raw companyname} in the places of the template that I need to. However when I want to place it in my navbits which are created by the php file it just echos itself.
Code:
$navbits = construct_navbits(array('' => '&nbsp;</span></li><li class="navbit"><span><a href="/">Home</a></span></li><li class="navbit"><span><a href="../hostindex.php">Web Hosting</a></span></li><li class="navbit lastnavbit"><span>{vb:raw companyname}
 
')); 
$navbar = render_navbar_template($navbits); 

// ###### YOUR CUSTOM CODE GOES HERE ##### 
$pagetitle = '$companyname'; 
$templater = vB_Template::create('headerincludea'); 
$headerincludea = $templater->render(); 

$templater = vB_Template::create('webhost-php');
$templater->register('companyname', $companyname);
$templater->render();
 

 
$templater->register_page_templates(); 
$templater->register('navbar', $navbar); 
$templater->register('pagetitle', $pagetitle); 
$templater->register('headerincludea', $headerincludea); 


print_output($templater->render());
Reply With Quote
  #236  
Old 05-26-2012, 08:43 PM
kh99 kh99 is offline
 
Join Date: Aug 2009
Location: Maine
Posts: 13,185
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Try putting $companyname in your navbits instead of {vb:raw companyname} Since it's in a single-quoted string you need to use concatenation, like:

Code:
$navbits = construct_navbits(array('' => '&nbsp;</span></li><li class="navbit"><span>
<a href="/">Home</a></span></li><li class="navbit"><span>
<a href="../hostindex.php">Web Hosting</a></span></li>
<li class="navbit lastnavbit"><span>' . $companyname . '
 
'));
Reply With Quote
  #237  
Old 05-26-2012, 08:57 PM
Dave-ahfb Dave-ahfb is offline
 
Join Date: Mar 2002
Posts: 117
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by kh99 View Post
Try putting $companyname in your navbits instead of {vb:raw companyname} Since it's in a single-quoted string you need to use concatenation, like:

Code:
$navbits = construct_navbits(array('' => '&nbsp;</span></li><li class="navbit"><span>
<a href="/">Home</a></span></li><li class="navbit"><span>
<a href="../hostindex.php">Web Hosting</a></span></li>
<li class="navbit lastnavbit"><span>' . $companyname . '
 
'));
Thanks a ton! I had tried $companyname without the '. .' and had the same results (echoed $companyname.
Reply With Quote
  #238  
Old 05-31-2012, 11:57 AM
Chr1sj Chr1sj is offline
 
Join Date: May 2012
Posts: 2
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Can anyone help me out what i'm doing wrong?

i'm trying to add something to the Default navbar template. (a server status for my game server)
but first i'm trying out the example but i can't get it to work.

This is my plugin setup.
Product : vBulletin
Hook location: Global_start
Title: server Status
execution order :5

Plugin code:
Code:
/* Some Code, setting variables, (multidimensional) array */
$my_var = "abc";

/* render template and register variables */
$templater = vB_Template::create('navbar');
    $templater->register('my_var', $my_var);
$templater->render();
Then in the navbar template of my default style i add
Code:
{vb:raw my_var}
even tried withing
Code:
 <p>{vb:raw my_var}</p>
Anyone able to help me out ?

Edit: and Enable Plugin/Hook System is enabled also
Reply With Quote
  #239  
Old 05-31-2012, 12:02 PM
kh99 kh99 is offline
 
Join Date: Aug 2009
Location: Maine
Posts: 13,185
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

You don't want to render the navbar template because the vbulletin code already does that for you. To get your variable registered to that template you want to use preRegister, like;

Code:
$my_var = "abc";
vB_Template::preRegister('navbar', array('my_var' => $my_var));
Reply With Quote
Благодарность от:
Chr1sj
  #240  
Old 05-31-2012, 12:28 PM
Chr1sj Chr1sj is offline
 
Join Date: May 2012
Posts: 2
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Thanks a lot. :up:
Now i can start creating my plugin understanding the preRegister.
Reply With Quote
  #241  
Old 06-10-2012, 08:41 AM
codewaggle codewaggle is offline
 
Join Date: Dec 2011
Posts: 8
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by Abe Babe View Post
I have a template that I need to insert into multiple pre-existing templates. After a bit of struggling, I have managed to get the following code running.

Code:
$templater = vB_Template::create('layout_start');
    $templater->register('my_var', $my_var);
$templatevalues['start_insertvar'] = $templater->render();
vB_Template::preRegister('FORUMHOME', $templatevalues);
I have two questions. Is there any way to preRegister for more than one pre-existing template (or a global registration), or do I have to create Plugins for every page I want to add this to (*groan*)? And what is the best hook to have this on. I am currently using 'parse_templates'.
------------------------------------

I'm doing this using $GLOBALS[templatevalues] = $templatevalues; rather than preRegister().

Code:
$templater = vB_Template::create('layout_start');
$templater->register('my_var', $my_var);
$templatevalues['start_insertvar'] = $templater->render();

$GLOBALS[templatevalues] = $templatevalues;

UPDATE: (Thanks to kh99 for his guidance.)
The following line isn't needed and was used incorrectly:
$template->register_global('templatevalues');

Then use this in the templates where you want the output to appear:
Code:
{vb:raw GLOBALS.templatevalues.start_insertvar}
Be Well
Reply With Quote
Благодарность от:
BirdOPrey5
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 07:39 PM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.05188 seconds
  • Memory Usage 2,398KB
  • Queries Executed 26 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (14)bbcode_code
  • (3)bbcode_html
  • (10)bbcode_php
  • (3)bbcode_quote
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)modsystem_article
  • (1)navbar
  • (4)navbar_link
  • (120)option
  • (1)pagenav
  • (1)pagenav_curpage
  • (4)pagenav_pagelink
  • (1)pagenav_pagelinkrel
  • (11)post_thanks_box
  • (19)post_thanks_box_bit
  • (11)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (3)post_thanks_postbit
  • (11)post_thanks_postbit_info
  • (10)postbit
  • (11)postbit_onlinestatus
  • (11)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • fetch_musername
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • post_thanks_function_fetch_thanks_bit_start
  • post_thanks_function_show_thanks_date_start
  • post_thanks_function_show_thanks_date_end
  • post_thanks_function_fetch_thanks_bit_end
  • post_thanks_function_fetch_post_thanks_template_start
  • post_thanks_function_fetch_post_thanks_template_end
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • pagenav_page
  • pagenav_complete
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete