【问题标题】:Silverstripe - Repeating / Reusable grouped fieldsSilverstripe - 重复/可重复使用的分组字段
【发布时间】:2021-07-27 14:44:09
【问题描述】:

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

【问题讨论】:

    标签: silverstripe


    【解决方案1】:

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

    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() 是一个自动生成的 Method,它返回所有链接到当前页面的 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>
    
    

    【讨论】:

    • 谢谢,我又更新了我的问题。不幸的是,我没有在文档中找到将数据对象输出为 CMS 中的网格字段的方法。
    • 我已经更新了我的答案,在底部添加了有关如何使用网格字段的更多详细信息
    猜你喜欢
    • 2016-03-25
    • 2014-05-31
    • 1970-01-01
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多