Skip to content

Commit

Permalink
[TASK] Use simplified backend module template for UsageWidget
Browse files Browse the repository at this point in the history
TYPO3 v12 introduced a simplified ext:backend ModuleTemplate API [1]
to avoid the use of `StandaloneView` in the backend context and it's
not a suprise that TYPO3 v13 continued on this path and deprecated
it in TYPO3 13.3 [2] finally removing it as breaking change in TYPO3
v14 [3].

Sounding quite challenging, it's quite easy to make the `UsageWidget`
for `EXT:dashboard` compatible with TYPO3 v12 and v13 using simplified
backend module template API directly with the template override [4]
feature already included.

The surrounding `<p>` tag in the fluid template for the usage text
is replaced with `<span>` to make the UX feeling more user-friendly.

[1] https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/12.0/Feature-96730-SimplifiedExtbackendModuleTemplateAPI.html
[2] https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/13.3/Deprecation-104773-CustomFluidViewsAndExtbase.html
[3] https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/14.0/Breaking-105377-DeprecatedFunctionalityRemoved.html
[4] https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/12.0/Feature-96812-OverrideBackendTemplatesWithTSconfig.html
  • Loading branch information
sbuerk committed Dec 19, 2024
1 parent b9f4df7 commit f71cf02
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,52 @@

declare(strict_types=1);

namespace WebVision\Deepltranslate\Core\Core12\Widgets;
namespace WebVision\Deepltranslate\Core\Widgets;

use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\View\BackendViewFactory;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Dashboard\Widgets\RequestAwareWidgetInterface;
use TYPO3\CMS\Dashboard\Widgets\WidgetConfigurationInterface;
use TYPO3\CMS\Dashboard\Widgets\WidgetInterface;
use TYPO3\CMS\Fluid\View\StandaloneView;
use WebVision\Deepltranslate\Core\Service\UsageService;

/**
* `EXT:dashboard` widget compatible with TYPO3 v12 to display deepl api usage.
*
* @internal implementation only and not part of public API.
* @todo Remove this class when TYPO3 v12 support is dropped along with registration in {@see Configuration/Services.php}.
*/
class UsageWidget implements WidgetInterface
final class UsageWidget implements RequestAwareWidgetInterface, WidgetInterface
{
private WidgetConfigurationInterface $configuration;

private StandaloneView $view;

/**
* @var array<string, mixed>
*/
private array $options;

private ServerRequestInterface $request;

/**
* @param array<string, mixed> $options
*/
public function __construct(
WidgetConfigurationInterface $configuration,
StandaloneView $view,
private readonly WidgetConfigurationInterface $configuration,
private readonly BackendViewFactory $backendViewFactory,
private readonly UsageService $usageService,
array $options = []
) {
$this->configuration = $configuration;
$this->view = $view;
$this->options = $options;
}

public function renderWidgetContent(): string
public function setRequest(ServerRequestInterface $request): void
{
/** @var UsageService $usageService */
$usageService = GeneralUtility::makeInstance(UsageService::class);

// Workaround to make the widget template available in two TYPO3 versions
$templateRootPaths = $this->view->getTemplateRootPaths();
$templateRootPaths[1718368476557] = 'EXT:deepltranslate_core/Resources/Private/Backend/Templates/';
$this->view->setTemplateRootPaths($templateRootPaths);

$currentUsage = $usageService->getCurrentUsage();
$this->request = $request;
}

$this->view->assignMultiple([
public function renderWidgetContent(): string
{
$currentUsage = $this->usageService->getCurrentUsage();
$view = $this->backendViewFactory->create($this->request, ['typo3/cms-dashboard', 'web-vision/deepltranslate-core']);
$view->assignMultiple([
'usages' => [
[
'label' => $this->getLanguageService()->sL('LLL:EXT:deepltranslate_core/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.character'),
Expand All @@ -64,7 +58,7 @@ public function renderWidgetContent(): string
'configuration' => $this->configuration,
]);

return $this->view->render('Widget/UsageWidget');
return $view->render('Widget/UsageWidget');
}

/**
Expand Down
41 changes: 17 additions & 24 deletions Configuration/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use TYPO3\CMS\Backend\View\BackendViewFactory;
use TYPO3\CMS\Core\DependencyInjection\SingletonPass;
use TYPO3\CMS\Core\Information\Typo3Version;
use TYPO3\CMS\Dashboard\WidgetRegistry;
use WebVision\Deepltranslate\Core\Core12\Widgets\UsageWidget as Core12UsageWidget;
use WebVision\Deepltranslate\Core\Form\Item\SiteConfigSupportedLanguageItemsProcFunc;
use WebVision\Deepltranslate\Core\Form\User\HasFormalitySupport;
use WebVision\Deepltranslate\Core\Hooks\TranslateHook;
use WebVision\Deepltranslate\Core\Service\UsageService;
use WebVision\Deepltranslate\Core\Widgets\UsageWidget;

return function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder) {
$typo3version = new Typo3Version();
$services = $containerConfigurator
->services();

Expand All @@ -39,26 +39,19 @@
* Registration directly in Services.yaml will break without EXT:dashboard installed!
*/
if ($containerBuilder->hasDefinition(WidgetRegistry::class)) {
if ($typo3version->getMajorVersion() >= 13) {
// @todo Register TYPO3 v13 compatible UsageWidget implementation. (StandaloneView => ViewFactory)
}
/**
* @todo Remove core12 usage widget when TYPO3 v12 support is removed along with {@see Core11UsageWidget}.
*/
if ($typo3version->getMajorVersion() === 12) {
$services->set('widgets.deepltranslate.widget.useswidget')
->class(Core12UsageWidget::class)
->arg('$view', new Reference('dashboard.views.widget'))
->arg('$options', [])
->tag('dashboard.widget', [
'identifier' => 'widgets-deepl-uses',
'groupNames' => 'deepl',
'title' => 'LLL:EXT:deepltranslate_core/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.title',
'description' => 'LLL:EXT:deepltranslate_core/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.description',
'iconIdentifier' => 'content-widget-list',
'height' => 'small',
'width' => 'small',
]);
}
$services->set('widgets.deepltranslate.widget.useswidget')
->class(UsageWidget::class)
->arg('$backendViewFactory', new Reference(BackendViewFactory::class))
->arg('$usageService', new Reference(UsageService::class))
->arg('$options', [])
->tag('dashboard.widget', [
'identifier' => 'widgets-deepl-uses',
'groupNames' => 'deepl',
'title' => 'LLL:EXT:deepltranslate_core/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.title',
'description' => 'LLL:EXT:deepltranslate_core/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.description',
'iconIdentifier' => 'content-widget-list',
'height' => 'small',
'width' => 'small',
]);
}
};
12 changes: 5 additions & 7 deletions Resources/Private/Backend/Templates/Widget/UsageWidget.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@ <h4>{item.label}</h4>
<f:if condition="{percentage} >= 100">
<f:variable name="severity" value="danger" />
</f:if>
<p>
<f:translate
key="LLL:EXT:deepltranslate_core/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.message"
arguments="{0: count, 1: limit}"
/>
</p>
<div class="progress" role="progressbar" aria-label="Usage" aria-valuenow="{procss}" aria-valuemin="0" aria-valuemax="100" style="height: 50%">
<span><f:translate
key="LLL:EXT:deepltranslate_core/Resources/Private/Language/locallang.xlf:widgets.deepltranslate.widget.useswidget.message"
arguments="{0: count, 1: limit}"
/></span>
<div class="progress" role="progressbar" aria-label="Usage" aria-valuenow="{procss}" aria-valuemin="0" aria-valuemax="100" style="height: 20%">
<div class="progress-bar" style="width: {percentage}%; --bs-progress-bar-bg: var(--bs-{severity -> f:or(alternative: 'info')});">&nbsp;</div>
</div>
</div>
Expand Down

0 comments on commit f71cf02

Please sign in to comment.