Open maxime-rainville opened 1 month ago
getVersionedState()
(fluent updates this to correctly indicate if the item is archived for the current locale)
canArchive()
in FluentVersionedExtension
to return false if isArchivedInLocale()
returns true? Not sure what flow-on that might have as it might result in errors now being thrown where before actions would just result in nothing happening.LiteralField
in the edit formgetCMSActions()
into the formschema form
...
menu if there are multiple actions, and expose these as available actions when viewing links in a list (similar to the elemental block ...
actions menu)Hey @GuySartorelli thanks for documenting the options we have in tackling this challenge. I really like the idea of focusing on low hanging fruit first before committing too much effort into this.
From all the available options for CMS 5 I like the LiteralField
option the best. This is based on the feedback from the client on our project as we actually ended up building something similar for asset admin (similar problem - React UI, no GridFields).
The main reason why this solution was picked is that it gives content authors to overview across all locales. Model deletion was specifically an issue as content authors were reporting that it doesn't work. This is due to the delete / archive button not communicating the information that there is no content to delete in this locale.
We found this solution also to be least invasive as we're mostly just adding new enhancements in instead of replacing existing behaviour.
Here are some details about our solution.
class LocalisedBadges extends DataExtension
{
public function updateCMSFields(FieldList $fields): void
{
/** @var SiteTree $owner */
$owner = $this->getOwner();
$field = DatalessField::create('LocalisedBadges');
$field->setTemplate('App\Forms\LocalisedBadges');
$field->customise(LocalisedBadgesHelper::singleton()->getLocales($owner));
$fields->unshift($field);
}
}
class LocalisedBadgesHelper
{
use Injectable;
/*
* Specific logic for deciding how the badges will be displayed on the frontend
*/
public function getLocales(SiteTree|File $data, string $objectType = 'Page'): array
{
$nonExistingLocales = Locale::getLocales()->sort('Sort');
$existingLocales = Locale::getLocales()->sort('Sort');
$localeVersions = FluentHelper::getLocaleCodesByObjectInstance($data);
if (count($localeVersions) > 0) {
$nonExistingLocales = $nonExistingLocales->exclude('Locale', $localeVersions);
$existingLocales = $existingLocales->filter('Locale', $localeVersions);
} else {
$existingLocales = ArrayList::create();
}
$badgeData = [
'EditLink' => $data->CMSEditLink(),
'Existing' => $existingLocales,
'NonExisting' => $nonExistingLocales,
'ObjectType' => $objectType,
];
return $badgeData;
}
}
<div class="locale-badges">
<% if $Current || $Existing %>
<div class="locale-badge-container">
<p>Locales</p>
<div>
<% loop $Existing %>
<a href="{$Up.EditLink}/?l={$Locale}"
aria-label="{$Title}"
class="badge <% if $CurrentLocale.ID == $ID %>badge-success<% else %>badge-info fluent-badge--localised<% end_if %>"
data-balloon-pos="down"
target="_top"
>
<% if $LocaleSuffix = 001 %>
EN
<% else %>
$LocaleSuffix
<% end_if %>
</a>
<% end_loop %>
</div>
</div>
<% end_if %>
<% if $NonExisting %>
<div class="locale-badge-container">
<p>{$ObjectType} doesn't exist in</p>
<div>
<% loop $NonExisting %>
<a href="{$Up.EditLink}/?l={$Locale}"
aria-label="{$Title}"
class="badge badge-secondary <% if $CurrentLocale.ID == $ID %>badge-success<% end_if %>"
data-balloon-pos="down"
target="_top"
>
<% if $LocaleSuffix = 001 %>
EN
<% else %>
$LocaleSuffix
<% end_if %>
</a>
<% end_loop %>
</div>
</div>
<% end_if %>
</div>
.locale-badges {
background-color: #E9F0F4;
border-bottom: 1px solid #ced5e1;
display: flex;
margin: -20px -20px 20px;
padding: 0 20px;
[aria-label][data-balloon-pos]:after {
font-family: inherit;
text-transform: capitalize;
}
}
.badge-non-existing-current {
background-color: #333;
&:hover {
background-color: #333;
}
}
.locale-badge-container {
padding: 8px 0;
p {
margin-bottom: 0;
}
&:nth-of-type(n + 2) {
margin-left: 15px;
border-left: 1px solid #ced5e1;
padding-left: 15px;
}
}
// Asset admin editor locale badges
.editor__details {
.locale-badges {
margin-top: 0.5rem;
}
}
public static function resolveInheritStatus(File $object, array $args, array $context, ?ResolveInfo $info): bool
{
// just for code linting
/** @var DataObject|Versioned|FluentVersionedExtension $versionedObject */
$versionedObject = $object;
return !$versionedObject->isDraftedInLocale();
}
This flag is then injected into the React component.
const inheritBadge = {
node: "span",
key: "inherit-status",
className: `gallery-item--inherit ${styles.flagInheritedLocale}`,
};
We've recently identified that managing Archiving Link in Fluent doesn't work ... or at least works in a very clumsy way.
See https://github.com/silverstripe/silverstripe-linkfield/pull/273#issuecomment-2046515727 for the full context.
Timebox
1 work day
Objectives