ВходПользовательПароль
   
Регистрация
Регистрация
Помощь
Помощь
Поиск
Поиск
Gosudar.com.ru  
  

Меню сайта
Навигация
Объявления Объявления
Блоги Блоги
Файловый архив Файловый архив
Последние Последние
Гостевая Гостевая
Контакты Контакты
Личный Раздел
Вход Вход
Регистрация Регистрация
Cms R3-born
Библиотека Библиотека
Файлы R3-born Файлы R3-born
Разработка(блог) Разработка(блог)
Демо-модули
Фотоальбом Фотоальбом
Новости Новости
Форум Форум

Счётчик
5643056430564305643056430
Главная » Библиотека

Библиотека

Библиотека  » CMS R3-born  » Документация
Template Engine (Advanced)
Описание Manual. English
Автор martin Число Январь 04 2008, 22:33 Тип FAQ
Категория Документация
Просмотров 1272
Трекбек URL для этой записи: Трекбек
  Голосов 0


Template Engine (Advanced)
Manual. English
The template engine in R3-born uses portions of the eXtreme Styles MOD, plus some other enhancements/optimisations of my own. Therefore R3-born is compatible with most of the features provided by the eXtreme Styles MOD. This includes...

  • Fast templates compilation algorythm
  • Fast templates execution (even if not cached)
  • Cache system doesn't use the database
  • PHP code in templates. PHP code should start with <?php or <!-- PHP --> and end with ?> or <!-- ENDPHP --> Short tags are not allowed.
  • Unlimited <!-- BEGIN blah --><!-- END blah --> switches in one line.
  • Include other tpl files with <!-- INCLUDE file.tpl -->
  • Variable {LANG} that corresponds to current language. Can be used to create truly multi-lingual templates (you can use this in urls: "images/lang_{LANG}/icon_blah.gif").
  • Variable {PHP} that corresponds to file extension with session data. Can be used to avoid modding when you need to add some url (like "somescript.{PHP}" or "script.{PHP}test=1") Variable contains "?" or "&" at the end so you could easily add arguments to url.
  • Variable {TEMPLATE} that corresponds to current template directory (like "templates/subAndreas/"). Can be used to avoid filenames case confusion.
  • Simple template cache management
  • Tokens IF, ELSEIF, ELSE, ENDIF, DEFINE, UNDEFINE
  • Support for BEGINELSE


Variables

All template variables should be named appropriately (using underscores for spaces), language entries should be prefixed with L_, system data with S_, urls with U_, javascript urls with UA_, language to be put in javascript statements with LA_, all other variables should be presented 'as is'.

L_* template variables are automatically trie to map to the corresponding language entry. if the code does not set (and therefore overwrite) this variable specifically. For example {L_USERNAME} maps to $lang['USERNAME']. The LA_* template variables are handled within the same way as L_* variables, but properly escaped to be put in javascript code. This should reduce the need to assign loads of new lang vars in Modules and Blocks.

Including files

We now have INCLUDE. This takes the simple form:

<!-- INCLUDE filename -->

In R3-born the template designer can output what they like. Note that you can introduce new templates (i.e. other than those in the default set) using this system and include them as you wish without the need to modify loads of files as wwas the case with phpBB 2.0.x.

Basic Loops

To recap, loops in templates start with <!-- BEGIN something --> and ends with <!-- END something -->.

 Код:  
<!-- BEGIN loopname -->
   markup, {loopname.X_YYYYY}, etc.
<!-- END loopname -->


