Extension for File class: updateCMSFields not working

<%- if @topic_view.topic.tags.present? %>
<%= t 'js.tagging.tags' %>: <%- @topic_view.topic.tags.each do |t| %> <%= t %> <%- end %>
<% end %>

Silverstripe Version: 4.1

Question:

I’m trying to add an extension to the File class as follows:

class FileExtension extends DataExtension
{
    private static $db = array(
        'Copyright' => 'Varchar(255)'
    );

    public function updateCMSFields(FieldList $fields) {
        $fields->insertAfter(
            'Title',
            TextField::create('Copyright', 'Copyright')
        );
    }
}

registered the extension in mysite.yml:

Silverstripe\Assets\File:
  extensions:
    - FileExtension

Upon running /dev/build, the ‘Copyright’ field is created as expected, but when opening a file in the CMS, the corresponding TextField isn’t rendered.
In fact, my updateCMSFields method doesn’t even get called (tried putting a ‘die()’ statement in there).

Something i missed?

Hi @schellmax I encountered this issue too (see this comment). The new assets admin doesn’t call getCMSFields() as you pointed out, instead a factory is used to build the editing form. It’s counter-intuitive and I’m not sure why it was done that way… but there is probably a good reason? :slight_smile:

Anyway, you can hook in to SilverStripe\AssetAdmin\Forms\AssetFormFactory::getFormFields with the updateFormFields() extension hook to add a field to the file editing form.

1 Like

Interesting. Does this mean we now require 2 extensions to do this? 1 to add the db field and 1 to modify the cms fields?

using a second extension seems to be the only way then.
this is what i came up with, inspired by the silverstripe-focuspoint module code @JonoM mentioned:

class ImageFormFactoryExtension extends Extension
{
    public function updateFormFields(FieldList $fields)
    {
        $fields->insertAfter(
            'Title',
            TextField::create('Copyright', 'Copyright')
        );
    }
}

so there is not only AssetFormFactory but also ImageFormFactory, which i used, as i need this for images only.

3 Likes

I tried this and it works. Couldn’t find a full working example so I did what @schellmax did and looked at the code for the silverstripe-focuspoint module. 2 new files and an edit to my main yml file.

Image extension ImageExtension.php :

<?php
 namespace MyCoolProject;
 use SilverStripe\ORM\DataExtension;
 class ImageExtension extends DataExtension {
  private static $db = ["caption" => "Text"];
 }

Form Factory extension ImageFormFactoryExtension.php :

<?php 
 namespace MyCoolProject;
 use SilverStripe\Core\Extension;
 use SilverStripe\Forms\FieldList;
 use SilverStripe\Forms\TextareaField;
 class ImageFormFactoryExtension extends Extension {
  public function updateFormFields(FieldList $fields) {
   $fields->insertAfter(
    "Name",
    TextareaField::create("caption", "Image caption")->setRows(3)
   );
  }
}

YML file :

SilverStripe\Assets\Image:
  extensions:
    - MyCoolProject\ImageExtension
SilverStripe\AssetAdmin\Forms\ImageFormFactory:
  extensions:
    - MyCoolProject\ImageFormFactoryExtension
SilverStripe\Assets\Storage\DBFile:
  extensions:
    - MyCoolProject\ImageExtension

I hope this helps someone out there :slight_smile: