In UCH, the template and dynamic data are separated. Therefore, at the end of many PHP files, we will see the template file, such as cp_blog.php, which finally has include_once template ("cp_blog ");
In the following code, the name is regular. $ Tpl has no suffix, $ tplfile is a template file suffixed with htm, and $ objfile is a cache file suffixed with php.
The process for using a template in UCH is as follows:
Get dynamic data in php code, and then define de_once template ($ tpl)
The template function parses the template File $ tplfile and returns the cached File $ objfile.
The parse_template function is called in the template function to parse $ tplfile,
$ Tplfile contains a set of UCH-defined syntaxes, which can be seen in the parse_template function! -- Template name --> <! -Block/name -->. These syntaxes are replaced with corresponding functions in parse_template, such as readtemplate blocktags. These functions are also located in function_template.php.
What is a little bit difficult here is that the template file may still pass <! -- Template name --> contains other template files. Therefore, you must call preg_replace twice in parse_template. The first time you read the name of the subtemplate file included in the template file $ tplfile, the second is to read the Sun Tzu template file contained in the sub-template file name. UCH has a maximum of three-layer template inclusion relationships, namely, parent> son> grandson. Therefore, you do not need to call preg_replace for the third time to read the duplicate template files that may be contained in the Sun Tzu template file.
The template function is defined in function_common.php.
Function template ($ name ){
Global $ _ SCONFIG, $ _ SGLOBAL;
If (strexists ($ name ,/)){
$ Tpl = $ name; // $ name indicates the complete directory.
} Else {
$ Tpl = "template/$ _ SCONFIG [template]/$ name ";
/*
$ Name is only a file name. $ tpl is similar to template/default/cp_blog or template/blue/cp_blog.
The default template style is default, but if you select another style, $ _ SCONFIG [template] will become another value such as blue.
You can select a template style in the lower-right corner of the homepage.
*/
}
$ Objfile = S_ROOT ../data/tpl_cache/. str_replace (/, _, $ tpl).. php;
/*
Cache file name. $ objfile is similar to data/tpl_cache/template_default_cp_blog.php or data/tpl_cache/template_blue_cp_blog.php.
*/
If (! File_exists ($ objfile )){
Include_once (S_ROOT ../source/function_template.php );
Parse_template ($ tpl );
// If the cached file does not exist, parse the Template File
}
Return $ objfile;
}
The parse_template function is defined in function_template.php.
Function parse_template ($ tpl ){
Global $ _ SGLOBAL, $ _ SC, $ _ SCONFIG;
// Contains the Template
$ _ SGLOBAL [sub_tpls] = array ($ tpl );
$ Tplfile = S_ROOT ../.20.tpl..htm;
/*
$ Tplfile is similar to template/default/cp_blog.htm or template/blue/cp_blog.htm.
*/
$ Objfile = S_ROOT ../data/tpl_cache/. str_replace (/, _, $ tpl).. php;
/*
$ Objfile is similar to data/tpl_cache/template_default_cp_blog.php or data/tpl_cache/template_blue_cp_blog.php.
*/
// Read
If (! File_exists ($ tplfile )){
$ Tplfile = str_replace (/. $ _ SCONFIG [template]./,/default/, $ tplfile );
// If a template file of a non-default template style does not exist, use the default template file instead.
}
$ Template = sreadfile ($ tplfile );
// Read the Template File Content
If (empty ($ template )){
Exit ("Template file: $ tplfile Not found or have no access! ");
}
// Template
$ Template = preg_replace ("/<! -- {Templates + ([a-z0-9 _/] +)} -->/ie "," readtemplate (\ 1) ", $ template );
/*
This is the template syntax for UCH definition. <! -- {Template name} -->
Replaced with readtemplate (name), which is also defined in function_template.php. Name is ([a-zA-Z0-9 _/] +)
Why more A-Z, because "/<! -- {Templates + ([a-z0-9 _/] +)} -->/ie "the last I option indicates case-insensitive regular match
The regular expression grouping in python seems to be represented by 1, where \ 1 is used.
\ 1 Why should we wrap it in single quotes? This is because the parameter of the readtemplate function is a string.
*/
// Process the code in the subpage
$ Template = preg_replace ("/<! -- {Templates + ([a-z0-9 _/] +)} -->/ie "," readtemplate (\ 1) ", $ template );
// Resolution module call
$ Template = preg_replace ("/<! -- {Block/(. + ?)} -->/Ie "," blocktags (\ 1) ", $ template );
/*
<! -- {Block/name} --> is replaced with blocktags (name)
Name is (. + ?) . Match any character except the line break. + indicates one or more occurrences.
? It indicates that the request is a lazy match. Otherwise, all}-> will be matched by. +.
*/
// Parse the advertisement
$ Template = preg_replace ("/<! -- {Ad/(. + ?)} -->/Ie "," adtags (\ 1) ", $ template );
/*
<! -- {Ad/name} --> replaced with <! -- Adtags (name) -->
For example, there is one in space_doing.htm <! -- {Ad/header} --> is replaced with <! -- AD_TAG_1 -->
*/
// Time Processing
$ Template = preg_replace ("/<! -- {Date (. + ?))} -->/Ie "," datetags (\ 1) ", $ template );
/*
<! -- {Date (name)} --> is replaced with datetags (name)
For example, space_doing.htm contains
<! -- {Date (m-d H: I, $ basevalue [dateline], 1)} --> replaced with <! -- DATE_TAG_7 -->
*/
// Avatar Processing
$ Template = preg_replace ("/<! -- {Avatar (. + ?))} -->/Ie "," avatartags (\ 1) ", $ template );
/*
<! -- {Avatar (name)} --> is replaced with avatartags (name)
For example, there is one in space_doing.htm <! -- {Avatar ($ _ SGLOBAL [supe_uid], small)} --> replaced with <! -- AVATAR_TAG_10 -->
*/
// PHP code
$ Template = preg_replace ("/<! -- {Evals + (. + ?) S *} -->/ies "," evaltags (\ 1) ", $ template );
/*
<! -- {Eval php_expression} --> replaced with evaltags (php_expression)
Php_expression is (. + ?) And here, matching all characters including linefeeds is determined by the s option in/ies.
For example, there is one in space_doing.htm <! -- {Eval echo formhash () ;}--> replaced with <! -- EVAL_TAG_16 -->
*/
// Start processing
// Variable
$ Var_regexp = "(\ $ [a-zA-Z_x7f-xff] [a-zA-Z0-9_x7f-xff] *) ([a-zA-Z0-9 _-." \ [] $ x7f-xff] +]) *) ";
/*
The Escape Character is displayed in red, and the \ character displayed in red is used as the backslash.
But why do I need three at the beginning. After testing, the \ $ matches $, but changes to $ does not match the variable name in the template file. I haven't figured it out yet.
$ Var_regexp matches the variable name
[A-zA-Z_x7f-xff] variable names start with letters, underscores, or Chinese Characters
X7f-xff is confusing. What exactly is it? Do you want to match the extended ASCII code? 0x7f-0xff does extend the range of the ASCII code table, but apparently no one uses these control characters as variable names.
I am a UTF-8 version of UCH, from the UCS-2 (which is now commonly used Unicode) to the UTF-8 encoding method is as follows:
UCS-2 coding (hexadecimal)
UTF-8 byte stream (Binary)
0000-007F
0 xxxxxxx
0080-07FF
110 xxxxx 10 xxxxxx
0800-FFFF
1110 xxxx 10 xxxxxx 10 xxxxxx
The preceding signature -007f is compatible with ASCII codes.
Unicode encoding of Chinese characters is in 0080-FFFF, And the byte after conversion to UTF-8 is
110xxxxx, 10xxxxxx, or 1110 xxxx, in the range of 0x011111-0x11111111, that is, 0x7f-0xff.
More precisely, the part that matches the beginning of the variable name can be written as a [a-zA-Z_xc0-xef], because the starting byte of the Chinese character can only be 110xxxxx or 1110 xxxx, And the range is 0xc0-0xdf and 0xe0-0xef
[A-zA-Z0-9_x7f-xff] * a variable name cannot start with a number, which is the same as a C language, and is allowed to be greater than the value range of the first byte of the variable name
More precisely, here can be written as [a-zA-Z0-9_x80-xef] * because here the Chinese character byte may be 110xxxxx or 1110xxxx or 10 xxxxxx, than 0xc0-0xef 10 xxxxxx, that is, 0x80-0xbf, together is 0x80-0xef
([[A-zA-Z0-9 _-. "\ [] $ x7f-xff] +]) *
Variables may be in the form of arrays, such as $ name1 [$ name2], $ [a-zA-Z_x7f-xff] [a-zA-Z0-9_x7f-xff] * matching $ name1, how do I match the following [$ name2? I initially thought it was [$ [a-zA-Z_x7f-xff] [a-zA-Z0-9_x7f-xff], because [] should also be a variable name.
However, variables may be nested arrays, for example, $ name1 [$ name2 [$ name3 [$ name4], it is obviously not feasible to match variable names one by one with $ [a-zA-Z_x7f-xff] [a-zA-Z0-9_x7f-xff. So I just used [] to box all possible characters and hoped that programmers would not write too many variable names.
*/
$ Template = preg_replace ("/<! -- {(. + ?)} -->/S "," {\ 1} ", $ template );
/*
<! -- {Name} --> string is replaced with {name}
Previously resolved advertisements, time processing, etc. generated <! -- EVAL_TAG_15 --> and so on do not match and are retained.
Name is (. + ?) Here. Match All characters including linefeeds (with the/s option )? Indicates a lazy match.
*/
$ Template = preg_replace ("/([] +) +/s", "\ 1", $ template );
/*
Remove the Tab character after the newline and carriage return
The comparison results in beyondcompare are as follows:
*/
$ Template = preg_replace ("/(\ $[a-zA-Z0-9 _ [] \" $ x7f-xff] + ). ([a-zA-Z_x7f-xff] [a-zA-Z0-9_x7f-xff] *)/s "," \ 1 [\ 2] ", $ template );
/*
Replace $ name1.name2 with $ name1 [name2]. Do not create $ name1 [name2]. Both \ 2 and "\ 1" are post-reference regular expressions. However, I have not found any examples in the template file.
*/
$ Template = preg_replace ("/{(\ $[a-zA-Z0-9 _ [] \" $. x7f-xff] +)}/s "," <? = \ 1?> ", $ Template );
/*
Replace {$ name1} with <? = $ Name1?>
For example, {$ _ SN [$ space [uid]} In space_doing.htm is replaced
<? = $ _ SN [$ space [uid]?>
*/
$ Template = preg_replace ("/$ var_regexp/es", "addquote (<? = \ 1?>) ", $ Template );
/*
Replace the variable name that has not been wrapped by {} with addquote (<? = \ 1?>)
Addquote is used to convert [name] to ['name']
For example, {if $ space} In space_doing.htm is replaced with {if <? = $ Space?>}
However, this example also has a secondary parameter. For example, in space_doing.htm, {$ _ SN [$ space [uid]} is replaced with <? = $ _ SN [$ space [uid]?>, This is replaced with <? = <? = $ _ SN [$ space [uid]? >?>
*/
$ Template = preg_replace ("/<? = <? = $ Var_regexp? >?> /Es "," addquote (<? = \ 1?>) ", $ Template );
/*
Eliminate the side effects of the previous statement? = <? = $ _ SN [$ space [uid]? >?> Change to <? = $ _ SN [$ space [uid]?>
*/
// Logic
$ Template = preg_replace ("/{elseifs + (. + ?)} /Ies "," stripvtags (<? Php} elseif (\ 1) {?> ,) ", $ Template );
/*
Replace {elseif expression1} with stripvtags (<? Php} elseif (expression1) {?> ,)
The role of stripvtags is similar to <? = $ Name?> Replace with $ name
*/
$ Template = preg_replace ("/{else}/is", "<? Php} else {?> ", $ Template );
/*
Replace {else} with <? Php} else {?>
*/
// Loop
For ($ I = 0; $ I <5; $ I ++ ){
$ Template = preg_replace ("/{loops + (S +) s + (S +)} (. + ?) {/Loop}/ies "," stripvtags (<? Php if (is_array (\ 1) {foreach (\ 1 as \ 2) {?>, \ 3 <? Php }}?>) ", $ Template );
/*
Parse loop
Replace {loop array1 key1} expression1 {/loop}
Stripvtags (
<'? Php if (is_array (array1) {foreach (array1 as key1) {?> ',
'Expression1 <? Php }}?> '
)
For example, in space_doing.htm
<Title> {if <? =_ _ TPL [titles]?>} {Loop <? =_ _ TPL [titles]?> <? = $ Value?>} {If <? = $ Value?>} <? = $ Value?> -{/If} {/loop} {/if} {if <? = $ Space?>} <? = $ _ SN [$ space [uid]?> -{/If} <? = $ _ SCONFIG [sitename]?>
Replaced
<Title> {if <? =_ _ TPL [titles]?>} <? Php if (is_array ($ _ TPL [titles]) {foreach ($ _ TPL [titles] as $ value) {?> {If <? = $ Value?>} <? = $ Value?> -{/If} <? Php }}?> {/If} {if <? = $ Space?>} <? = $ _ SN [$ space [uid]?> -{/If} <? = $ _ SCONFIG [sitename]?>
*/
$ Template = preg_replace ("/{loops + (S +) s + (S +)} (. + ?) {/Loop}/ies "," stripvtags (<? Php if (is_array (\ 1) {foreach (\ 1 as \ 2 => \ 3) {?>, \ 4 <? Php }}?>) ", $ Template );
/*
Parse loop
Replace {loop array1 key1 value1} expression1 {/loop}
Stripvtags (
<'? Php if (is_array (array1) {foreach (array1 as key1 => value1) {?> ',
'Expression1 <? Php }}?> '
)
For example, in space_doing.htm
{Loop <? = $ Moodlist?> <? = $ Key?> <? = $ Value?>}
<Li>
<Div class = "avatar48"> <a href = "space. php? Uid = <? = $ Value [uid]?> & Do = doing "> "alt =" <? = $ _ SN [$ value [uid]?> "/> </A> </div>
<P> <a href = "space. php? Uid = <? = $ Value [uid]?> "Title =" <? = $ _ SN [$ value [uid]?> "> <? = $ _ SN [$ value [uid]?> </A> </p>
<P class = "time"> <! -- DATE_TAG_9 --> </p>
</Li>
{/Loop}
Replaced
<? Php if (is_array ($ moodlist) {foreach ($ moodlist as $ key =>$ value) {?>
<Li>
<Div class = "avatar48"> <a href = "space. php? Uid = <? = $ Value [uid]?> & Do = doing "> "alt =" <? = $ _ SN [$ value [uid]?> "/> </A> </div>
<P> <a href = "space. php? Uid = <? = $ Value [uid]?> "Title =" <? = $ _ SN [$ value [uid]?> "> <? = $ _ SN [$ value [uid]?> </A> </p>
<P class = "time"> <! -- DATE_TAG_9 --> </p>
</Li>
<? Php }}?>
*/
$ Template = preg_replace ("/{ifs + (. + ?)} (. + ?) {/If}/ies "," stripvtags (<? Php if (\ 1) {?>, \ 2 <? Php}?>) ", $ Template );
/*
Parse if
Similar
{If name1} expression1 {/if}
Replace
Stripvtags (
<'? Php if (name1) {?> ',
'Expression1 <? Php }?> '
)
For example, in space_doing.htm
{If empty (<? =$ _ SGLOBAL [inajax]?> )}
Replace
<? Php if (empty ($ _ SGLOBAL [inajax]) {?>
*/
}/* For Loop end */
/*
Why is there a for loop? The nested loop statement may exist.
For example, space_doing.htm has such a piece of code.
{Loop <? = $ List?> <? = $ Basevalue?>}
.........
.........
{Loop <? = $ Clist [$ basevalue [doid]?> <? = $ Value?>}
.........
{/Loop}
.........
{/Loop}
$ I = 0,
$ Template = preg_replace ("/{loops + (S +) s + (S +)} (. + ?) {/Loop}/ies "," stripvtags (<? Php if (is_array (\ 1) {foreach (\ 1 as \ 2) {?>, \ 3 <? Php }}?>) ", $ Template );
Only the outer loop is replaced, and the inner loop is (. + ?) Matched
? It indicates a lazy match. Otherwise, {/loop} will be matched by (. + ).
But since it is a lazy match, why (. + ?) Does it stop when the {/loop} matches the inner layer?
Because The regular expression has another rule, it has a higher priority than The lazy/greedy rule: The first match to start has The highest priority-The match that begins earliest wins.
$ I = 1, the inner loop will also be replaced
From this for loop, we can also see that the UCH template allows a maximum of five layers of nested loops. Of course, this is enough.
*/
// Constant
$ Template = preg_replace ("/{([a-zA-Z_x7f-xff] [a-zA-Z0-9_x7f-xff] *)}/s", "<? = \ 1?> ", $ Template );
/*
$ Is less than the variable name, and constant in array form is not considered.
*/
// Replace
If (! Empty ($ _ SGLOBAL [block_search]) {
$ Template = str_replace ($ _ SGLOBAL [block_search], $ _ SGLOBAL [block_replace], $ template );
}
// Line feed
$ Template = preg_replace ("/?> [] * <? /S "," ", $ template );
/*
?>
<?
The end of the previous php code and the start of the next php code are replaced by spaces.
*/
// Additional processing
$ Template = "<? Php if (! Defined (IN_UCHOME) exit (Access Denied);?> <? Php subtplcheck (". implode (|, $ _ SGLOBAL [sub_tpls]).", $ _ SGLOBAL [timestamp], $ tpl);?> $ Template <? Php ob_out ();?> ";
// Write
If (! Swritefile ($ objfile, $ template )){
Exit ("File: $ objfile can not be write! ");
}
/*
Write cache files
Therefore, at the end of the template function, $ objfile is returned no matter whether or not $ objfile exists at the beginning.
*/
}
Function readtemplate ($ name ){
Global $ _ SGLOBAL, $ _ SCONFIG;
$ Tpl = strexists ($ name ,/)? $ Name: "template/$ _ SCONFIG [template]/$ name ";
$ Tplfile = S_ROOT ../.20.tpl..htm;
$ _ SGLOBAL [sub_tpls] [] = $ tpl;
If (! File_exists ($ tplfile )){
$ Tplfile = str_replace (/. $ _ SCONFIG [template]./,/default/, $ tplfile );
}
/*
If the $ _ SCONFIG [template] template file does not exist, use the default template file instead.
*/
$ Content = sreadfile ($ tplfile );
// Read the content of the template file
Return $ content;
}
Function addquote ($ var ){
Return str_replace ("\" ",", preg_replace ("/[([a-zA-Z0-9 _-. x7f-xff] +)]/s "," [\ 1] ", $ var ));
/*
This preg_replace is useless. How can I replace [name1] with [name1]?
Str_replace \ ""
*/
}
Function blocktags ($ parameter ){
Global $ _ SGLOBAL;
$ _ SGLOBAL [I] ++;
$ Search = "<! -- BLOCK_TAG _ {$ _ SGLOBAL [I]} --> ";
/*
Replace {block/name} with BLOCK_TAG_1 BLOCK_TAG_2 in the order in which the advertisement appears.
*/
$ _ SGLOBAL [block_search] [$ _ SGLOBAL [I] = $ search;
$ _ SGLOBAL [block_replace] [$ _ SGLOBAL [I] = "<? Php block ("$ parameter");?> ";
Return $ search;
}
Function adtags ($ pagetype ){
Global $ _ SGLOBAL;
$ _ SGLOBAL [I] ++;
$ Search = "<! -- AD_TAG _ {$ _ SGLOBAL [I]} --> ";
/*
Replace {ad/name} with AD_TAG_3 AD_TAG_4 in order of advertisement appearance.
This number is followed by the previous BLOCK_TAG.
*/
$ _ SGLOBAL [block_search] [$ _ SGLOBAL [I] = $ search;
$ _ SGLOBAL [block_replace] [$ _ SGLOBAL [I] = "<? Php adshow ($ pagetype);?> ";
Return $ search;
}
Function datetags ($ parameter ){
Global $ _ SGLOBAL;
$ _ SGLOBAL [I] ++;
$ Search = "<! -- DATE_TAG _ {$ _ SGLOBAL [I]} --> ";
/*
Replace {date (name)} with DATE_TAG_7 DATE_TAG_8
Note that the numbers here follow the AD_TAG above.
*/
$ _ SGLOBAL [block_search] [$ _ SGLOBAL [I] = $ search;
$ _ SGLOBAL [block_replace] [$ _ SGLOBAL [I] = "<? Php echo sgmdate ($ parameter);?> ";
Return $ search;
}
Function avatartags ($ parameter ){
Global $ _ SGLOBAL;
$ _ SGLOBAL [I] ++;
$ Search = "<! -- AVATAR_TAG _ {$ _ SGLOBAL [I]} --> ";
/*
Replace {avatar (name)} with AVATAR_TAG_9 AVATAR_TAG_10
Note that the numbers here follow the preceding DATE_TAG.
*/
$ _ SGLOBAL [block_search] [$ _ SGLOBAL [I] = $ search;
$ _ SGLOBAL [block_replace] [$ _ SGLOBAL [I] = "<? Php echo avatar ($ parameter);?> ";
Return $ search;
}
Function evaltags ($ php ){
Global $ _ SGLOBAL;
$ _ SGLOBAL [I] ++;
$ Search = "<! -- EVAL_TAG _ {$ _ SGLOBAL [I]} --> ";
/*
Replace {eval php_expression} with EVAL_TAG_16 EVAL_TAG_17 and so on in the order in which the eval template method appears.
Note that the number here is followed by the previous AVATAR_TAG.
*/
$ _ SGLOBAL [block_search] [$ _ SGLOBAL [I] = $ search;
$ _ SGLOBAL [block_replace] [$ _ SGLOBAL [I] = "<? Php ". stripvtags ($ php)."?> ";
Return $ search;
}
Function addquote ($ var ){
Return str_replace ("\" ",", preg_replace ("/[([a-zA-Z0-9 _-. x7f-xff] +)]/s "," [\ 1] ", $ var ));
/*
Preg_replace converts a format similar to [name] to ['name']
Str_replace converts \ into an example, but I haven't found it yet.
*/
}
Function stripvtags ($ expr, $ statement = ){
$ Expr = str_replace ("\" ",", preg_replace ("/<? = (\ $. +?)?> /S "," \ 1 ", $ expr ));
/*
Preg_replace will <? = $ Name?> Replace with $ name
*/
$ Statement = str_replace ("\" ",", $ statement );
Return $ expr. $ statement;
}