如何在 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
我有一个单页应用程序,我可以通过
在我的 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