* @link https://getkirby.com * @copyright Bastian Allgeier * @license https://getkirby.com/license */ class Template { /** * Global template data * * @var array */ public static $data = []; /** * The name of the template * * @var string */ protected $name; /** * Template type (html, json, etc.) * * @var string */ protected $type; /** * Default template type if no specific type is set * * @var string */ protected $defaultType; /** * Creates a new template object * * @param string $name * @param string $type * @param string $defaultType */ public function __construct(string $name, string $type = 'html', string $defaultType = 'html') { $this->name = strtolower($name); $this->type = $type; $this->defaultType = $defaultType; } /** * Converts the object to a simple string * This is used in template filters for example * * @return string */ public function __toString(): string { return $this->name; } /** * Checks if the template exists * * @return bool */ public function exists(): bool { if ($file = $this->file()) { return file_exists($file); } return false; } /** * Returns the expected template file extension * * @return string */ public function extension(): string { return 'php'; } /** * Returns the default template type * * @return string */ public function defaultType(): string { return $this->defaultType; } /** * Returns the place where templates are located * in the site folder and and can be found in extensions * * @return string */ public function store(): string { return 'templates'; } /** * Detects the location of the template file * if it exists. * * @return string|null */ public function file(): ?string { if ($this->hasDefaultType() === true) { try { // Try the default template in the default template directory. return F::realpath($this->root() . '/' . $this->name() . '.' . $this->extension(), $this->root()); } catch (Exception $e) { // ignore errors, continue searching } // Look for the default template provided by an extension. $path = App::instance()->extension($this->store(), $this->name()); if ($path !== null) { return $path; } } $name = $this->name() . '.' . $this->type(); try { // Try the template with type extension in the default template directory. return F::realpath($this->root() . '/' . $name . '.' . $this->extension(), $this->root()); } catch (Exception $e) { // Look for the template with type extension provided by an extension. // This might be null if the template does not exist. return App::instance()->extension($this->store(), $name); } } /** * Returns the template name * * @return string */ public function name(): string { return $this->name; } /** * @param array $data * @return string */ public function render(array $data = []): string { return Tpl::load($this->file(), $data); } /** * Returns the root to the templates directory * * @return string */ public function root(): string { return App::instance()->root($this->store()); } /** * Returns the template type * * @return string */ public function type(): string { return $this->type; } /** * Checks if the template uses the default type * * @return bool */ public function hasDefaultType(): bool { $type = $this->type(); return $type === null || $type === $this->defaultType(); } }