To use a variable inside current loop use $loopname_item['VARIABLE_NAME
'] where 'loopname' is name of last loop.

To get number of items in current loop use $loopname_count, to get current item in loop use $loopname_i

Extended Blocks/Loops
Loops have been extended with an extension to begin, called BEGINELSE:

 Код:  
<!-- BEGIN loop -->
   markup
<!-- BEGINELSE -->
   markup
<!-- END loop -->


This will cause the markup between BEGINELSE and END to be output if the loop contains no values. This is useful for forums with no topics (for example) ... in some ways it replaces "bits of" the existing "switch_" type control (the rest being replaced by conditionals).

Another way of checking if a loop contains values is by prefixing the loops name with a dot:

 Код:  
<!-- IF .loop -->
   <!-- BEGIN loop -->
      markup
   <!-- END loop -->
<!-- ELSE -->
   markup
<!-- ENDIF -->


You are even able to check the number of items within a loop by comparing it with values within the IF condition:

 Код:  
<!-- IF .loop > 2 -->
   <!-- BEGIN loop -->
      markup
   <!-- END loop -->
<!-- ELSE -->
   markup
<!-- ENDIF -->


Nesting loops cause the conditionals needing prefixed with all loops from the outer one to the inner most. An illustration of this:

 Код:  
<!-- BEGIN firstloop -->
   {firstloop.MY_VARIABLE_FROM_FIRSTLOOP}

   <!-- BEGIN secondloop -->
      {firstloop.secondloop.MY_VARIABLE_FROM_SECONDLOOP}
   <!-- END secondloop -->
<!-- END firstloop -->


Sometimes it is necessary to break out of nested loops to be able to call another loop within the current iteration. This sounds a little bit confusing and it is not used very often. The following (rather complex) example shows this quite good - it also shows how you test for the first and last row in a loop (i will explain the example in detail further down):

 Код:  
<!-- BEGIN l_block1 -->
   <!-- IF l_block1.S_SELECTED -->
      <strong>{l_block1.L_TITLE}</strong>
      <!-- IF S_PRIVMSGS -->

         <!-- the ! at the beginning of the loop name forces the loop to be not a nested one of l_block1 -->
         <!-- BEGIN !folder -->
            <!-- IF folder.S_FIRST_ROW -->
               <ul class="nav">
            <!-- ENDIF -->

            <li><a href="{folder.U_FOLDER}">{folder.FOLDER_NAME}</a></li>

            <!-- IF folder.S_LAST_ROW -->
               </ul>
            <!-- ENDIF -->
         <!-- END !folder -->

      <!-- ENDIF -->

      <ul class="nav">
      <!-- BEGIN l_block2 -->
         <li>
            <!-- IF l_block1.l_block2.S_SELECTED -->
               <strong>{l_block1.l_block2.L_TITLE}</strong>
            <!-- ELSE -->
               <a href="{l_block1.l_block2.U_TITLE}">{l_block1.l_block2.L_TITLE}</a>
            <!-- ENDIF -->
         </li>
      <!-- END l_block2 -->
      </ul>
   <!-- ELSE -->
      <a class="nav" href="{l_block1.U_TITLE}">{l_block1.L_TITLE}</a>
   <!-- ENDIF -->
<!-- END l_block1 -->


Let us first concentrate on this part of the example:

 Код:  
<!-- BEGIN l_block1 -->
   <!-- IF l_block1.S_SELECTED -->
      markup
   <!-- ELSE -->
      <a class="nav" href="{l_block1.U_TITLE}">{l_block1.L_TITLE}</a>
   <!-- ENDIF -->
<!-- END l_block1 -->


Here we open the loop l_block1 and doing some things if the value S_SELECTED within the current loop iteration is true, else we write the blocks link and title. Here, you see {l_block1.L_TITLE} referenced - you remember that L_* variables get automatically assigned the corresponding language entry? This is true, but not within loops. The L_TITLE variable within the loop l_block1 is assigned within the code itself.

Let's have a closer look to the markup:

 Код:  
<!-- BEGIN l_block1 -->
.
.
   <!-- IF S_PRIVMSGS -->

      <!-- BEGIN !folder -->
         <!-- IF folder.S_FIRST_ROW -->
            <ul class="nav">
         <!-- ENDIF -->

         <li><a href="{folder.U_FOLDER}">{folder.FOLDER_NAME}</a></li>

         <!-- IF folder.S_LAST_ROW -->
            </ul>
         <!-- ENDIF -->
      <!-- END !folder -->

   <!-- ENDIF -->
.
.
<!-- END l_block1 -->


The <!-- IF S_PRIVMSGS --> statement clearly checks a global variable and not one within the loop, since the loop is not given here. So, if S_PRIVMSGS is true we execute the shown markup. Now, you see the <!-- BEGIN !folder --> statement. The exclamation mark is responsible for instructing the template engine to iterate through the main loop folder. So, we are now within the loop folder - with <!-- BEGIN folder --> we would have been within the loop l_block1.folder automatically as is the case with l_block2:

 Код:  
<!-- BEGIN l_block1 -->
.
.
   <ul class="nav">
   <!-- BEGIN l_block2 -->
      <li>
         <!-- IF l_block1.l_block2.S_SELECTED -->
            <strong>{l_block1.l_block2.L_TITLE}</strong>
         <!-- ELSE -->
            <a href="{l_block1.l_block2.U_TITLE}">{l_block1.l_block2.L_TITLE}</a>
         <!-- ENDIF -->
      </li>
   <!-- END l_block2 -->
   </ul>
.
.
<!-- END l_block1 -->


You see the difference? The loop l_block2 is a member of the loop l_block1 but the loop folder is a main loop.

You can also do comparison on S_FIRST_ROW and S_LAST_ROW. If you haven't guessed already - it is checking for the first iteration of the loop with S_FIRST_ROW and the last iteration with S_LAST_ROW.

 Код:  
<!-- IF folder.S_FIRST_ROW -->
   <ul class="nav">
<!-- ENDIF -->

<li><a href="{folder.U_FOLDER}">{folder.FOLDER_NAME}</a></li>

<!-- IF folder.S_LAST_ROW -->
   </ul>
<!-- ENDIF -->


This can come in handy quite often if you want to open or close design elements, like the above list. Let us imagine a folder loop build with three iterations, it would go this way:

 Код:  
<ul class="nav"> <!-- written on first iteration -->
   <li>first element</li> <!-- written on first iteration -->
   <li>second element</li> <!-- written on second iteration -->
   <li>third element</li> <!-- written on third iteration -->
</ul> <!-- written on third iteration -->


As you can see, all three elements are written down as well as the markup for the first iteration and the last one. Sometimes you want to omit writing the general markup - for example:

 Код:  
<!-- IF folder.S_FIRST_ROW -->
   <ul class="nav">
<!-- ELSEIF folder.S_LAST_ROW -->
   </ul>
<!-- ELSE -->
   <li><a href="{folder.U_FOLDER}">{folder.FOLDER_NAME}</a></li>
<!-- ENDIF -->


would result in the following markup:

 Код:  
<ul class="nav"> <!-- written on first iteration -->
   <li>second element</li> <!-- written on second iteration -->
</ul> <!-- written on third iteration -->


Just always remember that processing is taking place from up to down.

Conditionals/Control structures

The most significant addition to the R3-born template engine are conditions or control structures, "if something then do this else do that". The system is very similar to Smarty. This may confuse some people at first but it offers great potential and great flexibility with a little imagination. In their most simple form these constructs take the form:

 Код:  
<!-- IF expr -->
   markup
<!-- ENDIF -->


expr can take many forms, for example:

 Код:  
<!-- IF loop.S_ROW_COUNT is even -->
   markup
<!-- ENDIF -->


This will output the markup if the S_ROW_COUNT variable in the current iteration of loop is an even value (i.e. the expr is TRUE). You can use various comparison methods (standard as well as equivalent textual versions noted in square brackets) including (not, or, and, eq, neq, is should be used if possible for better readability):

== [eq]
!= [neq, ne]
<> (same as !=)
!== (not equivalent in value and type)
=== (equivalent in value and type)
> [gt]
< [lt]
>= [gte]
<= [lte]
&& [and]
|| [or]
% [mod]
! [not]
+
-
*
/
,
<< (bitwise shift left)
>> (bitwise shift right)
| (bitwise or)
^ (bitwise xor)
& (bitwise and)
~ (bitwise not)
is (can be used to join comparison operations)

Basic parenthesis can also be used to enforce good old BODMAS rules. Additionally some basic comparison types are defined:

even
odd
div

Beyond the simple use of IF you can also do a sequence of comparisons using the following:

 Код:  
<!-- IF expr1 -->
   markup
<!-- ELSEIF expr2 -->
   markup
   .
   .
   .
<!-- ELSEIF exprN -->
   markup
<!-- ELSE -->
   markup
<!-- ENDIF -->


Each statement will be tested in turn and the relevant output generated when a match (if a match) is found. It is not necessary to always use ELSEIF, ELSE can be used alone to match "everything else".

So what can you do with all this? Well take for example the colouration of rows in viewforum. In R3-born row colours are currently predefined within the source as either row1 or row2. However, it is possible to move this to the template, it may look a little daunting at first but remember control flows from top to bottom and it's not too difficult:

 Код:  
<table>
   <!-- IF loop.S_ROW_COUNT is even -->
      <tr class="row1">
   <!-- ELSE -->
      <tr class="row2">
   <!-- ENDIF -->
   <td>HELLO!</td>
</tr>
</table>


This will cause the row cell to be output using class row1 when the row count is even, and class row2 otherwise. The S_ROW_COUNT parameter gets assigned to loops by default. Another example would be the following:

 Код:  
<table>
   <!-- IF loop.S_ROW_COUNT > 10 -->
      <tr bgcolor="#FF0000">
   <!-- ELSEIF loop.S_ROW_COUNT > 5 -->
      <tr bgcolor="#00FF00">
   <!-- ELSEIF loop.S_ROW_COUNT > 2 -->
      <tr bgcolor="#0000FF">
   <!-- ELSE -->
      <tr bgcolor="#FF00FF">
   <!-- ENDIF -->
   <td>hello!</td>
</tr>
</table>


This will output the row cell in purple for the first two rows, blue for rows 2 to 5, green for rows 5 to 10 and red for remainder. So, you could produce a "nice" gradient effect, for example.

What else can you do? Well, you could use IF to do common checks on for example the login state of a user:

 Код:  
<!-- IF S_USER_LOGGED_IN -->
   markup
<!-- ENDIF -->


This could replace the existing (fudged) method in R3-born 0.1.1 using a zero length array and BEGIN/END.

DEFINE
You can define your own variables within the context of the .tpl by using something similar to the example below.

 Код:  
<!-- DEFINE $MY_TYPE= 1 -->


Once you have defined a variable you can then use it conditional structures, such as...

 Код:  
<!-- IF loop.ITEM_TYPE < $MY_TYPE --> 
   <!-- DEFINE $MY_TYPE = loop.ITEM_TYPE --> 
   markup
<!-- ELSEIF loop.ITEM_TYPE > 1 --> 
   <!-- DEFINE $MY_TYPE = 2 --> 
<!-- ENDIF -->


How to use PHP in templates.

This a contentious feature, but the ability to use PHP within the template has been introduced. This is achieved by enclosing the PHP within relevant tags.

NOTE! It is requested that template designers do not use PHP in their templates. The ability to include raw PHP was introduced primarily to allow end users to include banner code, etc. without modifying multiple files, it was not intended for general use. Therefore none of the official R3-born templates will use PHP.

You can use php in any tpl file except for bbcode.tpl (bbcode.tpl is parsed differently by R3-born so you can't use php in it).

PHP code should start with <?php or <!-- PHP --> and must end with ?> or <!-- ENDPHP -->. Short php tags (<? and <?=) are not allowed.

 Код:  
<!-- PHP -->
   echo "hello!";
<!-- ENDPHP -->


How to use PHP variables in templates

The Template class is included inside function, so if you want to use global variables inside php in a .tpl you must declare it as global before using it.

If you want to use global variables like $userdata, $lang or $images you must declare it global before using it.

 Код:  
<?php 
global $userdata; 
echo $userdata['username']; 
?>


How to include other PHP files in templates

To include local php file you can use usual include(); function. Path to file is relative to the root directory. Use the $root_path variable to make sure that path is always relative to R3-born root path.

If R3-born is installed in the directory '/R3-born/' and you want to include the file '/my_website/header.php' you should use this code in the .tpl:

 Код:  
<?php
global $root_path;
include($root_path . '../my_website/header.php'); ?>


If you want to include remote file via http you should use the readfile(); function.

 Код:  
<?php @readfile('http://somewhere/somefile.php'); ?>


Remote files are treated as html files, not as php files. And you'd better add @ before function to suppress warning in case if remote file is temporary unavailable.

How to use template variables, switches and loops in PHP

Template variables like {VAR1} and {postrow.VAR1} cannot be used in php inside templates directly.

To use root level variable like {VAR1} you should use this:

 Код:  
<?php 
echo 'variable VAR1 is ', $this->vars['VAR1']; 
?>


To use loop variables like {postrow.VAR1} you should use this:

 Код:  
<?php 
echo 'variable postrow.VAR1 is ', $postrow_item['VAR1']; 
?>


To use more complex variable like {loop1.loop2.loop3.VAR1} you should use only last loop item like this:

 Код:  
<?php 
echo 'variable loop1.loop2.loop3.VAR1 is ', $loop3_item['VAR1']; 
?>


References
 


Часовой пояс: GMT + 3

Кто онлайн
Кто онлайн
Кто онлайн Всего зарегистрированных пользователей: 405
Последний зарегистрированный пользователь: MugenEi
Сейчас посетителей на сайте: 60, из них зарегистрированных: 0, скрытых: 0, гостей: 52, ботов: 8
Больше всего посетителей (302) здесь было Июль 27 2023, 12:54
Зарегистрированные пользователи: нет
Боты : AhrefsBot (8)
Легенда: Админ, Зам.админа, ViP, Спамеры
Эти данные основаны на активности пользователей за последние пять минут

Вход
Вход
Пользователь:    Пароль:     Автоматически входить при каждом посещении     

Powered by R3-Born² © 2024
Все логотипы и торговые марки являются собственностью их законных владельцев.
Правила пользования | Полис Секретности

Valid XHTML 1.0 Transitional SPECIALIST® Online Certified PHP Specialist Valid CSS!