diff --git a/docs/programmers/api-variables.md b/docs/programmers/api-variables.md index ee9c07611..3ae24c3c3 100644 --- a/docs/programmers/api-variables.md +++ b/docs/programmers/api-variables.md @@ -45,6 +45,7 @@ them directly, or use the corresponding setter/getter methods. - [$template_dir](./api-variables/variable-template-dir.md) - [$trusted_dir](./api-variables/variable-trusted-dir.md) - [$use_include_path](./api-variables/variable-use-include-path.md) +- [$use_only_compiled](./api-variables/variable-use-only-compiled.md) - [$use_sub_dirs](./api-variables/variable-use-sub-dirs.md) > **Note** diff --git a/docs/programmers/api-variables/variable-use-only-compiled.md b/docs/programmers/api-variables/variable-use-only-compiled.md new file mode 100644 index 000000000..1c376e7e5 --- /dev/null +++ b/docs/programmers/api-variables/variable-use-only-compiled.md @@ -0,0 +1,9 @@ +\$use\_only\_compiled {#variable.use.only.compiled} +================ + +If set to TRUE, Smarty will use only compiled templates, alsoù +ignoring the (in)existence of base templates. Compiled filenames +will be constant and relative to the template basename. +Useful to use pre-compiled templates and distribute them already +compiled on production websites. Overrides and disables +[`$merge_compiled_includes`](#variable.merge.compiled.includes) diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 5351b5791..e6fb0b03b 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -578,6 +578,13 @@ class Smarty extends Smarty_Internal_TemplateBase */ public $_debug = null; + /** + * force using of only compiled templates, ignoring source + * + * @var boolean + */ + public $use_only_compiled = false; + /** * template directory * @@ -1279,6 +1286,14 @@ public function setCachingType($caching_type) $this->caching_type = $caching_type; } + /** + * @param boolean $use_only_compiled + */ + public function setUseOnlyCompiled($use_only_compiled) + { + $this->use_only_compiled = $use_only_compiled; + } + /** * Test install * diff --git a/libs/sysplugins/smarty_internal_compile_include.php b/libs/sysplugins/smarty_internal_compile_include.php index bf62461bc..77f1ba629 100644 --- a/libs/sysplugins/smarty_internal_compile_include.php +++ b/libs/sysplugins/smarty_internal_compile_include.php @@ -145,6 +145,10 @@ public function compile($args, Smarty_Internal_SmartyTemplateCompiler $compiler) if (isset($_attr[ 'compile_id' ]) && $compiler->isVariable($_attr[ 'compile_id' ])) { $merge_compiled_includes = false; } + // compile names without uid + if ($compiler->smarty->use_only_compiled) { + $merge_compiled_includes = false; + } } /* * if the {include} tag provides individual parameter for caching or compile_id diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index 72d1d52e0..5607577ac 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -192,7 +192,7 @@ public function render($no_output_filter = true, $display = null) $this->smarty->_debug->start_template($this, $display); } // checks if template exists - if (!$this->source->exists) { + if (!$this->source->exists && !$this->smarty->use_only_compiled) { throw new SmartyException( "Unable to load template '{$this->source->type}:{$this->source->name}'" . ($this->_isSubTpl() ? " in '{$this->parent->template_resource}'" : '') diff --git a/libs/sysplugins/smarty_template_compiled.php b/libs/sysplugins/smarty_template_compiled.php index 37d8f0a9e..fb5e5e5a8 100644 --- a/libs/sysplugins/smarty_template_compiled.php +++ b/libs/sysplugins/smarty_template_compiled.php @@ -50,23 +50,37 @@ public function populateCompiledFilepath(Smarty_Internal_Template $_template) $this->filepath .= preg_replace('![^\w]+!', '_', $_template->compile_id) . ($smarty->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'); } - // if use_sub_dirs, break file into directories - if ($smarty->use_sub_dirs) { - $this->filepath .= $source->uid[ 0 ] . $source->uid[ 1 ] . DIRECTORY_SEPARATOR . $source->uid[ 2 ] . - $source->uid[ 3 ] . DIRECTORY_SEPARATOR . $source->uid[ 4 ] . $source->uid[ 5 ] . - DIRECTORY_SEPARATOR; - } - $this->filepath .= $source->uid . '_'; - if ($source->isConfig) { - $this->filepath .= (int)$smarty->config_read_hidden + (int)$smarty->config_booleanize * 2 + - (int)$smarty->config_overwrite * 4; + $basename = $smarty->use_only_compiled ? basename($source->name) : $source->handler->getBasename($source); + if ($smarty->use_only_compiled) { + if (empty($basename)) { + throw new SmartyException("Unable to get basename"); + } + // if use_sub_dirs, break file into directories + if ($smarty->use_sub_dirs) { + $padded_basename = str_pad(str_replace('.','',$basename), 6, '_'); + $this->filepath .= $padded_basename[ 0 ] . $padded_basename[ 1 ] . DIRECTORY_SEPARATOR . + $padded_basename[ 2 ] . $padded_basename[ 3 ] . DIRECTORY_SEPARATOR . + $padded_basename[ 4 ] . $padded_basename[ 5 ] . DIRECTORY_SEPARATOR; + } } else { - $this->filepath .= (int)$smarty->merge_compiled_includes + (int)$smarty->escape_html * 2 + - (($smarty->merge_compiled_includes && $source->type === 'extends') ? - (int)$smarty->extends_recursion * 4 : 0); + // if use_sub_dirs, break file into directories + if ($smarty->use_sub_dirs) { + $this->filepath .= $source->uid[ 0 ] . $source->uid[ 1 ] . DIRECTORY_SEPARATOR . $source->uid[ 2 ] . + $source->uid[ 3 ] . DIRECTORY_SEPARATOR . $source->uid[ 4 ] . $source->uid[ 5 ] . + DIRECTORY_SEPARATOR; + } + $this->filepath .= $source->uid . '_'; + if ($source->isConfig) { + $this->filepath .= (int)$smarty->config_read_hidden + (int)$smarty->config_booleanize * 2 + + (int)$smarty->config_overwrite * 4; + } else { + $this->filepath .= (int)$smarty->merge_compiled_includes + (int)$smarty->escape_html * 2 + + (($smarty->merge_compiled_includes && $source->type === 'extends') ? + (int)$smarty->extends_recursion * 4 : 0); + } + $this->filepath .= '.'; } - $this->filepath .= '.' . $source->type; - $basename = $source->handler->getBasename($source); + $this->filepath .= $source->type; if (!empty($basename)) { $this->filepath .= '.' . $basename; } @@ -91,7 +105,7 @@ public function populateCompiledFilepath(Smarty_Internal_Template $_template) public function render(Smarty_Internal_Template $_template) { // checks if template exists - if (!$_template->source->exists) { + if (!$_template->source->exists && !is_file($_template->source->filepath) && !$_template->smarty->use_only_compiled) { $type = $_template->source->isConfig ? 'config' : 'template'; throw new SmartyException("Unable to load {$type} '{$_template->source->type}:{$_template->source->name}'"); } @@ -135,8 +149,9 @@ public function process(Smarty_Internal_Template $_smarty_tpl) if ($source->handler->recompiled) { $source->handler->process($_smarty_tpl); } elseif (!$source->handler->uncompiled) { - if (!$this->exists || $smarty->force_compile - || ($_smarty_tpl->compile_check && $source->getTimeStamp() > $this->getTimeStamp()) + if ( !$smarty->use_only_compiled && + (!$this->exists || $smarty->force_compile + || ($_smarty_tpl->compile_check && $source->getTimeStamp() > $this->getTimeStamp())) ) { $this->compileTemplateSource($_smarty_tpl); $compileCheck = $_smarty_tpl->compile_check; @@ -147,7 +162,9 @@ public function process(Smarty_Internal_Template $_smarty_tpl) $_smarty_tpl->mustCompile = true; @include $this->filepath; if ($_smarty_tpl->mustCompile) { - $this->compileTemplateSource($_smarty_tpl); + if (!$smarty->use_only_compiled) { + $this->compileTemplateSource($_smarty_tpl); + } $compileCheck = $_smarty_tpl->compile_check; $_smarty_tpl->compile_check = Smarty::COMPILECHECK_OFF; $this->loadCompiledTemplate($_smarty_tpl);