Skip to content

Commit 159b3ac

Browse files
committed
[TASK] Refactor JavaScript implementation
The issue on TYPO3 13 having the button label writing outside the borders made a refactoring and regeneration of the localization.ts necessary. The labels were rewritten as CDATA to allow line breaks, getting rid of the too long labels. Together with TYPO3 Core standardized TSconfig for localizations the overridden JavaScript is more lightweight and doesn't need the AjaxRoute anymore. Therefore the AjaxRoutes.php and AjaxController.php are removed. In addition to Core functionality, the DeepL allow translateion now can be enabled/disabled by the following setting in Page TSConfig: ``` # Enabled (Default) mod.web_layout.localization.enableDeeplTranslate = 1 # Disabled mod.web_layout.localization.enableDeeplTranslate = 0 ``` This could be overridden in User TSconfig, too: ``` # Enabled (Default) page.mod.web_layout.localization.enableDeeplTranslate = 1 # Disabled page.mod.web_layout.localization.enableDeeplTranslate = 0 ```
1 parent f99d421 commit 159b3ac

File tree

11 files changed

+103
-173
lines changed

11 files changed

+103
-173
lines changed

Build/Sources/Core13/localization.ts

Lines changed: 43 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,21 @@
1313

1414
import DocumentService from '@typo3/core/document-service';
1515
import $ from 'jquery';
16-
import { AjaxResponse } from '@typo3/core/ajax/ajax-response';
16+
import type { AjaxResponse } from '@typo3/core/ajax/ajax-response';
1717
import { SeverityEnum } from './enum/severity';
1818
import AjaxRequest from '@typo3/core/ajax/ajax-request';
1919
import Icons from './icons';
20-
import Modal, { ModalElement } from './modal';
21-
import MultiStepWizard, { MultiStepWizardSettings } from './multi-step-wizard';
20+
import Modal, { type ModalElement } from './modal';
21+
import MultiStepWizard, { type MultiStepWizardSettings } from './multi-step-wizard';
2222
import '@typo3/backend/element/icon-element';
23-
import { MarkupIdentifiers } from './enum/icon-types';
23+
import { MarkupIdentifiers } from '@typo3/backend/enum/icon-types';
2424

2525
type LanguageRecord = {
2626
uid: number;
2727
title: string;
2828
flagIcon: string;
2929
};
3030

