richardsjoqvist / silverstripe-blocks
Blocks是一个通用类,可以用来构建小型内容块,这些块可以与全局或特定页面关联。
Requires
- php: >=5.3.2
- composer/installers: *
- silverstripe/framework: 3.1.*
README
Blocks是一个通用类,可以用来构建小型内容块,这些块可以与全局或特定页面关联。
要求
- SilverStripe 3.1
安装
将模块放入您的SilverStripe项目中,并运行/dev/build
升级
如果您是从Blocks的早期版本升级,您需要在代码中进行一些调整。Blocks现在使用标准的private static $db而不是protected $_datafields
// Example before:
protected $_datafields = array(
'FeedURL' => 'TextField',
'Results' => 'NumericField',
'SummaryMaxLength' => 'NumericField',
'CacheTime' => 'NumericField',
'Striptags' => 'CheckboxField',
'Modifier' => 'DropdownField',
);
// Example after:
private static $db = array(
'FeedURL' => 'Text',
'Results' => 'Int',
'SummaryMaxLength' => 'Int',
'CacheTime' => 'Int',
'Striptags' => 'Int',
'Modifier' => 'Text',
);
您还必须在getCMSFields()中添加字段到您的模型。
function getCMSFields() {
// Before:
foreach($this->_datafields as $fieldname => $fieldclass) {
if($fieldname != 'Modifier') { // Add field by hand later
$fields->push(new $fieldclass($fieldname, Block::getDataFieldLabel(__CLASS__, $fieldname)));
}
}
// After:
$fields->push(new TextField('FeedURL', 'FeedURL'));
$fields->push(new NumericField('Results', 'Results'));
$fields->push(new NumericField('SummaryMaxLength', 'SummaryMaxLength'));
$fields->push(new NumericField('CacheTime', 'CacheTime'));
$fields->push(new CheckboxField('Striptags', 'Striptags'));
}
Blocks的这次发布与旧方法向后兼容,如果常规$db字段中没有数据,它仍然会从Block->Data读取数据。一旦在Blocks的新版本中保存了一个块,数据将从$db字段中读取。
最后,您需要升级后运行/dev/build(当然,如果在必要时更新了代码,也必须这样做)。
可选依赖
如果您的项目中可用,以下插件会被使用
使用
实现
Blocks需要被扩展以正常工作。在/mysite/code中创建一个php文件,例如命名为ContentBlock.php。将以下代码添加到文件中
class ContentBlock extends Block
{
}
接下来,您需要为新创建的类设置一个关系,例如在Page.php中
private static $has_many = array(
'ContentBlocks' => 'ContentBlock',
);
运行/dev/build以注册新类和关系。最后,在getcmsfields()中为ContentBlock类添加一个管理器(预定义的GridField)
class Page extends SiteTree
{
function getCMSFields()
{
$fields = parent::getCMSFields();
// Tab Manager Source Class Title DataList
// | | | | |
$fields->addFieldToTab('Root.ContentBlocks', new Block_Manager('ContentBlock', 'Content Blocks', $this->ContentBlocks()) );
return $fields;
}
}
重复上述步骤创建另一个类,例如BannerBlock来创建另一种类型的块。一个站点可以有多少种类型的块没有限制。
自定义扩展块
扩展块可以像任何其他类型的DataObject扩展类一样进行自定义,例如
class ContentBlock extends Block
{
private static $db = array(
'SomeText' => 'Text',
'AnInt' => 'Int',
);
function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->push(new TextField('SomeText', 'Some text'));
$fields->push(new CheckboxField('AnInt', 'Check me out'));
$fields->removeByName('Content');
return $fields;
}
}
模板
可以使用循环在模板中显示与页面关联的块
<% loop ContentBlocks %>
$Title
$LeadIn
$Content
$Image.SetWidth(150)
<% if HasLink %>
<a href="$LinkURL" <% if LinkIsExternal %>class="external"<% end_if%>>$LinkTitle</a>
<% end_if %>
<% end_loop %>
继承
您可能想要创建全局块或从其他页面继承块。在这种情况下,您可以在Page_Controller类中创建一个函数,以对返回循环的内容块有更细粒度的控制
class Page_Controller extends ContentController
{
function ContentBlocks($limit=0)
{
// Get blocks for current page
$blocks = ContentBlock::get()
->filter(array('PageID' => $this->dataRecord->ID))
->sort('SortOrder', 'ASC')
->limit((int)$limit);
if($blocks->Count()) return $blocks;
// No blocks exists for current page, inherit from home page
if(class_exists('HomePage')) {
if(class_exists('Translatable')) {
$HomePage = Translatable::get_one_by_locale('HomePage', Translatable::get_current_locale());
} else {
$HomePage = DataObject::get_one('HomePage');
}
if($HomePage) {
$blocks = ContentBlock::get()
->filter(array('PageID' => $HomePage->ID))
->sort('SortOrder', 'ASC')
->limit((int)$limit);
if($blocks->Count()) return $blocks;
}
}
return null;
}
}
此函数返回当前页面的内容块,但如果当前页面没有内容块,它将转到主页并返回该主页上的任何内容块。
包含的预定义模型
该模块包含了一些模型,可以直接使用(或扩展)以特定目的
- ContactBlock - 用于向页面添加联系人
- FeedBlock - 用于向页面添加rss源
- LinkBlock - 向页面添加链接集合
ContactBlock
此模型可用于向页面添加联系人。要使用它,您需要在Page.php中定义一个关系
private static $has_many = array(
'Contacts' => 'ContactBlock',
);
运行/dev/build以注册关系,然后在getcmsfields()中为ContactBlock类添加管理器
class Page extends SiteTree
{
function getCMSFields()
{
$fields = parent::getCMSFields();
// Tab Manager Source Class Title DataList
// | | | | |
$fields->addFieldToTab('Root.Contacts', new Block_Manager('ContactBlock', 'Contacts', $this->Contacts()) );
return $fields;
}
}
可以将联系人添加到模板输出,就像添加其他任何块一样(见模板)。可以单独打印的额外字段包括
- 标题:联系人的名字
- 角色:角色(职位)
- 电子邮件:电子邮件地址
- 电话:电话号码
- 手机:手机号码
- 街道:地址
- 邮编:邮编
- 城市:城市
- 箱:邮政信箱
- 图片:联系人的照片
FeedBlock
该模型可以用于向页面添加RSS源。要使用它,您需要在Page.php中定义一个关系
private static $has_many = array(
'RssFeeds' => 'FeedBlock',
);
运行/dev/build以注册关系,然后在不得到CmsFields()中添加FeedBlock类的管理器
class Page extends SiteTree
{
function getCMSFields()
{
$fields = parent::getCMSFields();
// Tab Manager Source Class Title DataList
// | | | | |
$fields->addFieldToTab('Root.RssFeeds', new FeedBlock_Manager('FeedBlock', 'Blog Feeds', $this->RssFeeds()) );
return $fields;
}
}
可以将源添加到模板输出,就像添加其他任何块一样(见FeedBlock模板)。可以单独打印的额外字段包括
- FeedURL:源URL
- URL:链接URL(针对块,而不是每个项目)
- IsExternal:如果块链接是外部的,则为true
- IsInternal:如果块链接是内部的,则为true
- 图片:图片
- 条目:源中的条目
此外,源中的每个条目都有以下字段,可以单独打印
- 标题:标题
- 摘要:缩短的描述(100个字符)
- 描述:描述(文本)
- 日期:日期(SS_DateTime对象)
- 链接:原始条目的链接
FeedBlock模板
由于源块有另一个维度,即每个源包含多个条目,因此模板需要嵌套循环才能显示条目以及源
<% loop RssFeeds %>
<!-- Check if feed has any items -->
<% if Items %>
<div class="feed">
$Image.SetWidth(50)
<% if URL %>
<a href="$URL" <% if IsExternal %>class="external"<% end_if%>>$Title</a>
<% else %>
<strong>$Title</strong>
<% end_if %>
<br/>
<span class="discrete">Feed Source: <a href="$FeedURL" class="external">$FeedURL</a></span><br/>
<!-- Iterate over each item in feed -->
<% loop Items %>
<a href="$Link" class="external">$Title</a><br/>
<span class="date">$Date.Format(Y-m-d H:i:s)</span><br/>
$Description<br/>
<br/>
<% end_loop %>
</div>
<% end_if %>
<% end_loop %>
全局源
在某些情况下,您可能希望为整个站点创建全局源。例如,您可能希望在主页上定义源,并让其他页面继承这些源。在这种情况下,您可以在Page_Controller类中创建一个函数来控制哪些源返回到循环
class Page_Controller extends ContentController
{
function RssFeeds($limit=0)
{
// Get all items from custom RssFeed class which extends FeedBlock:
if(class_exists('HomePage')) {
if(class_exists('Translatable')) {
$HomePage = Translatable::get_one_by_locale('HomePage', Translatable::get_current_locale());
} else {
$HomePage = DataObject::get_one('HomePage');
}
if($HomePage) {
$blocks = ContentBlock::get()
->filter(array('PageID' => $HomePage->ID))
->sort('SortOrder', 'ASC')
->limit((int)$limit);
if($blocks->Count()) return $blocks;
}
}
return null;
}
}
此函数从名为RssFeed的类中获取所有条目,该类扩展了FeedBlock。
修改源条目
FeedBlock允许您创建修改函数,在将条目显示在页面上之前运行。要指定哪些方法可以作为修饰符可用,您需要扩展FeedBlock并创建所需的函数。
示例:RssFeed.php(将其放置在Page.php相同的目录中,注册关系并运行/dev/build)
class RssFeed extends FeedBlock
{
/**
* Define which functions are available as modifiers
*/
protected $modifier_functions = array(
'MyFunction',
'MyOtherFunction',
);
/**
* Modify feed results
* @param DataObject $entry
*/
function MyFunction($entry)
{
// Remove images from entry
$entry->description = preg_replace("/(<img )([^>]*)(>)/isU", '', $entry->description);
}
/**
* Modify feed results
* @param DataObject $entry
*/
function MyOtherFunction($entry)
{
// Remove links from entry
$entry->description = preg_replace("/(<a )([^>]*)(>)/isU", '', $entry->description);
$entry->description = str_replace('</a>', '', $entry->description);
}
}
在管理器中编辑RssFeed项时,可以为该源中的条目选择一个指定的修饰符函数。然后,每个项目都通过选定的修改函数传递,然后再在页面上显示。
LinkBlock
此模型可以用于向页面添加一组链接。要使用它,您需要在Page.php中定义一个关系
private static $has_many = array(
'Links' => 'LinkBlock',
);
运行/dev/build以注册关系,然后在不得到CmsFields()中添加LinkBlock类的管理器
class Page extends SiteTree
{
function getCMSFields()
{
$fields = parent::getCMSFields();
// Tab Manager Source Class Title DataList items
// | | | | |
$fields->addFieldToTab('Root.Links', new Block_Manager('LinkBlock', 'Links', $this->Links()) );
return $fields;
}
}
可以将链接添加到模板输出,就像添加其他任何块一样(见模板)。可以单独打印的额外字段包括
- 标题:链接标题
- URL:链接URL
- IsExternal:如果链接是外部的,则为true
- IsInternal:如果链接是内部的,则为true
- 属性:添加到a标签的自定义属性
- CssClasses:添加到<a>-标签的类名
- 图片:图片

