Silverstripe - 重复/可重复使用的分组字段
Silverstripe - Repeating / Reusable grouped fields
我想实现一个布局,其中一列重复多次,并且可以在 CMS 中指定为动态内容。但是,我找不到适合这个的对象类型。
我是否必须为每一列单独指定输入字段?
private static $db = [
'Intro_Headline' => 'Varchar',
'Intro_Subheadline' => 'Varchar',
'Intro_Text' => 'HTMLText',
'Intro_Headline2' => 'Varchar',
'Intro_Subheadline2' => 'Varchar',
'Intro_Text2' => 'HTMLText',
...
];
--
$fields = parent::getCMSFields();
//Intro Field 1
$fields->addFieldToTab('Root.Intro', TextField::create('Intro_Headline', 'Headline'), 'Content');
$fields->addFieldtoTab('Root.Intro', TextField::create('Intro_Subheadline', 'Subheadline'), 'Content');
$fields->addFieldToTab('Root.Intro', HTMLEditorField::create('Intro_Text', 'Text'), 'Content');
//Intro Field 2
$fields->addFieldToTab('Root.Intro', TextField::create('Intro_Headline2', 'Headline'), 'Content');
$fields->addFieldtoTab('Root.Intro', TextField::create('Intro_Subheadline2', 'Subheadline'), 'Content');
$fields->addFieldToTab('Root.Intro', HTMLEditorField::create('Intro_Text2', 'Text'), 'Content');
...
或者谁能告诉我找不到哪个字段类型?
更新:
现在,除了我的页面模型中的 $db 变量之外,我还有一个 $has_many 变量:
private static $has_many = [
'Intro_Columns' => IntroColumn::class,
];
在 getCMSFields() 函数中,我这样添加它们:
$fields->addFieldToTab('Root.Columns', GridField::create('Intro_Columns', 'Columns', IntroColumn::get()), 'Content');
我的数据对象如下所示:
class IntroColumn extends DataObject
{
private static $db = [
'img_url' => 'Text',
'headline' => 'Varchar',
'subheadline' => 'Varchar',
'text' => 'Text',
'link' => 'Text'
];
}
但是这些字段还没有显示在 CMS 中。如何从数据对象输出数据字段?
对于可重复的事物,您必须将它们放入不同的对象中,然后 link 这些对象的倍数到您当前的 object/page。
网格字段
在 SilverStripe 4 中执行此操作的默认方法是使用内置的数据库关系($has_many
或 $many_many
而不是 $db) and
GridField` 作为表单字段。
我建议您完成本教程:https://docs.silverstripe.org/en/4/developer_guides/model/relations/
特别是关于 $has_many
的部分将适用于您的用例。 (例如 1 个团队有多个玩家或 1 个公司有多个人)
$has_many
/$many_many
是一个非常通用的选项,可用于任意数量的可能数据库关系(linking 类别、图像、页面...)
基本模块
另一种选择是官方支持的名为 elemental 的模块。这是专门为可重复的内容而构建的。
https://github.com/silverstripe/silverstripe-elemental
序列化数据对象模块
可能不适合您的用例,但我维护了一个提供 GridField 替代方案的模块,但它更适合小型表单字段。 HTMLEditor 太大,无法在此模块中使用。
https://github.com/Zauberfisch/silverstripe-serialized-dataobject
PS:无论你走哪条路,我都强烈建议你从(1.)开始学习教程。这是 SilverStripe 的一项非常重要的基本功能。
编辑:对您更新后的问题的回应:
如果您正在使用 GridField,我会推荐以下内容:
class Page extends SiteTree {
private static $has_many = [
'Intro_Columns' => IntroColumn::class,
];
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Columns', new GridField(
'Intro_Columns',
'My Columns',
$this->Intro_Columns(),
new GridFieldConfig_RecordEditor()
), 'Content');
return $fields;
}
}
class IntroColumn extends DataObject {
private static $db = [
'headline' => 'Varchar',
'subheadline' => 'Varchar',
'text' => 'Text',
'link' => 'Text'
];
private static $has_one = [
'Image' => 'Image',
]
public function getCMSFields() {
$fields = new FieldList();
$fields->push(new TextField('headline', 'My Headline'));
$fields->push(new TextField('subheadline', 'My Subheadline'));
// ... and so on
$fields->push(new UploadField('Image', 'Upload an image'));
return $fields;
}
}
请注意,我使用 $this->Intro_Columns()
作为 GridField 的值而不是 IntroColumn::get()
。因为 $this->Intro_Columns()
是一个自动生成的方法,return 将所有 IntroColumn 对象 link 编辑到当前页面。但是 $this->Intro_Columns()
会 return 来自所有页面的所有 IntroColumns
在模板中,您还调用了这个自动生成的方法:
<!-- Page.ss -->
<h1>Page Title: $Title</h1>
<div class="intro-columns">
<% loop $Intro_Columns %>
<div class="intro-column">
<!-- here we are scoped into a single IntroColumn, so you can use all DB fields and methods of that object -->
<h2>$headline <br> $subheadline</h2>
$Image.URL <br>
...
</div>
<% end_loop %>
</div>
我想实现一个布局,其中一列重复多次,并且可以在 CMS 中指定为动态内容。但是,我找不到适合这个的对象类型。 我是否必须为每一列单独指定输入字段?
private static $db = [
'Intro_Headline' => 'Varchar',
'Intro_Subheadline' => 'Varchar',
'Intro_Text' => 'HTMLText',
'Intro_Headline2' => 'Varchar',
'Intro_Subheadline2' => 'Varchar',
'Intro_Text2' => 'HTMLText',
...
];
--
$fields = parent::getCMSFields();
//Intro Field 1
$fields->addFieldToTab('Root.Intro', TextField::create('Intro_Headline', 'Headline'), 'Content');
$fields->addFieldtoTab('Root.Intro', TextField::create('Intro_Subheadline', 'Subheadline'), 'Content');
$fields->addFieldToTab('Root.Intro', HTMLEditorField::create('Intro_Text', 'Text'), 'Content');
//Intro Field 2
$fields->addFieldToTab('Root.Intro', TextField::create('Intro_Headline2', 'Headline'), 'Content');
$fields->addFieldtoTab('Root.Intro', TextField::create('Intro_Subheadline2', 'Subheadline'), 'Content');
$fields->addFieldToTab('Root.Intro', HTMLEditorField::create('Intro_Text2', 'Text'), 'Content');
...
或者谁能告诉我找不到哪个字段类型?
更新: 现在,除了我的页面模型中的 $db 变量之外,我还有一个 $has_many 变量:
private static $has_many = [
'Intro_Columns' => IntroColumn::class,
];
在 getCMSFields() 函数中,我这样添加它们:
$fields->addFieldToTab('Root.Columns', GridField::create('Intro_Columns', 'Columns', IntroColumn::get()), 'Content');
我的数据对象如下所示:
class IntroColumn extends DataObject
{
private static $db = [
'img_url' => 'Text',
'headline' => 'Varchar',
'subheadline' => 'Varchar',
'text' => 'Text',
'link' => 'Text'
];
}
但是这些字段还没有显示在 CMS 中。如何从数据对象输出数据字段?
对于可重复的事物,您必须将它们放入不同的对象中,然后 link 这些对象的倍数到您当前的 object/page。
网格字段
在 SilverStripe 4 中执行此操作的默认方法是使用内置的数据库关系($has_many
或$many_many
而不是$db) and
GridField` 作为表单字段。我建议您完成本教程:https://docs.silverstripe.org/en/4/developer_guides/model/relations/
特别是关于$has_many
的部分将适用于您的用例。 (例如 1 个团队有多个玩家或 1 个公司有多个人)$has_many
/$many_many
是一个非常通用的选项,可用于任意数量的可能数据库关系(linking 类别、图像、页面...)基本模块
另一种选择是官方支持的名为 elemental 的模块。这是专门为可重复的内容而构建的。
https://github.com/silverstripe/silverstripe-elemental序列化数据对象模块
可能不适合您的用例,但我维护了一个提供 GridField 替代方案的模块,但它更适合小型表单字段。 HTMLEditor 太大,无法在此模块中使用。
https://github.com/Zauberfisch/silverstripe-serialized-dataobject
PS:无论你走哪条路,我都强烈建议你从(1.)开始学习教程。这是 SilverStripe 的一项非常重要的基本功能。
编辑:对您更新后的问题的回应:
如果您正在使用 GridField,我会推荐以下内容:
class Page extends SiteTree {
private static $has_many = [
'Intro_Columns' => IntroColumn::class,
];
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Columns', new GridField(
'Intro_Columns',
'My Columns',
$this->Intro_Columns(),
new GridFieldConfig_RecordEditor()
), 'Content');
return $fields;
}
}
class IntroColumn extends DataObject {
private static $db = [
'headline' => 'Varchar',
'subheadline' => 'Varchar',
'text' => 'Text',
'link' => 'Text'
];
private static $has_one = [
'Image' => 'Image',
]
public function getCMSFields() {
$fields = new FieldList();
$fields->push(new TextField('headline', 'My Headline'));
$fields->push(new TextField('subheadline', 'My Subheadline'));
// ... and so on
$fields->push(new UploadField('Image', 'Upload an image'));
return $fields;
}
}
请注意,我使用 $this->Intro_Columns()
作为 GridField 的值而不是 IntroColumn::get()
。因为 $this->Intro_Columns()
是一个自动生成的方法,return 将所有 IntroColumn 对象 link 编辑到当前页面。但是 $this->Intro_Columns()
会 return 来自所有页面的所有 IntroColumns
在模板中,您还调用了这个自动生成的方法:
<!-- Page.ss -->
<h1>Page Title: $Title</h1>
<div class="intro-columns">
<% loop $Intro_Columns %>
<div class="intro-column">
<!-- here we are scoped into a single IntroColumn, so you can use all DB fields and methods of that object -->
<h2>$headline <br> $subheadline</h2>
$Image.URL <br>
...
</div>
<% end_loop %>
</div>