31-
type DeeplSettings = {
32-
status: boolean;
33-
message: string;
34-
};
35-
3631
type SummaryColumns = {
3732
columns: { [key: number]: string };
3833
columnList: Array<number>;
@@ -69,7 +64,6 @@ class Localization {
6964
//------------------------------------------------------------------------------------------------------------------
7065
const deeplIconMarkup = await Icons.getIcon('actions-localize-deepl', Icons.sizes.large, null, null, MarkupIdentifiers.inline);
7166
//------------------------------------------------------------------------------------------------------------------
72-
7367
$(this.triggerButton).removeClass('disabled');
7468

7569
$(document).on('click', this.triggerButton, async (e: JQueryEventObject): Promise<void> => {
@@ -101,14 +95,12 @@ class Localization {
10195
parseInt($triggerButton.data('languageId'), 10),
10296
)).resolve();
10397

104-
// const deeplSettings: DeeplSettings = await (await this.deeplSettings()).resolve();
105-
10698
if ($triggerButton.data('allowTranslate')) {
10799
actions.push(
108100
'<div class="row">'
109101
+ '<div class="col-sm-3">'
110102
+ '<input class="btn-check t3js-localization-option" type="radio" name="mode" id="mode_translate" value="localize">'
111-
+ '<label class="btn btn-default btn-block-vertical deepl-translate-modal-icon-text-alignment" for="mode_translate" data-action="localize">'
103+
+ '<label class="btn btn-default btn-block-vertical" for="mode_translate" data-action="localize">'
112104
+ localizeIconMarkup
113105
+ TYPO3.lang['localize.wizard.button.translate']
114106
+ '</label>'
@@ -126,7 +118,7 @@ class Localization {
126118
'<div class="row">'
127119
+ '<div class="col-sm-3">'
128120
+ '<input class="btn-check t3js-localization-option" type="radio" name="mode" id="mode_copy" value="copyFromLanguage">'
129-
+ '<label class="btn btn-default btn-block-vertical deepl-translate-modal-icon-text-alignment" for="mode_copy" data-action="copy">'
121+
+ '<label class="btn btn-default btn-block-vertical" for="mode_copy" data-action="copy">'
130122
+ copyIconMarkup
131123
+ TYPO3.lang['localize.wizard.button.copy']
132124
+ '</label>'
@@ -140,44 +132,40 @@ class Localization {
140132
}
141133

142134
// deepltranslate
143-
actions.push(
144-
'<div class="row" id="deeplTranslate">'
145-
+ '<div class="col-sm-3">'
146-
+ '<input class="btn-check t3js-localization-option" type="radio" name="mode" id="mode_deepltranslateauto" value="localizedeepl">'
147-
+ '<label class="btn btn-default btn-block-vertical deepl-translate-modal-icon-text-alignment" for="mode_deepltranslateauto" data-action="deepltranslate">'
148-
+ deeplIconMarkup
149-
+ TYPO3.lang['localize.educate.deepltranslateHeader']
150-
+ '</label>'
151-
+ '</div>'
152-
+ '<div class="col-sm-9" id="deeplText">'
153-
+ '<div class=\'alert alert-danger\' hidden>'
154-
+ TYPO3.lang['localize.educate.deeplSettingsFailure']
155-
+ '</div>'
156-
+ '<p class="t3js-helptext t3js-helptext-copy text-body-secondary">' + TYPO3.lang['localize.educate.deepltranslate'] + '</p>'
157-
+ '</div>'
158-
+ '</div>',
159-
);
160-
availableLocalizationModes.push('localizedeepl');
161-
162-
// deepltranslate-auto
163-
actions.push(
164-
'<div class="row" id="deeplTranslateAuto">'
165-
+ '<div class="col-sm-3">'
166-
+ '<input class="btn-check t3js-localization-option" type="radio" name="mode" id="mode_deepltranslate" value="localizedeeplauto">'
167-
+ '<label class="btn btn-default btn-block-vertical deepl-translate-modal-icon-text-alignment" for="mode_deepltranslate" data-action="deepltranslate">'
168-
+ deeplIconMarkup
169-
+ TYPO3.lang['localize.educate.deepltranslateHeaderAutodetect']
170-
+ '</label>'
171-
+ '</div>'
172-
+ '<div class="col-sm-9" id="deeplTextAuto">'
173-
+ '<div class=\'alert alert-danger\' hidden>'
174-
+ TYPO3.lang['localize.educate.deeplSettingsFailure']
175-
+ '</div>'
176-
+ '<p class="t3js-helptext t3js-helptext-copy text-body-secondary">' + TYPO3.lang['localize.educate.deepltranslateAuto'] + '</p>'
177-
+ '</div>'
178-
+ '</div>',
179-
);
180-
availableLocalizationModes.push('localizedeeplauto');
135+
if ($triggerButton.data('allowDeeplTranslate')) {
136+
actions.push(
137+
'<div class="row" id="deeplTranslate">'
138+
+ '<div class="col-sm-3">'
139+
+ '<input class="btn-check t3js-localization-option" type="radio" name="mode" id="mode_deepltranslate" value="localizedeepl">'
140+
+ '<label class="btn btn-default btn-block-vertical" for="mode_deepltranslate" data-action="deepltranslate">'
141+
+ deeplIconMarkup
142+
+ TYPO3.lang['localize.educate.deepltranslateHeader']
143+
+ '</label>'
144+
+ '</div>'
145+
+ '<div class="col-sm-9" id="deeplText">'
146+
+ '<p class="t3js-helptext t3js-helptext-copy text-body-secondary">' + TYPO3.lang['localize.educate.deepltranslate'] + '</p>'
147+
+ '</div>'
148+
+ '</div>',
149+
);
150+
availableLocalizationModes.push('localizedeepl');
151+
152+
// deepltranslate-auto
153+
actions.push(
154+
'<div class="row" id="deeplTranslateAuto">'
155+
+ '<div class="col-sm-3">'
156+
+ '<input class="btn-check t3js-localization-option" type="radio" name="mode" id="mode_deepltranslateauto" value="localizedeeplauto">'
157+
+ '<label class="btn btn-default btn-block-vertical" for="mode_deepltranslateauto" data-action="deepltranslate">'
158+
+ deeplIconMarkup
159+
+ TYPO3.lang['localize.educate.deepltranslateHeaderAutodetect']
160+
+ '</label>'
161+
+ '</div>'
162+
+ '<div class="col-sm-9" id="deeplTextAuto">'
163+
+ '<p class="t3js-helptext t3js-helptext-copy text-body-secondary">' + TYPO3.lang['localize.educate.deepltranslateAuto'] + '</p>'
164+
+ '</div>'
165+
+ '</div>',
166+
);
167+
availableLocalizationModes.push('localizedeeplauto');
168+
}
181169

182170
if (availableLocalizationModes.length === 1) {
183171
MultiStepWizard.set('localizationMode', availableLocalizationModes[0]);
@@ -279,7 +267,7 @@ class Localization {
279267

280268
const column = columns[colPos];
281269
const rowElement = document.createElement('div');
282-
rowElement.classList.add('row', 'gy-2')
270+
rowElement.classList.add('row', 'gy-2');
283271

284272
result.records[colPos].forEach((record: SummaryColPosRecord): void => {
285273
const label = ' (' + record.uid + ') ' + record.title;
@@ -397,38 +385,8 @@ class Localization {
397385
MultiStepWizard.show();
398386

399387
MultiStepWizard.getComponent().on('change', '.t3js-localization-option', (optionEvt: JQueryEventObject): void => {
400-
const localizationMode = $(optionEvt.currentTarget).val();
401-
const divDeepl: HTMLElement = window.parent.document.querySelector('#deeplText .alert');
402-
const divDeeplAuto: HTMLElement = window.parent.document.querySelector('#deeplTextAuto .alert');
403-
if (localizationMode === 'localizedeepl' || localizationMode === 'localizedeeplauto') {
404-
const selector = localizationMode == 'localizedeepl' ? '#deeplText .alert' : '#deeplTextAuto .alert';
405-
const divDeeplSelector: HTMLElement = window.parent.document.querySelector(selector);
406-
//------------------------------------------------------------------------------------------------------------
407-
// deepltranslate-added
408-
//------------------------------------------------------------------------------------------------------------
409-
this.deeplSettings().then(async (response) => {
410-
const deeplSettings : DeeplSettings = await(response.resolve());
411-
if (deeplSettings.status === false) {
412-
MultiStepWizard.lockNextStep();
413-
divDeepl.hidden = true;
414-
divDeeplAuto.hidden = true;
415-
divDeeplSelector.hidden = false;
416-
} else {
417-
divDeepl.hidden = true;
418-
divDeeplAuto.hidden = true;
419-
MultiStepWizard.set('localizationMode', $(optionEvt.currentTarget).val());
420-
MultiStepWizard.unlockNextStep();
421-
}
422-
});
423-
//------------------------------------------------------------------------------------------------------------
424-
} else {
425-
divDeepl.hidden = true;
426-
divDeeplAuto.hidden = true;
427-
// original from TYPO3 outset the deeplSettings() promise handling
428-
MultiStepWizard.set('localizationMode', $(optionEvt.currentTarget).val());
429-
MultiStepWizard.unlockNextStep();
430-
// ^^ original TYPO3
431-
}
388+
MultiStepWizard.set('localizationMode', $(optionEvt.currentTarget).val());
389+
MultiStepWizard.unlockNextStep();
432390
});
433391
});
434392
});
@@ -471,15 +429,6 @@ class Localization {
471429
uidList: uidList,
472430
}).get();
473431
}
474-
475-
/**
476-
* Returns status of deepl configuration, is not set Deepl Button are disabled
477-
*
478-
* @returns {Promise<AjaxResponse>}
479-
*/
480-
private deeplSettings(): Promise<AjaxResponse> {
481-
return new AjaxRequest(TYPO3.settings.ajaxUrls.deepl_check_configuration).get();
482-
}
483432
}
484433

485434
export default new Localization();

Classes/Configuration.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace WebVision\Deepltranslate\Core;
66

7+
use TYPO3\CMS\Backend\Utility\BackendUtility;
78
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationExtensionNotConfiguredException;
89
use TYPO3\CMS\Core\Configuration\Exception\ExtensionConfigurationPathDoesNotExistException;
910
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
@@ -29,4 +30,20 @@ public function getApiKey(): string
2930
{
3031
return $this->apiKey;
3132
}
33+
34+
/**
35+
* Checks translation allowed against Page TSconfig from settings
36+
*
37+
* @param int $pageId
38+
* @return bool
39+
* @throws \JsonException
40+
*/
41+
public function isDeeplTranslationAllowedOnPage(int $pageId): bool
42+
{
43+
$localizationConfiguration = BackendUtility::getPagesTSconfig($pageId)['mod.']['web_layout.']['localization.'] ?? [];
44+
if ((bool)($localizationConfiguration['enableDeeplTranslate'] ?? true) === false) {
45+
return false;
46+
}
47+
return true;
48+
}
3249
}

Classes/ConfigurationInterface.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@
1313
interface ConfigurationInterface
1414
{
1515
public function getApiKey(): string;
16+
17+
public function isDeeplTranslationAllowedOnPage(int $pageId): bool;
1618
}

Classes/Controller/Backend/AjaxController.php

Lines changed: 0 additions & 39 deletions
This file was deleted.

Classes/Event/Listener/RenderLocalizationSelect.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,26 @@
77
use Psr\EventDispatcher\EventDispatcherInterface;
88
use TYPO3\CMS\Backend\Controller\Event\RenderAdditionalContentToRecordListEvent;
99
use TYPO3\CMS\Core\Site\Entity\Site;
10+
use WebVision\Deepltranslate\Core\ConfigurationInterface;
1011
use WebVision\Deepltranslate\Core\Event\RenderLocalizationSelectAllowed;
1112
use WebVision\Deepltranslate\Core\Form\TranslationDropdownGenerator;
1213

1314
final class RenderLocalizationSelect
1415
{
1516
public function __construct(
1617
private readonly TranslationDropdownGenerator $generator,
17-
private readonly EventDispatcherInterface $eventDispatcher
18+
private readonly EventDispatcherInterface $eventDispatcher,
19+
private readonly ConfigurationInterface $configuration
1820
) {
1921
}
2022

2123
public function __invoke(RenderAdditionalContentToRecordListEvent $event): void
2224
{
2325
$request = $event->getRequest();
26+
$currentPageId = (int)($request->getQueryParams()['id'] ?? 0);
27+
if (!$this->configuration->isDeeplTranslationAllowedOnPage($currentPageId)) {
28+
return;
29+
}
2430
// Check, if some event listener doesn't allow rendering here.
2531
// For use cases see Event
2632
$renderingAllowedEvent = $this->eventDispatcher->dispatch(new RenderLocalizationSelectAllowed($request));

Classes/ViewHelpers/Be/Access/DeeplTranslateAllowedViewHelper.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,31 @@
55
namespace WebVision\Deepltranslate\Core\ViewHelpers\Be\Access;
66

77
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
8+
use TYPO3\CMS\Core\Utility\GeneralUtility;
9+
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContext;
810
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
911
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
1012
use WebVision\Deepltranslate\Core\Access\AllowedTranslateAccess;
13+
use WebVision\Deepltranslate\Core\ConfigurationInterface;
1114

15+
/**
16+
* @internal This ViewHelper is marked internal and only to be used within
17+
* the DeepL translate packages and therefore no public API.
18+
*/
1219
final class DeeplTranslateAllowedViewHelper extends AbstractConditionViewHelper
1320
{
14-
public function initializeArguments(): void
15-
{
16-
parent::initializeArguments();
17-
}
18-
1921
public static function verdict(array $arguments, RenderingContextInterface $renderingContext): bool
2022
{
23+
$deeplConfiguration = GeneralUtility::makeInstance(ConfigurationInterface::class);
24+
if ($deeplConfiguration->getApiKey() === '') {
25+
return false;
26+
}
27+
/** @var RenderingContext $renderingContext */
28+
$currentPageId = (int)($renderingContext->getRequest()?->getQueryParams()['id'] ?? 0);
29+
// set default to true avoiding breaking behaviour issues
30+
if (!$deeplConfiguration->isDeeplTranslationAllowedOnPage($currentPageId)) {
31+
return false;
32+
}
2133
if (self::getBackendUserAuthentication()->check('custom_options', AllowedTranslateAccess::ALLOWED_TRANSLATE_OPTION_VALUE)) {
2234
return true;
2335
}

Configuration/Backend/AjaxRoutes.php

Lines changed: 0 additions & 17 deletions
This file was deleted.

Resources/Private/Language/de.locallang.xlf

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@
1212
<target>Mit DeepL übersetzen</target>
1313
</trans-unit>
1414
<trans-unit id="localize.educate.deepltranslateHeader">
15-
<source>Translate with DeepL</source>
16-
<target>Mit DeepL übersetzen</target>
15+
<source>DeepL Translate</source>
16+
<target>DeepL Übersetzung</target>
1717
</trans-unit>
1818
<trans-unit id="localize.educate.deepltranslateHeaderAutodetect">
19-
<source>Translate with DeepL (autodetect)</source>
20-
<target>Mit DeepL übersetzen (autodetect)</target>
19+
<source><![CDATA[DeepL Translate<br>(autodetect)]]></source>
20+
<target><![CDATA[DeepL Übersetzung<br>(autodetect)]]></target>
2121
</trans-unit>
2222
<trans-unit id="localize.educate.deepltranslate" xml:space="preserve">
23-
<source><![CDATA[Translating content using DeepL Translate will create a translation from the source language to the language translation you selected. The translated content will be fetched from DeepL translation service (DeepL claims 99 percentage accuracy). The DeepL service supports translation to and from English, French, German, Spanish, Italian, Dutch, and Polish languages. Other languages will be ignored and will default to the normal translate operation of TYPO3.]]></source>
24-
<target><![CDATA[Wenn Sie Inhalte mit DeepL Translate übersetzen, wird eine Übersetzung von der Ausgangssprache in die von Ihnen ausgewählte Sprache erstellt. Der übersetzte Inhalt wird vom DeepL Übersetzungsdienst abgerufen (DeepL behauptet eine 99-prozentige Genauigkeit). Der Dienst DeepL unterstützt die Übersetzung in und aus den Sprachen Englisch, Französisch, Deutsch, Spanisch, Italienisch, Niederländisch und Polnisch. Andere Sprachen werden ignoriert und die normale Übersetzungsfunktion von TYPO3 wird verwendet.]]></target>
23+
<source><![CDATA[Translating content via DeepL translate will create a translation from source language to the language you translate to. The translated content will be from DeepL translation service which is 99% accurate. DeepL service supports translation to and from <a href="https://developers.deepl.com/docs/getting-started/supported-languages" target="_blank">different languages</a>. Other languages will be ignored and will default to the normal translate operation of TYPO3.]]></source>
24+
<target><![CDATA[Die Übersetzung von Inhalten über DeepL translate erstellt eine Übersetzung von der Ausgangssprache in die Sprache, in die Sie übersetzen. Der übersetzte Inhalt wird vom DeepL Übersetzungsdienst stammen, der zu 99% genau ist. Der Dienst DeepL unterstützt die Übersetzung in und aus <a href="https://developers.deepl.com/docs/getting-started/supported-languages" target="_blank">verschiedenen Sprachen</a>. Andere Sprachen werden ignoriert und es wird die normale Übersetzungsfunktion von TYPO3 verwendet.]]></target>
2525
</trans-unit>
2626
<trans-unit id="localize.educate.deepltranslateAuto" xml:space="preserve">
2727
<source><![CDATA[Translating content using DeepL Translate (autodetect) will create a translation from the auto detected source language to the language translation you selected. The translated content will be fetched from DeepL translation service (DeepL claims 99 percentage accuracy). The DeepL service supports translation to and from English, French, German, Spanish, Italian, Dutch, and Polish languages. Other languages will be ignored and will default to the normal translate operation of TYPO3.]]></source>

0 commit comments

Comments
 (0)