在 Silverstripe 中更改模板继承顺序
Changing template inheritance order in Silverstripe
根据the documentation of Silverstripe,模板继承定义如下:
- mysite(或站点文件夹的其他名称)
- 特定于模块的主题(例如 themes/simple_blog)
- 主题(例如 themes/simple)
- 模块(例如博客)
- 框架
现在我的网站有很多不同的主题。好吧,“不同”是因为他们有不同的名字,但他们仍然有很多共同点。现在我将所有通用文件放在 /mysite/templates 文件夹中,但这意味着如果我的主题之一需要更改其中一个模板,我需要从通用文件夹中删除该文件,并将其移动到所有不同的主题文件夹。这样我就得到了很多重复的模板。
在我的例子中,更改继承顺序会有所帮助,使特定主题文件夹优先于 /mysite 文件夹。这样我就可以将必须更改的模板复制到主题文件夹中,该主题将使用更改后的模板,而其余的则继续使用 /mysite 文件夹中的通用模板:
- 主题(例如 themes/simple)
- 特定于模块的主题(例如 themes/simple_blog)
- mysite(或站点文件夹的其他名称)
- 模块(例如博客)
- 框架
在我看来,这也是更明显的方法,但我可能在这里遗漏了一些重要的观点。尽管如此,如果不破解核心是否可以做到这一点?
模板继承渲染似乎主要由两个 class 管理,SSViewer
(处理视图渲染的核心 class)和 Controller
(所有其他控制器继承自)。
对于视图渲染,SSViewer
对象可以 take an array in its constructor for template inheritance. This is important because the Controller
class actually instantiates the SSViewer
in a function called getViewer
。
在此阶段需要特别提及的是,您通常从 ContentController
而不是 overrides the getViewer
of Controller
继承的普通 SilverStripe 站点。它不会真正改变您需要编写的内容,但它很重要,具体取决于您希望它应用到多低的级别。
对于一般要应用于页面的内容,您会考虑在 Page_Controller
中覆盖 getViewer
。至于具体需要写什么,这在某种程度上取决于您的整个站点结构。我想它需要像这样开始:
public function getViewer($action) {
$viewer = Parent::getViewer($action);
$templates = $viewer->templates();
//Do your processing that you need to here
//Set it back via:
//$viewer->setTemplateFile($type, $file);
//Alternatively, you can create a new SSViewer object
return $viewer;
}
虽然这绝非易事,但需要进行一些实验才能确定您究竟需要做什么来对数据进行混洗。一旦开始沿着这条路走下去,您可能会发现许多边缘情况可能无法正常工作(例如,模板包含)。
问题和已接受的答案是针对 SilverStripe 3 的,应参考与 SilverStripe 3.x 相关的查询。以下参考SilverStripe 4.
由于SilverStripe 4是目前最新的稳定版,现在设置主题继承而不是模板继承,问答可能不适合较新的安装或最新的安装。
在 SilverStripe 4 中控制继承的最佳方法是确保以正确的顺序配置主题,并正确配置模块继承。
您的 mysite/_config/theme.yml
文件通常会声明主题继承,您应该调整此文件以适当地控制主题继承。对于模块,您需要在 mycustommodule/_config/modules.yml
文件中指定适当的 Before
和 After
。
以下示例适用于同时具有 mytheme 和简单主题的 sile、没有 _config/modules.yml
文件的自定义模块和没有 _config/modules.yml
文件的供应商模块。
SilverStripe\View\SSViewer:
themes:
- 'mytheme'
- 'simple'
- '$default'
在此示例中,SSViewer::get_themes()
将 return 这三个项目作为一个数组,顺序相同:['mytheme', 'simple', '$default]
。当检查模板是否存在时,$default
将被所有定义模板的模块的路径替换,顺序与它们在清单中出现的顺序相同。
<?php
use SilverStripe\View\ThemeResourceLoader;
$templatePaths = ThemeResourceLoader::inst()->getThemePaths(SSViewer::get_themes());
$templatePaths === [
'themes/mytheme',
'themes/simple',
'mycustommodule',
'vendor/silverstripe/asset-admin',
'vendor/silverstripe/campaign-admin',
'vendor/silverstripe/reports',
'vendor/silverstripe/siteconfig',
// Some vendor modules may appear here...
'vendor/othervendor/custommodule',
'vendor/silverstripe/cms',
'vendor/silverstripe/admin',
'vendor/silverstripe/assets',
'vendor/silverstripe/framework'
];
根据the documentation of Silverstripe,模板继承定义如下:
- mysite(或站点文件夹的其他名称)
- 特定于模块的主题(例如 themes/simple_blog)
- 主题(例如 themes/simple)
- 模块(例如博客)
- 框架
现在我的网站有很多不同的主题。好吧,“不同”是因为他们有不同的名字,但他们仍然有很多共同点。现在我将所有通用文件放在 /mysite/templates 文件夹中,但这意味着如果我的主题之一需要更改其中一个模板,我需要从通用文件夹中删除该文件,并将其移动到所有不同的主题文件夹。这样我就得到了很多重复的模板。
在我的例子中,更改继承顺序会有所帮助,使特定主题文件夹优先于 /mysite 文件夹。这样我就可以将必须更改的模板复制到主题文件夹中,该主题将使用更改后的模板,而其余的则继续使用 /mysite 文件夹中的通用模板:
- 主题(例如 themes/simple)
- 特定于模块的主题(例如 themes/simple_blog)
- mysite(或站点文件夹的其他名称)
- 模块(例如博客)
- 框架
在我看来,这也是更明显的方法,但我可能在这里遗漏了一些重要的观点。尽管如此,如果不破解核心是否可以做到这一点?
模板继承渲染似乎主要由两个 class 管理,SSViewer
(处理视图渲染的核心 class)和 Controller
(所有其他控制器继承自)。
对于视图渲染,SSViewer
对象可以 take an array in its constructor for template inheritance. This is important because the Controller
class actually instantiates the SSViewer
in a function called getViewer
。
在此阶段需要特别提及的是,您通常从 ContentController
而不是 overrides the getViewer
of Controller
继承的普通 SilverStripe 站点。它不会真正改变您需要编写的内容,但它很重要,具体取决于您希望它应用到多低的级别。
对于一般要应用于页面的内容,您会考虑在 Page_Controller
中覆盖 getViewer
。至于具体需要写什么,这在某种程度上取决于您的整个站点结构。我想它需要像这样开始:
public function getViewer($action) {
$viewer = Parent::getViewer($action);
$templates = $viewer->templates();
//Do your processing that you need to here
//Set it back via:
//$viewer->setTemplateFile($type, $file);
//Alternatively, you can create a new SSViewer object
return $viewer;
}
虽然这绝非易事,但需要进行一些实验才能确定您究竟需要做什么来对数据进行混洗。一旦开始沿着这条路走下去,您可能会发现许多边缘情况可能无法正常工作(例如,模板包含)。
问题和已接受的答案是针对 SilverStripe 3 的,应参考与 SilverStripe 3.x 相关的查询。以下参考SilverStripe 4.
由于SilverStripe 4是目前最新的稳定版,现在设置主题继承而不是模板继承,问答可能不适合较新的安装或最新的安装。
在 SilverStripe 4 中控制继承的最佳方法是确保以正确的顺序配置主题,并正确配置模块继承。
您的 mysite/_config/theme.yml
文件通常会声明主题继承,您应该调整此文件以适当地控制主题继承。对于模块,您需要在 mycustommodule/_config/modules.yml
文件中指定适当的 Before
和 After
。
以下示例适用于同时具有 mytheme 和简单主题的 sile、没有 _config/modules.yml
文件的自定义模块和没有 _config/modules.yml
文件的供应商模块。
SilverStripe\View\SSViewer:
themes:
- 'mytheme'
- 'simple'
- '$default'
在此示例中,SSViewer::get_themes()
将 return 这三个项目作为一个数组,顺序相同:['mytheme', 'simple', '$default]
。当检查模板是否存在时,$default
将被所有定义模板的模块的路径替换,顺序与它们在清单中出现的顺序相同。
<?php
use SilverStripe\View\ThemeResourceLoader;
$templatePaths = ThemeResourceLoader::inst()->getThemePaths(SSViewer::get_themes());
$templatePaths === [
'themes/mytheme',
'themes/simple',
'mycustommodule',
'vendor/silverstripe/asset-admin',
'vendor/silverstripe/campaign-admin',
'vendor/silverstripe/reports',
'vendor/silverstripe/siteconfig',
// Some vendor modules may appear here...
'vendor/othervendor/custommodule',
'vendor/silverstripe/cms',
'vendor/silverstripe/admin',
'vendor/silverstripe/assets',
'vendor/silverstripe/framework'
];