-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SPIKE Review Fluent support for LinkFIeld #210
Comments
Summary:Fluent seems to work fine for has_one LinkField's, however it is rough for has_many MutliLinkField's Shortcomings:Things work fairly well for the has_one LinkField, but seem to fall apart pretty badly for the has_many MutliLinkField. I'm not sure if that's because fluent seems to have not so great support for has_many (and many_many) relations, or if I just don't know how to properly use fluent The only real shortcoming with the has_one was there's a 'Localisation' tab with a gridfield that's supposed to render, though because we're using a react modal there is no react gridfield that can be rendered. I need to add this to GridField.php to prevent a fatal exception: // GridField.php
// ...
protected $schemaDataType = self::SCHEMA_DATA_TYPE_STRUCTURAL; And it simply renders as nothing: Possibly we could just manually remove the tab since its' non-functional Otherwise things seemed to work as expected, based on my limited knowledge of fluent. Has many was a different story unfortunately. Fluent docs indicate that you should use Locale based filter configuration for has_many and many_many, which means add the I noticed the following issues:
Setup:
Add fluent support to the Link DataObject
Fix required in silverstripe/framework so that we can submit the modal without getting a console warning. This gridfield will not render in a modal // silverstripe/framework GridField.php
// ...
protected $schemaDataType = self::SCHEMA_DATA_TYPE_STRUCTURAL; // app/src/Page.php
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\LinkField\Form\LinkField;
use SilverStripe\LinkField\Form\MultiLinkField;
use SilverStripe\LinkField\Models\Link;
class Page extends SiteTree
{
private static $db = [];
private static $has_one = [
'MyLink' => Link::class,
];
private static $has_many = [
'MyLinks' => Link::class,
];
private static $owns = [
'MyLink',
'MyLinks',
];
private static $cascade_deletes = [
'MyLink',
'MyLinks',
];
private static $cascade_duplicates = [
'MyLink',
'MyLinks',
];
private static $translate = [
'MyLinkID',
// this does nothing:
'MyLinks',
];
public function getCMSFields()
{
// Fluent recommended way to add fields - this is so that we get the 'Translatable field' purple icons
// https://github.com/tractorcow-farm/silverstripe-fluent/blob/master/docs/en/dataobjects.md#default-field-scaffolder)
$this->beforeUpdateCMSFields(function($fields) {
$fields->addFieldsToTab(
'Root.Main',
[
LinkField::create('MyLink'),
MultiLinkField::create('MyLinks')
]
);
});
// need to ensure 'updateCMSFields` hook is called according to fluent docs
$fields = parent::getCMSFields();
return $fields;
}
} // app/src/MyBlock.php
use DNADesign\Elemental\Models\BaseElement;
use SilverStripe\LinkField\Models\Link;
use SilverStripe\LinkField\Form\LinkField;
use SilverStripe\LinkField\Form\MultiLinkField;
use TractorCow\Fluent\Extension\FluentVersionedExtension;
use TractorCow\Fluent\Extension\FluentFilteredExtension;
class MyBlock extends BaseElement
{
private static $has_one = [
'MyLink' => Link::class,
];
private static $has_many = [
'MyLinks' => Link::class,
];
private static $owns = [
'MyLink',
'MyLinks',
];
private static $cascade_deletes = [
'MyLink',
'MyLinks',
];
private static $cascade_duplicates = [
'MyLink',
'MyLinks',
];
private static $table_name = 'MyBlock';
private static $singular_name = 'My Block';
private static $plural_name = 'My Blocks';
private static $description = 'This is my block';
private static $icon = 'font-icon-block-content';
public function getType()
{
return 'My Block';
}
public function getCMSFields()
{
$this->beforeUpdateCMSFields(function($fields) {
$fields->addFieldsToTab(
'Root.Main',
[
LinkField::create('MyLink'),
MultiLinkField::create('MyLinks')
]
);
});
$fields = parent::getCMSFields();
$fields->removeByName('MyLinkID');
return $fields;
}
} |
I wonder if this is related to the multi-relational The other has_many issues might be related to that - or at least probably all share some root cause whatever that cause is. |
From reading the comments so far, I don't know that we would be able to scope a card to provide Fluent support or prowide good guidance on how to enable. Do we feel that spending more time analysing this would allow us to reach more solid conclusions? Or this just a case of us needing to knock our collective head against the wall until we find solution? Might be worth getting some terraformers eyes on this. |
Hey @maxime-rainville @emteknetnz , thanks for the write-up 😄 , looks like you had quite a journey with Fluent. Here are some of my thoughts on this: Fluent customised CMS UI with React componentsFluent customisation generally doesn't work with React components as it heavily relies on GridField which does not work in React components. We have similar issue with Fluent CMS UI on the asset admin. I'm not sure what's the best solution for this one but it seems we should aim for some common extensibility interface in React components as the GridField used to provide as things like localisation badges and button label customisations are likely to be very similar between different areas of the CMS (asset admin, linkfield...). Has-many many-many fluent support & sortingCompletely agree that Fluent support of these features is very limited. I did try to set this up in a few different ways but I couldn't achieve good results. I think it is possible to set up something functional with the combination of localised many many through models and
This extension will prevent any content from showing on the frontend when it's applied so we expect content authors to maintain an allow list of locales where the content is allowed to be shown for this particular model instance (this is currently achieved via GridField which is probably not showing up in the LinkField). This is technically functional but the moment you have to maintain more than 10 model instances it gets super tedious and unsustainable. This is the reason why I usually recommend the holder approach for localisation (for example Elemental area for blocks) as it's much easier to set up and maintain. Overall, sorting capability requires sort data consistency within each locale. If links are individually localised they can have individual data states which breaks the consistency (for example I can see cases for localised links using has one as those would not need sorting capability though. |
Given the feedback provided here, I think we'll put "full blown Fluent support" in the too hard basket for now. We'll still have a card to "document simple linkfield-fluent scenarios" but there's an expectation that it won't work for the more complex configurations. I've created a follow up card to address the underlying problems: |
#237 is the follow up card. |
We're not sure the LinkField's new implementation will work well with Fluent. The feedback we got from our bespoke devs that use LinkField v3 with Fluent was that in most cases the Link was attached to some parent object that was being translated. In practice, this meant that different language blocks would have different links for each language.
e.g.: Your create an elemental block with a link. The English block has a link pointing to an English website and the French Block has completely different link pointing to a French website.
Yet the scenario where the Link itself was the thing being translated was judged as desirable and would be considered a substantial shortcoming if it wasn't possible.
e.g. You create a Link pointing to a page. The English and French Link are joint together. User can choose to provide a different title for each Language.
Timebox
1 day
TODO
Outcome
At the end of this SPIKE, we should:
The text was updated successfully, but these errors were encountered: