Silverstripe 3:如何按标题、日期等对 CMS 站点树中的页面进行排序
Silverstripe 3: how to sort pages in the CMS sitetree by title, date etc
我正在寻找一个工作示例,说明如何在默认情况下按标题对站点树中的页面进行排序。理想情况下,我只想对 child 特定类型的页面进行排序。在我的例子中,我希望 parent 投资组合下的所有图库页面都按标题的字母顺序排序。
这是为了在后端 CMS 中轻松搜索,因为我知道如何在模板中对它们进行排序。
我找到了这些示例,但不足以解决 SS3.1+
http://www.ssbits.com/tutorials/2011/custom-sorting-in-the-cms-sitetree/
https://github.com/silverstripe/silverstripe-cms/issues/848
查看您提供的示例和当前的 Silverstripe 源代码,您可以通过几种方法来解决这个问题。我的解决方案涉及使用 Silverstripe 的扩展系统来操纵层次结构的生成方式。
如何加载 SiteTree
CMS 加载站点树的方式有点冗长,所以我将快速简化:
- 模板
CMSPagesController_Content.ss
(用于页面部分)具有指向 lazy-load 链接树视图的标记
- 链接树视图(
CMSMain
中指定的函数)调用一些内部方法基本上加载CMSMain_TreeView
模板
此模板调用 CMSMain
中的 SiteTreeAsUL
函数
Note: SiteTreeAsUL
allows us to hook in before returning using the extension system in Silverstripe though we don't want to manipulate
the HTML directly.
getSiteTreeFor
, a function part of LeftAndMain
,在SiteTreeAsUL
.
里面调用
getSiteTreeFor
调用 getChildrenAsUL
, a function part of Hierarchy
,它实际上执行 HTML 构建,但最重要的是,调用正确的 "children" 方法。
我说正确的children方法有几个:
因为调用getSiteTreeFor
时没有指定children方法,it uses a hardcoded default of AllChildrenIncludingDeleted
.
现在,是时候对 children...
进行排序了
调用函数 AllChildrenIncludingDeleted
进行了几次调用,但我们想知道的是它在内部调用了扩展方法 augmentAllChildrenIncludingDeleted
.
因此,要完成您想做的事情,您可能会希望使用扩展函数 augmentAllChildrenIncludingDeleted
为 SiteTree
编写一个扩展。第一个参数是所有 children 的列表,它们存储为 ArrayList
.
Technical Note: It actually can be an ArrayList
OR DataList
because if there are no live children, it returns the raw result of
stageChildren
which is a DataList
.
While both have sort functions, they may act differently.
ArrayList
provides a sort function 这将使您能够按照自己的意愿去做。
像这样的东西应该可以工作:
class CMSSiteTreeSortingExtension extends Extension
{
public function augmentAllChildrenIncludingDeleted($Children, $Context = null)
{
if ($this->owner->ClassName == 'GalleryPage')
{
//Do your class specific sorting here....
}
$Children = $Children->sort('Title DESC');
}
}
并且只需将扩展名设置为 SiteTree
(或者 Page
如果需要,应该仍然有效)。
免责声明:我没有亲自尝试过,但它遵循 Silverstripe 如何与扩展一起工作的标准模式,因此您应该不会有问题。
当我无法使上述代码工作时,我一直在寻找一种在 SS4 中实现此目的的方法。这就是我想出的。
use SilverStripe\ORM\DB;
class MemberPage extends Page
{
public function onAfterWrite(){
parent::onAfterWrite();
$pages = MemberPage::get()->sort('Title');
$sortIndex = 0;
foreach ($pages as $page){
//sort indexes start at 1
$sortIndex++;
if ($page->Sort != $sortIndex){
//we can't use $page->write() here, otherwise it'll cause infinite loops,
//we'll just have to run the query on the database directly
DB::query("UPDATE SiteTree SET Sort = {$sortIndex} WHERE ID = {$page->ID}");
}
}
}
}
它不完全是 'the silverstripe way' 但它有效。
我正在寻找一个工作示例,说明如何在默认情况下按标题对站点树中的页面进行排序。理想情况下,我只想对 child 特定类型的页面进行排序。在我的例子中,我希望 parent 投资组合下的所有图库页面都按标题的字母顺序排序。 这是为了在后端 CMS 中轻松搜索,因为我知道如何在模板中对它们进行排序。
我找到了这些示例,但不足以解决 SS3.1+
http://www.ssbits.com/tutorials/2011/custom-sorting-in-the-cms-sitetree/ https://github.com/silverstripe/silverstripe-cms/issues/848
查看您提供的示例和当前的 Silverstripe 源代码,您可以通过几种方法来解决这个问题。我的解决方案涉及使用 Silverstripe 的扩展系统来操纵层次结构的生成方式。
如何加载 SiteTree
CMS 加载站点树的方式有点冗长,所以我将快速简化:
- 模板
CMSPagesController_Content.ss
(用于页面部分)具有指向 lazy-load 链接树视图的标记 - 链接树视图(
CMSMain
中指定的函数)调用一些内部方法基本上加载CMSMain_TreeView
模板 此模板调用
中的CMSMain
SiteTreeAsUL
函数Note:
SiteTreeAsUL
allows us to hook in before returning using the extension system in Silverstripe though we don't want to manipulate the HTML directly.getSiteTreeFor
, a function part ofLeftAndMain
,在SiteTreeAsUL
. 里面调用
getSiteTreeFor
调用getChildrenAsUL
, a function part ofHierarchy
,它实际上执行 HTML 构建,但最重要的是,调用正确的 "children" 方法。
我说正确的children方法有几个:
因为调用getSiteTreeFor
时没有指定children方法,it uses a hardcoded default of AllChildrenIncludingDeleted
.
现在,是时候对 children...
进行排序了调用函数 AllChildrenIncludingDeleted
进行了几次调用,但我们想知道的是它在内部调用了扩展方法 augmentAllChildrenIncludingDeleted
.
因此,要完成您想做的事情,您可能会希望使用扩展函数 augmentAllChildrenIncludingDeleted
为 SiteTree
编写一个扩展。第一个参数是所有 children 的列表,它们存储为 ArrayList
.
Technical Note: It actually can be an
ArrayList
ORDataList
because if there are no live children, it returns the raw result ofstageChildren
which is aDataList
. While both have sort functions, they may act differently.
ArrayList
provides a sort function 这将使您能够按照自己的意愿去做。
像这样的东西应该可以工作:
class CMSSiteTreeSortingExtension extends Extension
{
public function augmentAllChildrenIncludingDeleted($Children, $Context = null)
{
if ($this->owner->ClassName == 'GalleryPage')
{
//Do your class specific sorting here....
}
$Children = $Children->sort('Title DESC');
}
}
并且只需将扩展名设置为 SiteTree
(或者 Page
如果需要,应该仍然有效)。
免责声明:我没有亲自尝试过,但它遵循 Silverstripe 如何与扩展一起工作的标准模式,因此您应该不会有问题。
当我无法使上述代码工作时,我一直在寻找一种在 SS4 中实现此目的的方法。这就是我想出的。
use SilverStripe\ORM\DB;
class MemberPage extends Page
{
public function onAfterWrite(){
parent::onAfterWrite();
$pages = MemberPage::get()->sort('Title');
$sortIndex = 0;
foreach ($pages as $page){
//sort indexes start at 1
$sortIndex++;
if ($page->Sort != $sortIndex){
//we can't use $page->write() here, otherwise it'll cause infinite loops,
//we'll just have to run the query on the database directly
DB::query("UPDATE SiteTree SET Sort = {$sortIndex} WHERE ID = {$page->ID}");
}
}
}
}
它不完全是 'the silverstripe way' 但它有效。