如何在 Silverstripe 3 中显示 children 的单个页面,每个页面类型的视图

How to display single page of children with a view per page types in Silverstripe 3

我有一个单页应用程序,我可以通过

在我的 page.ss 中显示所有 children
<% control children %>

然而,这只会通过 page.ss 输出为 1 个视图,我想为每种页面类型使用单独的视图,所有这些都在单个页面应用程序设计中。

所以我的索引页包含 children 页的所有内容,但我希望每个 children 页都有自己的视图。

这在 Silverstripe 3 中是否可行?如果可行,如何实现?

查看 StripeCon EU website 的代码 它适用于部分(实际上是页面)。这些部分是独立可见的,但在主页上,它是一页纸。

我想这就是你想要的?

您可以使用 DataObjects 而不是页面,如其他答案所示(我的 blocks-module 的无耻插件)。

如果您更喜欢页面,那也是可以的。在模板方面需要一些技巧,但一旦设置就可以很好地工作。

首页

首先,您的页面需要一个入口点。这通常是主页。它需要一个单独的模板,因此我建议您为此创建一个特殊的 HomePage class。

例如。

<?php
class HomePage extends Page
{
    // only allow one HomePage
    public function canCreate($member = null)
    {
        return parent::canCreate($member) 
            ? HomePage::get()->count() == 0
            : false;
    }
}

class HomePage_Controller extends Page_Controller
{

}

特殊模板

您的主页会将所有其他页面呈现到一个模板中。我以一种方式实现了这一点,即页面使用不同的模板呈现到单页视图中。在 Page class:

中创建这样的方法
/**
 * Get markup for single-page layout
 * @return HTMLText
 */
public function getHTML()
{
    return $this->renderWith(array('Flat' . $this->ClassName, 'FlatPage'));
}

此设置要求模板是您的 class-名称,前缀为 Flat。因此,如果您有 GalleryPage class,它将使用 FlatGalleryPage 模板。如果找不到模板,它将回退到 FlatPage。为清楚起见,您可以在单独的文件夹中创建所有这些模板。例如。

# Example folder structure
templates
  + SinglePage
      + FlatPage.ss
      + FlatGalleryPage.ss
      + …

使用此设置,您可以为单页输出和 "regular" 输出使用不同的模板。

结合前面的步骤

在您的 HomePage.ss 模板中,您现在可以像这样呈现所有页面:

<% loop $Menu(1) %>
    <section id="$URLSegment">
        $HTML
    </section>
<% end_loop %>

您的导航可能如下所示:

<nav class="main">
    <ul>
    <% loop $Menu(1) %>
        <li>
            <a href="#/$URLSegment" >$MainMenuTitle</a>
        </li>
    <% end_loop %>
    </ul>
</nav>

这只会添加一个基于锚点的导航来导航到不同的页面。您可以随意添加一些 JavaScript.

注意事项和提示

单页视图中的表单很棘手,因为您是通过单个控制器查看不同的页面。响应渲染也很困难。如果您需要在单页应用程序中使用表单,我建议您使用 AJAX 让用户保持在当前视图中。

如果您想阻止直接访问子页面,您可以使用数据扩展将用户重定向到主页。示例:

<?php

/**
 * Redirect to the home-page whenever somebody tries to access this page
 */
class RedirectToHomeExtension extends DataExtension
{
    public function contentcontrollerInit($controller)
    {
        // Check if the current user isn't somebody with CMS access,
        // since this would mess with the CMS preview-pane.
        if (!(
            Permission::check('CMS_ACCESS_CMSMain', 'any') ||
            Permission::check('CMS_ACCESS_LeftAndMain', 'any')
        )){
            $controller->redirect(HomePage::get()->First()->Link(), 301);
        }
    }
}

然后通过配置像往常一样应用它:

GalleryPage:
  extensions:
    - RedirectToHomeExtension