Silverstripe 中灵活的内容模块

Flexible content modules in Silverstripe

我们正在考虑使用 Silverstripe CMS,并希望能够拥有可以重新排序的模块。

我们来自 Wordpress 设置,主要使用灵活的内容 ACF 字段。模块(例如文本、标头或视频)需要能够 re-ordered。

我们将 CMS 用作 API,因此这些模块作为页面的一部分输出或 post:

[
  {
    "id": 10,
    "title": "Post title",
    "slug": "post_slug",
    "path": "/post_slug",
    "template": "campaign",
    "published": "2017-05-25 06:09:36",
    "image": null,
    "seo": {
      "title": "",
      "description": "",
      "image": {
      },
    },
    "sections": [
      {
        "type": "masthead",
        "Title": "",
        "video": false,
        "image": [

        ],
        "showCta": false,
        "cta": [

        ]
      },
      {
        "type": "video_text",
        "video_text": [
          {
            "type": "video",
            "video_url": "https://www.youtube.com/watch?v=asdfa",
            "video_length": "07:38",
            "video_preview": false
          },
          {
            "type": "text",
            "title": "Video Title",
            "content": "Video text content",
            "call_to_action": false,
            "cta": [

            ]
          }
        ]
      },
      {
        "type": "text",
        "title": "Text Title",
        "content": "",
        "alignment": "centre",
        "call_to_action": false,
        "cta": {
          "text": "CTA button",
          "link_type": "internal_link",
          "internal_link": "about",
          "external_link": "",
          "section_id": [

          ]
        }
      },
    ]
  }
]

Silverstripe 是否有自己的模块处理方式/我是否需要放弃这种灵活的内容模块方法?其他人如何处理 Silverstripe 中的灵活内容模块?

silverstripe-blocks 和 silverstripe-elemental 在他们自己的方面都很好,但我认为他们不会达到你想要的。这些模块并没有真正赋予您使用预定义模板的能力。您可以挂接模板,但代码会很庞大。我不确定是否有一个开源模块。

从您的 JSON 代码中,为了让这些部分呈现如下所示的内容;

<section id="Sections">

    <div id="video_text" class="section">
       <iframe width="560" height="315" src="https://www.youtube.com/watch?v=asdfa" frameborder="0" allowfullscreen></iframe>
    </section>

    <div id="text" class="section">
       <h2>Text Title</h2>
       <a class='text-center btn btn-default' href="/about/">CTA button</a>
    </section>

</sections>

您可能想要这样做。 为您的部分使用 DataObjects (DO),便于重新排序。 创建一个抽象的 DO,BlockSection,其中包含 Title(Varchar)、Content(HTMLText)、Sort(Int) 等字段,最重要的是 has_one 到 Page。

对于视频使用可以命名为 DO VideoBlockSection 并且它扩展了 BlockSection, 另一个的 TextBlockSection。不要忘记每个 DO 的 $singular_name(对于网格中漂亮的 class 命名很有用)

在页面 getCMSFields 上添加网格以管理部分。您需要添加 GridFieldSortableRows 和 GridFieldAddNewMultiClass,现在您可以在每个页面上添加您的部分。

将 has_many 从页面添加到 BlockSection 以及一种将呈现块并输出 html 的方法。

Page.php

private static $has_many = array(
    "Sections" => "BlockSection",
);

function SectionContent()
$aContent = ArrayList::create();
$oSections = $this->Sections();
if (count($oSections )) {
   foreach ( $oSections as $oSection ) {
       $aContent->push(ArrayData::create([                 
            "Section"     => $oSection,
            "Content"   => $oSection->renderWith([$oSection->ClassName, get_parent_class($oSection)]),
        ]));
    }
 }
return $aContent;

对于 VideoBlockSection,模板数组列表将为 VideoBlockSection 和 BlockSection

VideoBlockSection.ss

<div id="video_text_{$ID}" class="section">
   <iframe width="560" height="315" src="{$URL}" frameborder="0" allowfullscreen></iframe>
</section>

在您的特定情况下,因为您使用的是 API,所以您需要使用包装器来呈现模板。 它需要将 [section][type] 匹配到模板 (renderWith) video_text 到 VideoBlockSection

最后在 Page.ss

<% loop $SectionContent %>
    {$Content}
<% end_loop %>

这是一个概念验证,但它对我有用,因此没有考虑重构、速度和内存使用(但它有效)。 这样我就不得不放弃不必要的所谓 "page types",我发现在大多数情况下它是不可重复使用的。

这对我来说 100% 有效,我将它与 Bootstrap 一起使用 3. 我用它来创建 CTA、视差滚动、Google 地图部分(一页上有多个地图)、缩略图.指定图像调整大小的方法(Cropped、ByWidth、ByHeight)。

不要放弃灵活的内容模块方法。 我正在开发一个与 SS4 和 Bootstrap 4 一起使用的开源模块(有可能使用任何其他 html 框架)