bummzack / sortablefile
为 SilverStripe 添加对 UploadField 排序功能的扩展。
Requires
- silverstripe/asset-admin: ^1.1 || ^2
- silverstripe/framework: ^4.1 || ^5
Requires (Dev)
- phpunit/phpunit: ^5.7
README
为 SilverStripe 4.1+ 提供的扩展,允许通过 UploadField
排序附加的文件。
此模块装饰现有的 UploadField
并为其添加排序功能。这主要用于与文件或图像的 many_many
关系一起使用。
安装
此模块仅适用于 SilverStripe 4.1+。
对于与 SilverStripe 3 兼容的版本,请使用 1.x
版本。
最简单的方法是使用 composer
composer require bummzack/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 实现。这就是为什么目前需要用户实现一个获取器,该获取器将返回排序后的文件,类似于以下内容
// Use this in your templates to get the correctly sorted images public function Images() { return $this->getManyManyComponents('Images')->sort('SortOrder'); } // and/or public function SortedImages() { return $this->Images()->Sort('SortOrder'); }
然后,在您的模板中使用
<% loop $SortedImages %>
$ScaleWidth(500)
<% end_loop %>
或者,您可以直接在模板中使用排序语句,这将消除在页面类中需要特殊获取器方法的需求。
<% 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
关系的支持。想象一下,用户将图像添加到 Page A
,然后通过 从文件添加 将相同的图像添加到 Page B
。文件将被从 Page A
中删除,没有任何警告或解释,这是糟糕的用户体验。