Skip to content

Commit

Permalink
API Refactor template layer (#11405)
Browse files Browse the repository at this point in the history
Includes the following large-scale changes:
- Impoved barrier between model and view layers
- Improved casting of scalar to relevant DBField types
- Improved capabilities for rendering arbitrary data in templates
  • Loading branch information
GuySartorelli authored Oct 30, 2024
1 parent 57ae271 commit 6b33b5a
Show file tree
Hide file tree
Showing 187 changed files with 6,173 additions and 4,755 deletions.
6 changes: 6 additions & 0 deletions _config/view.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
Name: view-config
---
SilverStripe\Core\Injector\Injector:
SilverStripe\View\TemplateEngine:
class: 'SilverStripe\View\SSTemplateEngine'
2 changes: 1 addition & 1 deletion src/Control/ContentNegotiator.php
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ public function html(HTTPResponse $response)
// Fix base tag
$content = preg_replace(
'/<base href="([^"]*)" \/>/',
'<base href="$1"><!--[if lte IE 6]></base><![endif]-->',
'<base href="$1">',
$content ?? ''
);

Expand Down
36 changes: 29 additions & 7 deletions src/Control/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
namespace SilverStripe\Control;

use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Dev\Debug;
use SilverStripe\Model\ModelData;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\Security\Member;
use SilverStripe\Security\Security;
use SilverStripe\View\SSViewer;
use SilverStripe\View\TemplateEngine;
use SilverStripe\View\TemplateGlobalProvider;

/**
Expand Down Expand Up @@ -87,6 +90,8 @@ class Controller extends RequestHandler implements TemplateGlobalProvider
'handleIndex',
];

protected ?TemplateEngine $templateEngine = null;

public function __construct()
{
parent::__construct();
Expand Down Expand Up @@ -400,7 +405,7 @@ public function getViewer($action)
$templates = array_unique(array_merge($actionTemplates, $classTemplates));
}

return SSViewer::create($templates);
return SSViewer::create($templates, $this->getTemplateEngine());
}

/**
Expand Down Expand Up @@ -452,9 +457,10 @@ protected function definingClassForAction($action)
}

$class = static::class;
while ($class != 'SilverStripe\\Control\\RequestHandler') {
$engine = $this->getTemplateEngine();
while ($class !== RequestHandler::class) {
$templateName = strtok($class ?? '', '_') . '_' . $action;
if (SSViewer::hasTemplate($templateName)) {
if ($engine->hasTemplate($templateName)) {
return $class;
}

Expand Down Expand Up @@ -486,17 +492,25 @@ public function hasActionTemplate($action)
$parentClass = get_parent_class($parentClass ?? '');
}

return SSViewer::hasTemplate($templates);
$engine = $this->getTemplateEngine();
return $engine->hasTemplate($templates);
}

public function renderWith($template, ModelData|array $customFields = []): DBHTMLText
{
// Ensure template engine is used, unless the viewer was already explicitly instantiated
if (!($template instanceof SSViewer)) {
$template = SSViewer::create($template, $this->getTemplateEngine());
}
return parent::renderWith($template, $customFields);
}

/**
* Render the current controller with the templates determined by {@link getViewer()}.
*
* @param array $params
*
* @return string
*/
public function render($params = null)
public function render($params = null): DBHTMLText
{
$template = $this->getViewer($this->getAction());

Expand Down Expand Up @@ -735,4 +749,12 @@ public static function get_template_global_variables()
'CurrentPage' => 'curr',
];
}

protected function getTemplateEngine(): TemplateEngine
{
if (!$this->templateEngine) {
$this->templateEngine = Injector::inst()->create(TemplateEngine::class);
}
return $this->templateEngine;
}
}
21 changes: 7 additions & 14 deletions src/Control/Email/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class Email extends SymfonyEmail
private static string|array $admin_email = '';

/**
* The name of the HTML template to render the email with (without *.ss extension)
* The name of the HTML template to render the email with
*/
private string $HTMLTemplate = '';

Expand Down Expand Up @@ -398,26 +398,21 @@ public function removeData(string $name)
return $this;
}

public function getHTMLTemplate(): string
public function getHTMLTemplate(): string|array
{
if ($this->HTMLTemplate) {
return $this->HTMLTemplate;
}

return ThemeResourceLoader::inst()->findTemplate(
SSViewer::get_templates_by_class(static::class, '', Email::class),
SSViewer::get_themes()
);
return SSViewer::get_templates_by_class(static::class, '', Email::class);
}

/**
* Set the template to render the email with
* Set the template to render the email with.
* Do not include a file extension unless you are referencing a full absolute file path.
*/
public function setHTMLTemplate(string $template): static
{
if (substr($template ?? '', -3) == '.ss') {
$template = substr($template ?? '', 0, -3);
}
$this->HTMLTemplate = $template;
return $this;
}
Expand All @@ -431,13 +426,11 @@ public function getPlainTemplate(): string
}

/**
* Set the template to render the plain part with
* Set the template to render the plain part with.
* Do not include a file extension unless you are referencing a full absolute file path.
*/
public function setPlainTemplate(string $template): static
{
if (substr($template ?? '', -3) == '.ss') {
$template = substr($template ?? '', 0, -3);
}
$this->plainTemplate = $template;
return $this;
}
Expand Down
2 changes: 0 additions & 2 deletions src/Control/HTTPResponse.php
Original file line number Diff line number Diff line change
Expand Up @@ -444,8 +444,6 @@ public function isRedirect()

