如何检测 Silverstripe 页面作为父项或子项加载到 Controller 中

How to detect Silverstripe page is loaded in Controller as parent or child

我们的 Silverstripe 项目有以下两种页面类型:

class MultiSectionPage extends Page {
  private static $allowed_children = array(
    'Section'
  );

  public function PageSections() {
    $PageSections = Section::get()->filter(array('ParentID' => $this->ID));
    return $PageSections;
  }
}

class Section extends Page {
  public static $allowed_children = array();
  private static $show_in_sitetree = false;
}

在 Layout/MultiSectionPage.ss 模板中,以下代码作为数据对象循环遍历每个子部分:

<% loop $PageSections %>
<% include MultiSectionPage_Section %>
<% end_loop %>

我想确保如果有人不小心链接到某个部分,它会重定向到父 MultiSectionPage。

class Section extends Page {
  public function Link() {
    return parent::Link() . '#section-' . $this->ID;
  }
}

class Section_Controller extends Page_Controller {

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

    if(!$this->getResponse()->isFinished() && $link = $this->Link()) {
        $this->redirect($link, 301);
        return;
    }
  }
}

但是,即使在查看 MultiSectionPage 时使用此方法也会触发重定向,因为每次呈现 Section DataObject 时都必须调用 init。

如何检测节控制器是作为独立父项(重定向)加载还是作为 MultiSectionPage 的子项加载?

查看 MultiSectionPage 时不应调用 Section_Controller。循环通过 PageSections 时仅加载 Section 对象。当检索 DataObjectsDataList 时,只加载它们的 class,而不是它们的控制器。

请注意 Section_Controller 应该重定向到父页面 link,而不是当前页面 link。我还建议将 Section Link 函数更新为 return 父 link:

class Section extends Page {
    private static $allowed_children = array();
    private static $show_in_sitetree = false;

    public function Link($action = null) {
        return $this->Parent()->Link($action);
    }
}

class Section_Controller extends Page_Controller {
    public function init() {
        parent::init();

        return $this->redirect($this->Parent()->Link(), 301);
    }
}