Skip to content

Commit

Permalink
Merge pull request #627 from tractorcow-farm/feature/copy-to-locale-ui
Browse files Browse the repository at this point in the history
NEW: Localisation manager UI improvements.
  • Loading branch information
tractorcow authored Jul 14, 2020
2 parents 4295192 + 2fb7945 commit 69a4a3c
Show file tree
Hide file tree
Showing 9 changed files with 592 additions and 46 deletions.
97 changes: 90 additions & 7 deletions src/Extension/FluentExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,30 @@ class FluentExtension extends DataExtension
*/
private static $data_exclude = [];

/**
* Enable copy to locale action in the localisation manager
*
* @config
* @var bool
*/
private static $copy_to_locale_enabled = true;

/**
* Enable copy from locale action in the localisation manager
*
* @config
* @var bool
*/
private static $copy_from_locale_enabled = true;

/**
* Enable batch actions in the edit form
*
* @config
* @var bool
*/
private static $batch_actions_enabled = true;

/**
* Cache of localised fields for this model
*/
Expand Down Expand Up @@ -845,6 +869,30 @@ public function LocaleInformation($locale = null)
return RecordLocale::create($this->owner, $localeObj);
}

/**
* Get list of locales where record is localised in
*
* @return array
*/
public function getLocaleInstances(): array
{
$locales = [];

foreach (Locale::getCached() as $locale) {
/** @var Locale $locale */
$info = $this->owner->LocaleInformation($locale->getLocale());
$source = $info->getSourceLocale();

if ($source->Locale !== $locale->Locale) {
continue;
}

$locales[] = $locale;
}

return $locales;
}

/**
* Return the linking mode for the current locale and object
*
Expand Down Expand Up @@ -1051,10 +1099,35 @@ protected function findRecordInLocale($locale, $table, $id)
*/
public function updateLocalisationTabColumns(&$summaryColumns)
{
$summaryColumns['IsDraft'] = [
'title' => 'Saved',
$summaryColumns['Status'] = [
'title' => 'Status',
'callback' => function (Locale $object) {
return $object->RecordLocale()->IsDraft() ? 'Saved' : '';
if (!$object->RecordLocale()) {
return '';
}

if ($object->RecordLocale()->IsDraft()) {
return _t(self::class . '.LOCALISED', 'Localised');
}

return _t(self::class . '.NOTLOCALISED', 'Not localised');
}
];

$summaryColumns['Source'] = [
'title' => 'Source',
'callback' => function (Locale $object) {
if (!$object->RecordLocale()) {
return '';
}

$sourceLocale = $object->RecordLocale()->getSourceLocale();

if ($sourceLocale) {
return $sourceLocale->getLongTitle();
}

return _t(self::class . '.NOSOURCE', 'No source');
}
];
}
Expand Down Expand Up @@ -1085,12 +1158,22 @@ public function updateLocalisationTabConfig(GridFieldConfig $config)
new GroupActionMenu(GridField_ActionMenuItem::DEFAULT_GROUP)
]);

$copyToLocaleEnabled = $this->owner->config()->get('copy_to_locale_enabled');
$copyFromLocaleEnabled = $this->owner->config()->get('copy_from_locale_enabled');

// Add each copy from / to
foreach (Locale::getCached() as $locale) {
$config->addComponents([
new CopyLocaleAction($locale->Locale, true),
new CopyLocaleAction($locale->Locale, false),
]);
if ($copyToLocaleEnabled) {
$config->addComponents([
CopyLocaleAction::create($locale->Locale, true),
]);
}

if ($copyFromLocaleEnabled) {
$config->addComponents([
CopyLocaleAction::create($locale->Locale, false),
]);
}
}
}
}
203 changes: 195 additions & 8 deletions src/Extension/FluentSiteTreeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\LiteralField;
use SilverStripe\Forms\Tab;
use SilverStripe\ORM\FieldType\DBHTMLText;
use SilverStripe\Versioned\Versioned;
use SilverStripe\View\SSViewer;
use TractorCow\Fluent\Extension\Traits\FluentAdminTrait;
use TractorCow\Fluent\Model\Locale;
use TractorCow\Fluent\Model\RecordLocale;
use TractorCow\Fluent\State\FluentState;

// Soft dependency on CMS module
Expand All @@ -39,6 +43,15 @@ class FluentSiteTreeExtension extends FluentVersionedExtension
*/
private static $locale_published_status_message = true;

/**
* Enable localise actions (copy to draft and copy & publish actions)
* these actions can be used to localise page content directly via main page actions
*
* @config
* @var bool
*/
private static $localise_actions_enabled = true;