/**
* The HTTP response represented as a raw string
*
* @return string
*/
public function __toString()
{
Expand Down
10 changes: 5 additions & 5 deletions src/Control/RSS/RSSFeed_Entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class RSSFeed_Entry extends ModelData
*/
public function __construct($entry, $titleField, $descriptionField, $authorField)
{
$this->failover = $entry;
$this->setFailover($entry);
$this->titleField = $titleField;
$this->descriptionField = $descriptionField;
$this->authorField = $authorField;
Expand All @@ -58,7 +58,7 @@ public function __construct($entry, $titleField, $descriptionField, $authorField
/**
* Get the description of this entry
*
* @return DBField Returns the description of the entry.
* @return DBField|null Returns the description of the entry.
*/
public function Title()
{
Expand All @@ -68,7 +68,7 @@ public function Title()
/**
* Get the description of this entry
*
* @return DBField Returns the description of the entry.
* @return DBField|null Returns the description of the entry.
*/
public function Description()
{
Expand All @@ -85,7 +85,7 @@ public function Description()
/**
* Get the author of this entry
*
* @return DBField Returns the author of the entry.
* @return DBField|null Returns the author of the entry.
*/
public function Author()
{
Expand All @@ -96,7 +96,7 @@ public function Author()
* Return the safely casted field
*
* @param string $fieldName Name of field
* @return DBField
* @return DBField|null
*/
public function rssField($fieldName)
{
Expand Down
2 changes: 0 additions & 2 deletions src/Core/Manifest/ModuleResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,6 @@ public function exists()

/**
* Get relative path
*
* @return string
*/
public function __toString()
{
Expand Down
6 changes: 3 additions & 3 deletions src/Dev/Backtrace.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ public static function full_func_name($item, $showArgs = false, $argCharLimit =
if ($showArgs && isset($item['args'])) {
$args = [];
foreach ($item['args'] as $arg) {
if (!is_object($arg) || method_exists($arg, '__toString')) {
if (is_object($arg)) {
$args[] = get_class($arg);
} else {
$sarg = is_array($arg) ? 'Array' : strval($arg);
$args[] = (strlen($sarg ?? '') > $argCharLimit) ? substr($sarg, 0, $argCharLimit) . '...' : $sarg;
} else {
$args[] = get_class($arg);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/Dev/TestSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Exception;
use InvalidArgumentException;
use LogicException;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Cookie_Backend;
use SilverStripe\Control\Director;
Expand Down Expand Up @@ -214,7 +215,7 @@ public function submitForm(string $formID, string $button = null, array $data =
$formCrawler = $page->filterXPath("//form[@id='$formID']");
$form = $formCrawler->form();
} catch (InvalidArgumentException $e) {
user_error("TestSession::submitForm failed to find the form {$formID}");
throw new LogicException("TestSession::submitForm failed to find the form '{$formID}'");
}

foreach ($data as $fieldName => $value) {
Expand All @@ -235,7 +236,7 @@ public function submitForm(string $formID, string $button = null, array $data =
if ($button) {
$btnXpath = "//button[@name='$button'] | //input[@name='$button'][@type='button' or @type='submit']";
if (!$formCrawler->children()->filterXPath($btnXpath)->count()) {
throw new Exception("Can't find button '$button' to submit as part of test.");
throw new LogicException("Can't find button '$button' to submit as part of test.");
}
$values[$button] = true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Forms/DropdownField.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
* DropdownField::create(
* 'Country',
* 'Country',
* singleton(MyObject::class)->dbObject('Country')->enumValues()
* singleton(MyObject::class)->dbObject('Country')?->enumValues()
* );
* </code>
*
Expand Down
2 changes: 1 addition & 1 deletion src/Forms/FieldGroup.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public function getMessage()
/** @var FormField $subfield */
$messages = [];
foreach ($dataFields as $subfield) {
$message = $subfield->obj('Message')->forTemplate();
$message = $subfield->obj('Message')?->forTemplate();
if ($message) {
$messages[] = rtrim($message ?? '', ".");
}
Expand Down
12 changes: 6 additions & 6 deletions src/Forms/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class Form extends ModelData implements HasRequestHandler
const ENC_TYPE_MULTIPART = 'multipart/form-data';

/**
* Accessed by Form.ss.
* Accessed by Form template.
* A performance enhancement over the generate-the-form-tag-and-then-remove-it code that was there previously
*
* @var bool
Expand Down Expand Up @@ -159,7 +159,7 @@ class Form extends ModelData implements HasRequestHandler
/**
* Legend value, to be inserted into the
* <legend> element before the <fieldset>
* in Form.ss template.
* in Form template.
*
* @var string|null
*/
Expand Down Expand Up @@ -888,7 +888,7 @@ public function setTarget($target)

/**
* Set the legend value to be inserted into
* the <legend> element in the Form.ss template.
* the <legend> element in the Form template.
* @param string $legend
* @return $this
*/
Expand All @@ -899,10 +899,10 @@ public function setLegend($legend)
}

/**
* Set the SS template that this form should use
* Set the template or template candidates that this form should use
* to render with. The default is "Form".
*
* @param string|array $template The name of the template (without the .ss extension) or array form
* @param string|array $template The name of the template (without the file extension) or array of candidates
* @return $this
*/
public function setTemplate($template)
Expand Down Expand Up @@ -1234,7 +1234,7 @@ public function getRecord()

/**
* Get the legend value to be inserted into the
* <legend> element in Form.ss
* <legend> element in Form template
*
* @return string
*/
Expand Down
Loading

0 comments on commit 6b33b5a

Please sign in to comment.