52 public function compile($args, $compiler) {
55 $save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code);
56 $this->
openTag($compiler,
'block', $save);
57 if ($_attr[
'nocache'] ==
true) {
58 $compiler->nocache =
true;
61 $compiler->inheritance =
true;
63 $compiler->smarty->merge_compiled_includes =
true;
66 $compiler->has_code =
false;
78 public static function saveBlockData($block_content, $block_tag, $template, $filepath) {
79 $_rdl = preg_quote($template->smarty->right_delimiter);
80 $_ldl = preg_quote($template->smarty->left_delimiter);
81 if (!$template->smarty->auto_literal) {
86 if (0 == preg_match(
"!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")(\s*?)?((append|prepend|nocache)?(\s*)?(hide)?)?(\s*{$_rdl})!", $block_tag, $_match)) {
87 $error_text =
'Syntax Error in template "' . $template->source->filepath .
'" "' . $block_tag .
'" illegal options';
90 $_name = trim($_match[3],
'\'"');
91 if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child}
92 // get nested block tags
93 if (0 != preg_match_all("!({$_ldl}{$al}block\s+)(name=)?(\w+|
'.*'|\
".*\")([\s\S]*?)(hide)?(\s*{$_rdl})([\s\S]*?)(.*)?({$_ldl}{$al}/block\s*{$_rdl})!", $block_content, $_match2)) {
94 foreach ($_match2[3] as $key => $name) {
96 $_name2 = trim($name,
'\'"');
97 if ($_match2[5][$key] != 'hide' || isset($template->block_data[$_name2])) {
98 if (isset($template->block_data[$_name2])) {
99 $replacement = $template->block_data[$_name2]['source'];
103 // replace {$smarty.block.child} tag
104 if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!
",$_match2[7][$key])) {
105 $replacement = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!
", $replacement, $_match2[7][$key]);
106 $block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!
", $replacement, $block_content);
108 if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!
",$_match2[8][$key])) {
109 $replacement = preg_replace("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!
", $replacement, $_match2[8][$key]);
110 $block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl})(.*)?({$_ldl}{$al}/block\s*{$_rdl}))!
", $replacement, $block_content);
113 // remove hidden blocks
114 $block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!
", '', $block_content);
118 // do we have not nested {$smart.block.child}
119 if (0 != preg_match("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!
", $block_content, $_match2)) {
120 // get child replacement for this block
121 if (isset($template->block_data[$_name])) {
122 $replacement = $template->block_data[$_name]['source'];
123 unset($template->block_data[$_name]);
127 $block_content = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!
", $replacement, $block_content);
129 if (isset($template->block_data[$_name])) {
130 if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
131 $template->block_data[$_name]['source'] =
132 str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']);
133 } elseif ($template->block_data[$_name]['mode'] == 'prepend') {
134 $template->block_data[$_name]['source'] .= $block_content;
135 } elseif ($template->block_data[$_name]['mode'] == 'append') {
136 $template->block_data[$_name]['source'] = $block_content . $template->block_data[$_name]['source'];
139 $template->block_data[$_name]['source'] = $block_content;
140 $template->block_data[$_name]['file'] = $filepath;
142 if ($_match[6] == 'append') {
143 $template->block_data[$_name]['mode'] = 'append';
144 } elseif ($_match[6] == 'prepend') {
145 $template->block_data[$_name]['mode'] = 'prepend';
147 $template->block_data[$_name]['mode'] = 'replace';
160 public static function compileChildBlock($compiler, $_name = null) {
162 // if called by {$smarty.block.child} we must search the name of enclosing {block}
163 if ($_name == null) {
164 $stack_count = count($compiler->_tag_stack);
165 while (--$stack_count >= 0) {
166 if ($compiler->_tag_stack[$stack_count][0] == 'block') {
167 $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "'\"");
171 // flag that child is already compile by {$smarty.block.child} inclusion
172 $compiler->template->block_data[$_name]['compiled
'] = true;
174 if ($_name == null) {
175 $compiler->trigger_template_error('{$smarty.block.child} used out of context
', $compiler->lex->taglineno);
178 if (!isset($compiler->template->block_data[$_name]['source
'])) {
181 $_tpl = new Smarty_Internal_template('string:
' . $compiler->template->block_data[$_name]['source
'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
182 $compiler->template->compile_id, $compiler->template->caching, $compiler->template->cache_lifetime);
183 $_tpl->variable_filters = $compiler->template->variable_filters;
184 $_tpl->properties['nocache_hash
'] = $compiler->template->properties['nocache_hash
'];
185 $_tpl->source->filepath = $compiler->template->block_data[$_name]['file
'];
186 $_tpl->allow_relative_path = true;
187 if ($compiler->nocache) {
188 $_tpl->compiler->forceNocache = 2;
190 $_tpl->compiler->forceNocache = 1;
192 $_tpl->compiler->suppressHeader = true;
193 $_tpl->compiler->suppressFilter = true;
194 $_tpl->compiler->suppressTemplatePropertyHeader = true;
195 $_tpl->compiler->suppressMergedTemplates = true;
196 if (strpos($compiler->template->block_data[$_name]['source
'], '%%%%SMARTY_PARENT%%%%
') !== false) {
197 $_output = str_replace('%%%%SMARTY_PARENT%%%%
', $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl));
198 } elseif ($compiler->template->block_data[$_name]['mode
'] == 'prepend
') {
199 $_output = $_tpl->compiler->compileTemplate($_tpl) . $compiler->parser->current_buffer->to_smarty_php();
200 } elseif ($compiler->template->block_data[$_name]['mode
'] == 'append
') {
201 $_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl);
202 } elseif (!empty($compiler->template->block_data[$_name])) {
203 $_output = $_tpl->compiler->compileTemplate($_tpl);
205 $compiler->template->properties['file_dependency
'] = array_merge($compiler->template->properties['file_dependency
'], $_tpl->properties['file_dependency
']);
206 $compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
207 $compiler->merged_templates = array_merge($compiler->merged_templates, $_tpl->compiler->merged_templates);
208 $compiler->template->variable_filters = $_tpl->variable_filters;
209 if ($_tpl->has_nocache_code) {
210 $compiler->template->has_nocache_code = true;
212 foreach ($_tpl->required_plugins as $key => $tmp1) {
213 if ($compiler->nocache && $compiler->template->caching) {
218 foreach ($tmp1 as $name => $tmp) {
219 foreach ($tmp as $type => $data) {
220 $compiler->template->required_plugins[$code][$name][$type] = $data;
236 class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
245 public function compile($args, $compiler) {
246 $compiler->has_code = true;
247 // check and get attributes
248 $_attr = $this->getAttributes($compiler, $args);
249 $saved_data = $this->closeTag($compiler, array('block
'));
250 $_name = trim($saved_data[0]['name
'], "\"'");
251 if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
252 // restore to status before {block} tag as new subtemplate code of parent {block} is not needed
253 // TODO: Below code was disabled in 3.1.8 because of problems with {include} in nested {block} tags in child templates
254 // combined with append/prepend or $smarty.block.parent
255 // For later versions it should be checked under which conditions it could run for optimisation
257 //$compiler->merged_templates = $saved_data[4];
258 //$compiler->smarty->merged_templates_func = $saved_data[5];
259 //$compiler->template->properties = $saved_data[6];
260 //$compiler->template->has_nocache_code = $saved_data[7];
261 $_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
263 if (isset($saved_data[0]['hide']) && !isset($compiler->template->block_data[$_name]['source'])) {
266 $_output = $compiler->parser->current_buffer->to_smarty_php();
268 unset($compiler->template->block_data[$_name]['compiled']);
271 $compiler->parser->current_buffer = $saved_data[1];
272 $compiler->nocache = $saved_data[2];
273 $compiler->smarty->merge_compiled_includes = $saved_data[3];
274 // reset flag for {block} tag
275 $compiler->inheritance = false;
276 // $_output content has already nocache code processed
277 $compiler->suppressNocacheProcessing = true;
static saveBlockData($block_content, $block_tag, $template, $filepath)
Save or replace child block source by block name during parsing.
openTag($compiler, $openTag, $data=null)
Push opening tag name on stack.
getAttributes($compiler, $attributes)
This function checks if the attributes passed are valid.
compile($args, $compiler)
Compiles code for the {block} tag.