微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Silverstripe - 重复/可重用分组字段

如何解决Silverstripe - 重复/可重用分组字段

我想实现一个布局,其中一列重复多次,并且可以在 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',TextField::create('Intro_Subheadline2',HTMLEditorField::create('Intro_Text2','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 中。如何从数据对象中输出数据字段?

解决方法

为了使事情可重复,您必须将它们放入不同的对象中,然后将多个这些对象链接到您当前的对象/页面。

  1. 网格域
    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 是一个非常通用的选项,可用于任意数量的可能的数据库关系(链接类别、图像、页面等)

  2. 基本模块
    另一种选择是官方支持的称为 elemental 的模块。这是专门为可重复的内容而构建的。
    https://github.com/silverstripe/silverstripe-elemental

  3. 序列化数据对象模块
    可能不适合您的用例,但我维护了一个提供 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() 是一个自动生成的方法,它返回链接到当前页面的所有 IntroColumn 对象。但是 $this->Intro_Columns() 会返回所有页面的所有 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>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。