正在更改Silverstepe中的模板继承顺序



根据Silverstepe的文档,模板继承定义如下:

  1. mysite(或站点文件夹的其他名称)
  2. 模块特定主题(例如主题/simple_blog)
  3. 主题(例如主题/简单)
  4. 模块(例如博客)
  5. 框架

现在我有一个网站,有很多不同的主题。嗯,";不同的";因为他们有不同的名字,但他们仍然有很多共同点。现在,我将所有常用文件放在/mysite/templates文件夹中,但这意味着,如果我的某个主题需要更改其中一个模板,我需要从常用文件夹中删除该文件,并将其移动到所有不同的主题文件夹中。通过这种方式,我最终得到了很多重复的模板。

在我的情况下,更改继承顺序将是有益的,使特定的主题文件夹优先于/mysite文件夹。通过这种方式,我可以将必须更改的模板复制到主题文件夹中,主题文件夹将使用更改后的模板,而其他模板则继续使用/mysite文件夹中的通用模板:

  1. 主题(例如主题/简单)
  2. 模块特定主题(例如主题/simple_blog)
  3. mysite(或站点文件夹的其他名称)
  4. 模块(例如博客)
  5. 框架

在我看来,这也是一种更令人反感的方式,但我可能错过了一些重要的一点。尽管如此,在不侵入核心的情况下,这样做可能吗?

模板继承渲染似乎主要由两个类管理,SSViewer(用于处理视图渲染的核心类)和Controller(所有其他控制器都从中继承)。

对于视图渲染,SSViewer对象可以在其构造函数中使用数组进行模板继承。这一点很重要,因为Controller类实际上在一个名为getViewer的函数中实例化了SSViewer

在这个阶段需要注意的是,您通常从ContentController继承的普通SilverStripe站点会覆盖ControllergetViewer。它不会真正改变你需要写的东西,但它很重要,这取决于你希望它应用的级别有多低。

对于一般情况下要应用于页面的内容,您可以考虑在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,应参考与SilverStripe3.x相关的查询。以下内容适用于Silver Stripe 4。

由于SilverStripe 4目前是最新的稳定版本,现在设置了主题继承而不是模板继承,因此这个问题和答案可能不适合更新的安装或最新的安装。

在SilverStripe 4中控制继承的最佳方法是确保以正确的顺序配置主题,并适当配置模块继承。

mysite/_config/theme.yml文件通常声明主题继承,您应该调整此文件以适当地控制主题继承。对于模块,您需要在mycustommodule/_config/modules.yml文件中指定适当的BeforeAfter

以下示例适用于同时具有mytheme和simple主题的sile、没有_config/modules.yml文件的自定义模块和没有_config/modules.yml文件的供应商模块。

SilverStripeViewSSViewer:
  themes:
    - 'mytheme'
    - 'simple'
    - '$default'

在本例中,SSViewer::get_themes()将以相同的顺序将这三项作为数组返回:['mytheme', 'simple', '$default]。当检查模板是否存在时,$default将被定义模板的所有模块的路径替换,其顺序与它们在清单中出现的顺序相同。

<?php
use SilverStripeViewThemeResourceLoader;
$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'
];

最新更新