use Exception;
use Friendica\DI;
-use Friendica\Render\FriendicaSmarty;
-use Friendica\Render\ITemplateEngine;
+use Friendica\Render\TemplateEngine;
/**
* This class handles Renderer related functions.
];
/**
- * This is our template processor
+ * Returns the rendered template output from the template string and variables
*
- * @param string|FriendicaSmarty $s The string requiring macro substitution or an instance of FriendicaSmarty
- * @param array $vars Key value pairs (search => replace)
- *
- * @return string substituted string
- * @throws Exception
+ * @param string $template
+ * @param array $vars
+ * @return string
*/
- public static function replaceMacros($s, array $vars = [])
+ public static function replaceMacros(string $template, array $vars)
{
$stamp1 = microtime(true);
// pass $baseurl to all templates if it isn't set
- $vars = array_merge(['$baseurl' => DI::baseUrl()->get()], $vars);
+ $vars = array_merge(['$baseurl' => DI::baseUrl()->get(), '$APP' => DI::app()], $vars);
$t = self::getTemplateEngine();
try {
- $output = $t->replaceMacros($s, $vars);
+ $output = $t->replaceMacros($template, $vars);
} catch (Exception $e) {
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
exit();
/**
* Load a given template $s
*
- * @param string $s Template to load.
+ * @param string $file Template to load.
* @param string $subDir Subdirectory (Optional)
*
* @return string template.
* @throws Exception
*/
- public static function getMarkupTemplate($s, $subDir = '')
+ public static function getMarkupTemplate($file, $subDir = '')
{
$stamp1 = microtime(true);
$t = self::getTemplateEngine();
try {
- $template = $t->getTemplateFile($s, $subDir);
+ $template = $t->getTemplateFile($file, $subDir);
} catch (Exception $e) {
echo "<pre><b>" . __FUNCTION__ . "</b>: " . $e->getMessage() . "</pre>";
exit();
{
$v = get_class_vars($class);
- if (!empty($v['name']))
- {
+ if (!empty($v['name'])) {
$name = $v['name'];
self::$template_engines[$name] = $class;
} else {
* If $name is not defined, return engine defined by theme,
* or default
*
- * @return ITemplateEngine Template Engine instance
+ * @return TemplateEngine Template Engine instance
*/
public static function getTemplateEngine()
{
if (isset(self::$template_engine_instance[$template_engine])) {
return self::$template_engine_instance[$template_engine];
} else {
+ $a = DI::app();
$class = self::$template_engines[$template_engine];
- $obj = new $class;
+ $obj = new $class($a->getCurrentTheme(), $a->theme_info);
self::$template_engine_instance[$template_engine] = $obj;
return $obj;
}
namespace Friendica\Render;
-use Friendica\DI;
use Smarty;
use Friendica\Core\Renderer;
public $filename;
- function __construct()
+ function __construct(string $theme, array $theme_info)
{
parent::__construct();
- $a = DI::app();
- $theme = $a->getCurrentTheme();
-
// setTemplateDir can be set to an array, which Smarty will parse in order.
// The order is thus very important here
$template_dirs = ['theme' => "view/theme/$theme/" . self::SMARTY3_TEMPLATE_FOLDER . "/"];
- if (!empty($a->theme_info['extends'])) {
- $template_dirs = $template_dirs + ['extends' => "view/theme/" . $a->theme_info["extends"] . "/" . self::SMARTY3_TEMPLATE_FOLDER . "/"];
+ if (!empty($theme_info['extends'])) {
+ $template_dirs = $template_dirs + ['extends' => "view/theme/" . $theme_info["extends"] . "/" . self::SMARTY3_TEMPLATE_FOLDER . "/"];
}
$template_dirs = $template_dirs + ['base' => "view/" . self::SMARTY3_TEMPLATE_FOLDER . "/"];
$this->setTemplateDir($template_dirs);
$this->setCompileDir('view/smarty3/compiled/');
- $this->setConfigDir('view/smarty3/config/');
- $this->setCacheDir('view/smarty3/cache/');
+ $this->setConfigDir('view/smarty3/');
+ $this->setCacheDir('view/smarty3/');
$this->left_delimiter = Renderer::getTemplateLeftDelimiter('smarty3');
$this->right_delimiter = Renderer::getTemplateRightDelimiter('smarty3');
// Don't report errors so verbosely
$this->error_reporting = E_ALL & ~E_NOTICE;
}
-
- function parsed($template = '')
- {
- if ($template) {
- return $this->fetch('string:' . $template);
- }
- return $this->fetch('file:' . $this->filename);
- }
-
-}
\ No newline at end of file
+}
use Friendica\Core\Hook;
use Friendica\DI;
+use Friendica\Util\Strings;
/**
- * Smarty implementation of the Friendica template engine interface
+ * Smarty implementation of the Friendica template abstraction
*/
-class FriendicaSmartyEngine implements ITemplateEngine
+final class FriendicaSmartyEngine extends TemplateEngine
{
static $name = "smarty3";
- public function __construct()
+ const FILE_PREFIX = 'file:';
+ const STRING_PREFIX = 'string:';
+
+ /** @var FriendicaSmarty */
+ private $smarty;
+
+ /**
+ * @inheritDoc
+ */
+ public function __construct(string $theme, array $theme_info)
{
- if (!is_writable(__DIR__ . '/../../view/smarty3/')) {
+ $this->theme = $theme;
+ $this->theme_info = $theme_info;
+ $this->smarty = new FriendicaSmarty($this->theme, $this->theme_info);
+
+ if (!is_writable(DI::basePath() . '/view/smarty3')) {
echo "<b>ERROR:</b> folder <tt>view/smarty3/</tt> must be writable by webserver.";
exit();
}
}
- // ITemplateEngine interface
- public function replaceMacros($s, $r)
+ /**
+ * @inheritDoc
+ */
+ public function replaceMacros(string $template, array $vars)
{
- $template = '';
- if (gettype($s) === 'string') {
- $template = $s;
- $s = new FriendicaSmarty();
+ if (!Strings::startsWith($template, self::FILE_PREFIX)) {
+ $template = self::STRING_PREFIX . $template;
}
- $r['$APP'] = DI::app();
-
// "middleware": inject variables into templates
$arr = [
- "template" => basename($s->filename),
- "vars" => $r
+ 'template' => basename($this->smarty->filename),
+ 'vars' => $vars
];
- Hook::callAll("template_vars", $arr);
- $r = $arr['vars'];
+ Hook::callAll('template_vars', $arr);
+ $vars = $arr['vars'];
- foreach ($r as $key => $value) {
+ foreach ($vars as $key => $value) {
if ($key[0] === '$') {
$key = substr($key, 1);
}
- $s->assign($key, $value);
+ $this->smarty->assign($key, $value);
}
- return $s->parsed($template);
+
+ return $this->smarty->fetch($template);
}
- public function getTemplateFile($file, $subDir = '')
+ /**
+ * @inheritDoc
+ */
+ public function getTemplateFile(string $file, string $subDir = '')
{
- $a = DI::app();
- $template = new FriendicaSmarty();
-
// Make sure $root ends with a slash /
if ($subDir !== '' && substr($subDir, -1, 1) !== '/') {
$subDir = $subDir . '/';
$root = DI::basePath() . '/' . $subDir;
- $theme = $a->getCurrentTheme();
- $filename = $template::SMARTY3_TEMPLATE_FOLDER . '/' . $file;
+ $filename = $this->smarty::SMARTY3_TEMPLATE_FOLDER . '/' . $file;
- if (file_exists("{$root}view/theme/$theme/$filename")) {
- $template_file = "{$root}view/theme/$theme/$filename";
- } elseif (!empty($a->theme_info['extends']) && file_exists(sprintf('%sview/theme/%s}/%s', $root, $a->theme_info['extends'], $filename))) {
- $template_file = sprintf('%sview/theme/%s}/%s', $root, $a->theme_info['extends'], $filename);
+ if (file_exists("{$root}view/theme/$this->theme/$filename")) {
+ $template_file = "{$root}view/theme/$this->theme/$filename";
+ } elseif (!empty($this->theme_info['extends']) && file_exists(sprintf('%sview/theme/%s}/%s', $root, $this->theme_info['extends'], $filename))) {
+ $template_file = sprintf('%sview/theme/%s}/%s', $root, $this->theme_info['extends'], $filename);
} elseif (file_exists("{$root}/$filename")) {
$template_file = "{$root}/$filename";
} else {
$template_file = "{$root}view/$filename";
}
- $template->filename = $template_file;
+ $this->smarty->filename = $template_file;
- return $template;
+ return self::FILE_PREFIX . $template_file;
}
}
+++ /dev/null
-<?php
-/**
- * @copyright Copyright (C) 2020, Friendica
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Render;
-
-/**
- * Interface for template engines
- */
-interface ITemplateEngine
-{
- public function replaceMacros($s, $v);
- public function getTemplateFile($file, $subDir = '');
-}
--- /dev/null
+<?php
+/**
+ * @copyright Copyright (C) 2020, Friendica
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Render;
+
+/**
+ * Interface for template engines
+ */
+abstract class TemplateEngine
+{
+ /** @var string */
+ static $name;
+
+ /** @var string */
+ protected $theme;
+ /** @var array */
+ protected $theme_info;
+
+ /**
+ * @param string $theme The current theme name
+ * @param array $theme_info The current theme info array
+ */
+ abstract public function __construct(string $theme, array $theme_info);
+
+ /**
+ * Returns the rendered template output from the template string and variables
+ *
+ * @param string $template
+ * @param array $vars
+ * @return string
+ */
+ abstract public function replaceMacros(string $template, array $vars);
+
+ /**
+ * Returns the template string from a file path and an optional sub-directory from the project root
+ *
+ * @param string $file
+ * @param string $subDir
+ * @return mixed
+ */
+ abstract public function getTemplateFile(string $file, string $subDir = '');
+}
->andReturn($this->configMock);
$this->app
->shouldReceive('getTemplateEngine')
- ->andReturn(new FriendicaSmartyEngine());
+ ->andReturn(new FriendicaSmartyEngine('frio', []));
$this->app
->shouldReceive('getCurrentTheme')
->andReturn('Smarty3');