zirak / widget-pages-extension
自由灵感来源于 burnbright/silverstripe-widgetpages,将 Widget 的 Gridfield 添加到扩展页面
Requires
README
自由灵感来源于 burnbright/silverstripe-widgetpages,它将 Widget 的 Gridfields 添加到扩展页面或 DataObjects。Widgets Pages Extension 是实际 widget 模块的增强(http://addons.silverstripe.org/add-ons/silverstripe/widgets)。
简介
此模块是为了解决一个老而令人烦恼的 widget 模块错误:[silverstripe/silverstripe-widgets#20](https://github.com/silverstripe/silverstripe-widgets/issues/20)。它也是一个通过许多_many 关系而不是实际 has_many 关系管理 widget 的替代方法的证明。通过此模块扩展 widget 行为,您可以链接现有的 widget,而不是再次重写它们。Widget 在其 WidgetArea 内可排序。此外,DataObjects 也可以有它们的 widget。
要求
- SilverStripe 3.1 或 3.2
安装
通过 composer 安装模块
composer zirak/widget-pages-extension
通过以下 yaml 扩展所需的页面
:::yml
Page:
extensions:
- WidgetPage
在 $has_one 关系中定义 WidgetAreas,并指定哪些 $allowed_widgets 对此页面类型是允许的
:::php
class Page extends SiteTree {
private static $db = array(
);
private static $has_one = array(
'HeaderBar' => 'WidgetArea',
'FooterBar' => 'WidgetArea'
);
private static $allowed_widgets = array(
'StandardWidget',
'TwitterWidget',
'FacebookWidget'
);
}
运行 dev/build
,并调整您的模板以通过调用 $WidgetArea 函数并传入 WidgetArea 名称作为参数来包含结果 WidgetArea 视图。它将遍历所有 widget。
:::HTML
<div class="typography">
<h2>HeaderBar</h2>
<% loop $WidgetArea(HeaderBar) %>
$WidgetHolder
<% end_loop %>
</div>
<div class="typography">
<h2>FooterBar</h2>
<% loop $WidgetArea(FooterBar) %>
$WidgetHolder
<% end_loop %>
</div>
要启用后端中的 WidgetAreas,请从“从父页面继承侧边栏”中移除检查,并保存页面。模块将创建 WidgetAreas,现在您可以开始填充它们。如果您保留页面上的标志,它将在父页面中搜索 Widget,由于它找到 SiteTree 根,然后停止并返回一个空的 WidgetArea。
在安装后,仔细阅读本文件末尾的 问题 部分。我正在努力解决这个问题,但并不容易(欢迎提交 PR)。
安装 widget
请参阅 widget 模块文档(http://addons.silverstripe.org/add-ons/silverstripe/widgets)。
将 widget 添加到其他页面
为了在页面上使 Widget 工作,您必须做几件事情。
- 安装 Widgets Pages Extension 模块,见上文。
- 将一个或多个 WidgetArea 字段添加到您的页面。
- 运行 dev/build?flush=all
mysite/code/Page.php
:::php
class Page extends SiteTree {
private static $db = array(
);
// Add 4 WidgetAreas
private static $has_one = array(
'HeaderBar' => 'WidgetArea',
'SidebarBar' => 'WidgetArea'
'CenterWidgetArea' => 'WidgetArea'
'FooterBar' => 'WidgetArea'
);
private static $allowed_widgets = array(
'StandardWidget',
'TwitterWidget',
'FacebookWidget'
);
}
在这种情况下,您需要修改您的模板以遍历 $WidgetArea(HeaderBar)、$WidgetArea(SidebarBar)、$WidgetArea(CenterWidgetArea) 和 $WidgetArea(FooterBar)。
编写自己的 widget
请参阅 widget 模块文档(http://addons.silverstripe.org/add-ons/silverstripe/widgets)。
将 widget 添加到 DataObjects
一个 DataObject 可以渲染为页面,只需要一个路由和一个控制器。借助 Widgets Pages Extension,DataObjects 也可以有自己的 widget。以下是一个示例:
DataObject
mysite/code/DoSurfboard.php
:::php
class DoSurfboard extends DataObject {
private static $db = array(
'Name' => 'Varchar',
'Color' => 'Varchar'
);
private static $has_one = array(
'LeftSidebar' => 'WidgetArea'
);
private static $summary_fields = array (
'Name',
'Color'
);
}
将 Widgets Pages Extension 添加到 DataObject
mysite/code/_config/extensions.yml
:::yml
---
Name: my-extensions
---
DoSurfboard:
extensions:
- WidgetDataObject
路由
mysite/code/_config/routes.yml
:::yml
---
Name: myroutes
After: framework/routes#coreroutes
---
Director:
rules:
'surfboard//$ID!': 'ShowSurfboard'
控制器
mysite/code/Controllers/ShowSurfboard.php
:::php
class ShowSurfboard extends ContentController {
private static $url_handlers = array('$ID!' => 'handleAction');
public function index(SS_HTTPRequest $req) {
$id = $req->param('ID');
// Use theme from the site config
if (($config = SiteConfig::current_site_config()) && $config->Theme) {
SSViewer::set_theme($config->Theme);
}
$themedir = $_SERVER['DOCUMENT_ROOT'] . '/' . SSViewer::get_theme_folder() . '/templates/';
$surfboard = DataObject::get_by_id('DoSurfboard', $id);
if ($surfboard) {
//Return our $Data array to use on the page
$Data = array('DoSurfboard' => $surfboard);
$this->Customise($Data);
return $this->renderWith($themedir . 'ShowSurfboard.ss');
} else {
//Not found
return $this->httpError(404, 'Not found');
}
}
}
模板
themes/theme-name/templates/ShowSurfboard.ss
<% with DoSurfboard %>
<h3>$Name</h3>
<p>$Color</p>
<div class="typography">
<h2>LeftSidebar</h2>
<% loop $WidgetArea(LeftSidebar) %>
$WidgetHolder
<% end_loop %>
</div>
<% end_with %>
待办事项
- 将 $InheritSideBar 移到页面中,以便能够仅继承某些 widget 区域
- 修复问题部分列出的错误,可能需要重新发布每个已发布页面
问题
安装此模块后,您需要重新发布希望使用小部件的现有页面,因为存在未保存的比率列表(UnsavedRationList)。如果您不重新发布页面,您将遇到以下错误:在 framework/model/UnsavedRelationList.php 行 307 处发生错误:未捕获的 LogicException:无法在未保存的关系列表(UnsavedRelationList)上调用 byID。