/**
* Add alternate links to metatags
*
Expand Down Expand Up @@ -202,6 +215,18 @@ public function updateCMSActions(FieldList $actions)
// Update specific sitetree publish actions
$this->updateSavePublishActions($actions);

// Update specific sitetree localise actions
$this->updateLocaliseActions($actions);

// Update information panel (shows published state)
$this->updateInformationPanel($actions);

// Update the state of publish action (if needed)
$this->updatePublishState($actions);

// Update unpublish and archive actions
$this->updateMoreOptionsActions($actions);

// Add extra fluent menu
$this->updateFluentActions($actions, $this->owner);
}
Expand Down Expand Up @@ -239,15 +264,25 @@ protected function addLocaleStatusMessage(FieldList $fields)
);
}
} else {
// If frontend publishing is *not* required, then we have two possibilities.
// If frontend publishing is *not* required, then we have multiple possibilities.
if (!$this->isDraftedInLocale()) {
// Our content hasn't been drafted or published. If this Locale has a Fallback, then content might be
// getting inherited from that Fallback.
$message = _t(
__CLASS__ . '.LOCALESTATUSFLUENTINHERITED',
'Content for this page may be inherited from another locale. If you wish you make an ' .
'independent copy of this page, please use one of the "Copy" actions provided.'
);
$info = RecordLocale::create($this->owner, Locale::getCurrentLocale());

// Our content hasn't been drafted or published.
if ($info->getSourceLocale()) {
// If this Locale has a Fallback, then content might be getting inherited from that Fallback.
$message = _t(
__CLASS__ . '.LOCALESTATUSFLUENTINHERITED',
'Content for this page may be inherited from another locale. If you wish you make an ' .
'independent copy of this page, please use one of the "Copy" actions provided.'
);
} else {
// This locale doesn't have any content source
$message = _t(
__CLASS__ . '.LOCALESTATUSFLUENTUNKNOWN',
'No content is available for this page. Please localise this page or provide a locale fallback.'
);
}
} elseif (!$this->isPublishedInLocale()) {
// Our content has been saved to draft, but hasn't yet been published. That published content may be
// coming from a Fallback.
Expand Down Expand Up @@ -366,6 +401,158 @@ protected function updateSavePublishActions(FieldList $actions)
}
}

/**
* Update publish action state to reflect the localised record instead of the base record
*
* @param FieldList $actions
*/
protected function updatePublishState(FieldList $actions): void
{
$owner = $this->owner;

if (!$owner->isInDB()) {
return;
}

$published = $owner->isPublishedInLocale();

if (!$published) {
return;
}

/** @var CompositeField $majorActions */
$majorActions = $actions->fieldByName('MajorActions');

if (!$majorActions) {
return;
}

$publishAction = $majorActions->fieldByName('action_publish');

if (!$publishAction) {
return;
}

// make sure that changes only on the base record
// do not trigger "need to publish" button state
// this is needed because the default interface looks
// at the base record instead of the localised page
$publishAction
->setTitle(_t('SilverStripe\\CMS\\Model\\SiteTree.BUTTONPUBLISHED', 'Published'))
->removeExtraClass(
'btn-primary font-icon-rocket btn-outline-primary font-icon-tick'
)
->addExtraClass('btn-outline-primary font-icon-tick');

if (!$owner->stagesDifferInLocale()) {
return;
}

// If staged and live is different we change the button to "Publish"
// as the page hasn't been published
$publishAction
->setTitle(_t('SilverStripe\\CMS\\Model\\SiteTree.BUTTONSAVEPUBLISH', 'Publish'))
->addExtraClass('btn-primary font-icon-rocket')
->removeExtraClass('btn-outline-primary font-icon-tick');
}

/**
* Update archive and unpublish actions to reflect the localised record instead of the base record
*
* @param FieldList $actions
*/
protected function updateMoreOptionsActions(FieldList $actions): void
{
/** @var Tab $moreOptions */
$moreOptions = $actions->fieldByName('ActionMenus.MoreOptions');

if (!$moreOptions) {
return;
}

if ($this->isPublishedInLocale()) {
return;
}

// remove unpublish action as the record is not published
$moreOptions->removeByName('action_unpublish');

// update the label on archive action as it could have "unpublish and archive" which is incorrect
$archiveAction = $moreOptions->fieldByName('action_archive');

if (!$archiveAction) {
return;
}

$archiveAction->setTitle(_t('SilverStripe\\CMS\\Controllers\\CMSMain.ARCHIVE', 'Archive'));
}

/**
* Remove "copy to draft" and "copy & publish" actions based on configuration
*
* @param FieldList $actions
*/
protected function updateLocaliseActions(FieldList $actions): void
{
$owner = $this->owner;

if ($owner->config()->get('localise_actions_enabled')) {
return;
}

if (!$owner->isInDB() || $owner->isDraftedInLocale()) {
return;
}

$actions->removeByName([
'action_save',
'action_publish',
]);
}

/**
* Information panel show published state of a base record by default
* this overrides the display with the published state of the localised record
*
* @param FieldList $actions
*/
protected function updateInformationPanel(FieldList $actions): void
{
$owner = $this->owner;

/** @var Tab $moreOptions */
$moreOptions = $actions->fieldByName('ActionMenus.MoreOptions');

if (!$moreOptions) {
return;
}

/** @var LiteralField $information */
$information = $moreOptions->fieldByName('Information');

if (!$information) {
return;
}

$liveRecord = Versioned::withVersionedMode(function () use ($owner) {
Versioned::set_stage(Versioned::LIVE);

return SiteTree::get()->byID($owner->ID);
});

$infoTemplate = SSViewer::get_templates_by_class(
$owner->ClassName,
'_Information',
SiteTree::class
);

// show published info of localised record, not base record (this is framework's default)
$information->setValue($owner->customise([
'Live' => $liveRecord,
'ExistsOnLive' => $owner->isPublishedInLocale(),
])->renderWith($infoTemplate));
}

/**
* @param Form $form
* @param string $message
Expand Down
Loading

0 comments on commit 69a4a3c

Please sign in to comment.