dia-nz/sortablefile

为 SilverStripe 4 添加到 UploadField 的排序功能的扩展。

维护者

详细信息

github.com/DIA-NZ/sortablefile

源代码

安装: 95

依赖项: 0

建议者: 0

安全: 0

星级: 0

关注者: 1

分支: 30

类型:silverstripe-vendormodule

2.1.6 2019-11-04 23:04 UTC

This package is auto-updated.

Last update: 2024-09-05 10:04:35 UTC


README

Scrutinizer Code Quality Code Coverage Build Status Latest Stable Version Latest Unstable Version Monthly Downloads

为 SilverStripe 4.1+ 开发的扩展,允许通过 UploadField 上传的文件进行排序。

此模块装饰了现有的 UploadField 并为其添加了排序功能。这主要用于与文件或图像的 many_many 关系一起使用。

screen-capture

安装

此模块仅适用于 SilverStripe 4.1+。

对于与 SilverStripe 3 兼容的版本,请使用 1.x 版本。

最简单的方法是使用 composer

composer require dia-nz/sortablefile ^2.0

之后运行 dev/build

用法

用法很简单。只需使用 SortableUploadField 代替 UploadField 来管理您的 many_many 关系。为了持久化排序顺序,需要向 many_many 关系添加一个额外的字段,该字段包含排序顺序。您可以通过指定 many_many_extraFields 中的排序列来实现(请参见下面的示例)。

默认情况下,SortableUploadField 假设排序列的名称为 SortOrder。如果您想使用其他字段名(例如 Sort),则必须明确设置它。

SortableUploadField::create('Files')->setSortColumn('Sort');

许多许多设置示例

假设我们有一个 PortfolioPage,该页面附带了多个 Images

PortfolioPage 看起来像这样

use SilverStripe\Assets\Image;
use SilverStripe\Forms\FieldList;
use Bummzack\SortableFile\Forms\SortableUploadField;

class PortfolioPage extends Page
{
    // This page can have many images
    private static $many_many = [
        'Images' => Image::class
    ];

    // this adds the SortOrder field to the relation table.
    // Please note that the key (in this case 'Images')
    // has to be the same key as in the $many_many definition!
    private static $many_many_extraFields = [
        'Images' => ['SortOrder' => 'Int']
    ];

    public function getCMSFields()
    {
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
            $fields->addFieldToTab('Root.Main', SortableUploadField::create(
                'Images', $this->fieldLabel('Images')
            ));
        });

        return parent::getCMSFields();
    }
}

一旦按照上述方式设置,那么您应该能够在 CMS 中添加图像并通过拖拽来排序它们(使用左侧的句柄)。

模板

通过关系表对文件进行排序并不容易通过 DataExtension 实现。这就是为什么目前需要用户实现一个将返回排序文件的 getter,大致如下

// Use this in your templates to get the correctly sorted images
public function SortedImages()
{
    return $this->Images()->Sort('SortOrder');
}

然后在您的模板中使用

<% loop $SortedImages %>
  $ScaleWidth(500)
<% end_loop %>

或者,您可以在模板中直接使用排序语句,这将在您的页面类中消除对特殊 getter 方法的需要。

<% loop $Images.Sort('SortOrder') %>
  $ScaleWidth(500)
<% end_loop %>

许多许多通过

此模块还支持编辑许多许多通过列表。使用 many_many through 的优点是,您的关联可以正确地版本化。

设置示例

这是一个使用与上面相同的 PortfolioPage 的示例设置,但现在使用 many_many through。如果这看起来不清楚,请参阅官方文档

首先,PortfolioPage

<?php

use Bummzack\SortableFile\Forms\SortableUploadField;
use SilverStripe\Forms\FieldList;

class PortfolioPage extends Page
{
    private static $many_many = [
        'Images' => [
            'through' => PortfolioImage::class,
            'from' => 'PortfolioPage',
            'to' => 'Image',
        ]
    ];

    // This is required to automatically publish your images
    // whenever you publish your page
    private static $owns = [
        'Images'
    ];

    // This is required to publish deletions as well,
    // as this will not happen by default!
    private static $cascade_deletes = [
        'Images'
    ];

    public function getCMSFields()
    {
        $this->beforeUpdateCMSFields(function (FieldList $fields) {
            $fields->addFieldToTab('Root.Main', SortableUploadField::create(
                'Images', $this->fieldLabel('Images')
            ));
        });

        return parent::getCMSFields();
    }

    // This is a helper method, that is needed to display the items in the
    // correct order. Is required for proper CMS functionality and can be
    // used in templates as $getImages
    public function getImages()
    {
        return $this->Images()->sort('SortOrder');
    }
}

many_many through 关系的思路是,您有一个连接对象的中介 DataObject。因此,我们添加一个名为 PortfolioImage 的 DataObject。

<?php

use SilverStripe\Assets\Image;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;

class PortfolioImage extends DataObject
{
    private static $db = [
        'SortOrder' => 'Int'
    ];

    private static $has_one = [
        'Image' => Image::class,
        'PortfolioPage' => PortfolioPage::class
    ];

    private static $default_sort = 'SortOrder';

    // It's important that you add the Versioned extension to this!
    private static $extensions = [
        Versioned::class
    ];
}

我们还应该向 Image 类添加 belongs_many_many 关系。这通过配置非常容易完成。因此,在您的 mysite/_config/config.yml 中添加

SilverStripe\Assets\Image:
  belongs_many_many:
    PortfolioPages: PortfolioPage.Images

has_many 支持发生了什么变化?

由于如果文件只能添加到单个页面,可能会造成非常糟糕的用户体验,因此已取消对 has_many 关系的 support。想象一下,用户将图像添加到 Page A,然后通过 从文件添加 将相同的图像添加到 Page B。然后,该文件将从 Page A 中删除,没有任何警告或解释,这是很差的 UX。