通过$ has_many关系的数据对象循环?

时间:2016-03-24 02:30:30

标签: silverstripe

我的$has_manyDashboardPage数据对象之间存在PastEvent关系。在我的DashboardPage.ss模板中,我希望能够遍历所有PastEvents。我相信由于 $ has_many 关系,我应该可以在DashboardPage.ss模板上执行以下操作:

DashboardPage.ss

<% loop $PastEvents %>
    <div>
      <div>$EventName</div>
      <div>$ClassType</div>
      etc...
   </div>
<% end_loop %>

然而,没有任何表现。我错过了什么?

DashboardPage.php

<?php

class DashboardPage extends Page implements TemplateGlobalProvider {

    private static $db = array(
        'Testing' => 'Varchar(255)'
    );

    private static $has_many = array(
        'PastEvents' => 'PastEvent'
    );

    public function getCMSFields() {
        $fields = parent::getCMSFields();

        $fields->removeByName('Content');

        return $fields;
    }

    public static function get_template_global_variables() {
        return array('DashboardLink' => 'getDashboardLink');
    }

    public static function getDashboardLink($action='') {
        $page = DashboardPage::get()->first();
        return $page ? $page->Link($action) : '';
    }

}

class DashboardPage_Controller extends Page_Controller {

    private static $allowed_actions = array(
        'show'
    );


    public function init() {
        parent::init();

        Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.carousel.css');
        Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.theme.css');
        Requirements::css('themes/' . SSViewer::current_theme() . '/owl-carousel/owl.transitions.css');
    }

    public function show(){
        dd('Coming here');
    }

}

PastEvent.php

<?php

class PastEvent extends DataObject {

    private static $db = array(
        'EventName' => 'Varchar(255)',
        'ClassType' => 'Varchar(255)',
        'Instructor' => 'Varchar(255)',
        'EmbedCode' => 'Text',
        'EventDate' => 'Date',
        'Time' => 'Time'
    );

    private static $has_one = array(
        'BranchLocation' => 'BranchLocation',
        'DashboardPage' => 'DashboardPage'
    );

    private static $summary_fields = array(
        'EventName' => 'EventName',
        'BranchLocation.Name' => 'Branch Location',
        'ClassType' => 'ClassType',
        'Instructor' => 'Instructor',
        'EventDate' => 'Event Date',
        'Time' => 'Time',
    );

    public function getCMSFields() {
        $fields = new FieldList(
            TextField::create('EventName'),
            TextField::create('ClassType'),
            TextField::create('Instructor'),
            DropdownField::create(
                'BranchLocationID',
                'Branch Location',
                BranchLocation::get()->map('ID', 'Name')->toArray()
            ),
            TextareaField::create('EmbedCode'),
            DateField::create('EventDate')->setConfig('showcalendar', true)->setDescription('Click inside textbox to open calender'),
            TimePickerField::create('Time')
        );

        return $fields;
    }

    public function Link() {
        return $this->DashboardPage()->Link('show/'.$this->ID);
    }

}

1 个答案:

答案 0 :(得分:2)

您需要在DashboardPage上管理PastEvent

public function getCMSFields() {
...
    $fields->push(GridField::create('PastEvents', 'Past Events',
        $this->PastEvents(),
        singleton('PastEvent')->canEdit()
            ? GridFieldConfig_RecordEditor::create()
            : GridFieldConfig_RecordViewer::create()
    ));
...
}

您可以添加其他地方的过去活动,假设您使用“/ dashboard”网址创建了自己的网页。

$dashboard = SiteTree::get_by_link('dashboard');
$events = $dashboard->PastEvents();
$events->add($this->createNewEvent());

您不需要show()操作来显示DashboardPage(默认情况下使用隐式index()操作)。页面操作会扩展页面网址,因此当您请求/dashboard/show时,系统会调用您的操作,这似乎是您的意图。

改进模板以显示没有事件:

<% if $PastEvents.Count %>
    <ul>
    <% loop $PastEvents %>
        <li>
            <a href="$Link">$EventName</a>
            <div>$ClassType</div>
            ...
        </li>
    <% end_loop %>
    </ul>
<% else %>
    <p>There are no past events.</p>
<% end_if %>

由于您的网页提供了show操作

的正确链接
public function Link() {
    return $this->DashboardPage()->Link('show/'.$this->ID);
}

你的节目动作可能就像这样

public function show($eventID = 0) {
    $event = $this->PastEvents()->byID($eventID);
    if (!$event) {
        $this->httpError(404);
    }

    // render with templates/Page.ss and templates/Layout/PastEventDetails.ss
    return $event->renderWith(array('PastEventDetails', 'Page'));
}