我在silverstripe.org网站上观看了第7课 - 第10课的视频,已经阅读了本页面上的所有文章:http://docs.silverstripe.org/en/3.1/developer_guides/model/,已经全部在API中,并且已经使用了数小时的谷歌搜索和/或堆栈论坛。我真的很难尝试应用我学到的东西。这就是我想要做的事情。我想扩展Article Holder&文章页面的概念。我正在尝试创建另一个主文章持有者页面,我的网站树将按此组织:
HomePage
|
| _ MasterArticleHolderOne
| |
| | _ ArticleHolderA
| | |
| | | _ ArticlePageA1
| | |
| | | _ ArticlePageA2
| | |
| | | _ ArticlePageA3
| |
| |
| | _ ArticleHolderB
| | |
| | | _ ArticlePageB1
| | |
| | | _ ArticlePageB2
| | |
| | | _ ArticlePageB3
| |
| |
| | _ ArticleHolderB
| |
| | _ ArticlePageB1
| |
| | _ ArticlePageB2
| |
| | _ ArticlePageB3
|
| _ MasterArticleHolderTwo
我希望MasterArticleHolder页面能做到这一点:CMS中有一个选项可供MasterArticleHolder页面选择任何现有的ArticleHolder页面(意味着即使上面的MasterArticleHolderTwo也可以显示来自ArticleHolderA或B或C的文章)和然后,MasterArticleHolder页面将显示所选ArticleHolder页面的子项的所有文章。这些文章需要按PublicationDate排序;没有按照他们所属的持有人分组。
这是我到目前为止编写的代码。 ArticlePage和ArticleHolder完美地工作。它是我正在努力的MasterArticleHolder(尽管我设法至少在CMS中为所有现有的ArticleHolder页面创建了复选框,但是不知道它是否会在其他所有内容实际运行后写的):
ArticlePage
class ArticlePage extends Page {
private static $db = array(
'PublicationDate' => 'Date',
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', DateField::create('PublicationDate','Publication Date')->setConfig('showcalendar', true));
return $fields;
}
}
ArticleHolder
class ArticleHolder_Controller extends Page_Controller {
public function LatestArticles() {
return ArticlePage::get()
->filter('PublicationDate:LessThanOrEqual', SS_Datetime::now())
->sort('PublicationDate', 'DESC');
}
}
MasterArticleHolder
class MasterArticleHolder extends Page {
private static $many_many = array (
'Categories' => 'ArticleHolder'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', CheckboxSetField::create(
'Categories',
'Articles to Display',
ArticleHolder::get()->map('ID','MenuTitle')
));
return $fields;
}
}
class MasterArticleHolder_Controller extends Page_Controller {
public function LatestArticles() {
return ArticlePage::get()
->filter(array('PublicationDate:LessThanOrEqual' => SS_Datetime::now()))
->sort('PublicationDate', 'DESC')
}
}
在我看来可能存在以下关系,但我不知道哪一个是必需的,如果有的话
以下关系也可能适用,但对我来说似乎不太可能
现在我通常知道has_one,has_many和many_many适用于扩展DataObject的对象但是我认为,因为以圆形方式的页面扩展了DataObject,这些关系可能仍然适用,但我可能完全错了,真的过度思考。
希望我能够很好地解释自己以获得帮助,但不能过多地压倒所有人。我很感激您的反馈!
答案 0 :(得分:0)
你应该进一步深入研究教程,这个(使用Pages)是......不是最好的解决方案。它可以工作,但是非常复杂,并不是一个好主意。
如果您将此作为一项学习练习,那么这很酷,但如果不是,那么只需使用博客模块http://addons.silverstripe.org/add-ons/silverstripe/blog - 它基本上就是这样。
最好在本练习中使用DataObjects而不是Pages。请参阅视频教程9(http://www.silverstripe.org/learn/lessons/working-with-data-relationships-has-many)
现在你所拥有的一个简单的解决方案是:
ArticlePage::get()
->filter([
'ParentID'=>$this->Categories()->getIDList(),
'PublicationDate:LessThanOrEqual'=>'now'
])
->sort('PublicationDate','desc');
基本上:让每篇文章的父母都是我选择的类别之一(然后是现有的过滤器,排序等)。
使用DataObjects而不是Pages基本上是相同的(Pages是DataObjects),但是您可以减少对站点树(在CMS中)的污染以及与子项等有关的层次问题。
但另一方面,你放松了自动路由,以及Page给你的各种其他东西。这就是为什么Blog模块是一个更好的解决方案,如果您不只是想学习。
答案 1 :(得分:0)
可悲的是,我没有时间对这些进行测试,但以下情况应该起作用..至少作为指导:
删除
private static $many_many = array (
'Categories' => 'ArticleHolder'
);
并将类别添加为数据库字段
private static $db = array(
'Categories' => 'Varchar'
);
无需引入新关系,因为他们已经是该持有人的子女。复选框字段集将数据存储为逗号分隔列表。这是一个松散的关系所以请注意。
然后在过滤器中使用逗号分隔列表,例如:
public function LatestArticles() {
$ids = explode(",", $this->Categories)
return ArticlePage::get()
->filter(array('ParentID' => $ids))
->sort('PublicationDate', 'DESC')
}
我不记得是数据库字段parent_id还是ParentID,或者你可能希望从数据库表中检出什么。