[FEATURE] Add backend for loading translations via ajax
This commit is contained in:
parent
e126e674c7
commit
ddbb0c35b0
@ -141,6 +141,11 @@ class ActionController extends BaseController
|
|||||||
*/
|
*/
|
||||||
protected $propertyMapperConfigurationBuilder;
|
protected $propertyMapperConfigurationBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* translation extensions
|
||||||
|
*/
|
||||||
|
protected $translations = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \TYPO3\CMS\Extbase\Service\ExtensionService $extensionService
|
* @param \TYPO3\CMS\Extbase\Service\ExtensionService $extensionService
|
||||||
*/
|
*/
|
||||||
@ -616,8 +621,24 @@ class ActionController extends BaseController
|
|||||||
$this->request->getControllerActionName(),
|
$this->request->getControllerActionName(),
|
||||||
$pluginArguments
|
$pluginArguments
|
||||||
);
|
);
|
||||||
|
$uriTranslation = $this->getControllerContext()
|
||||||
|
->getUriBuilder()
|
||||||
|
->reset()
|
||||||
|
->setCreateAbsoluteUri(true)
|
||||||
|
->setAddQueryString(true)
|
||||||
|
->setTargetPageType(6001)
|
||||||
|
->uriFor(
|
||||||
|
'translations',
|
||||||
|
[
|
||||||
|
'extensions' => $this->translations,
|
||||||
|
],
|
||||||
|
'Translation',
|
||||||
|
'TemplatesAide',
|
||||||
|
'Translationplugin'
|
||||||
|
);
|
||||||
$this->ajaxEnv = [
|
$this->ajaxEnv = [
|
||||||
'uri' => $uri,
|
'uri' => $uri,
|
||||||
|
'uriTranslation' => $uriTranslation,
|
||||||
'object' => $object,
|
'object' => $object,
|
||||||
'namespace' => $this->getPluginNamespace(),
|
'namespace' => $this->getPluginNamespace(),
|
||||||
];
|
];
|
||||||
|
57
Classes/Controller/TranslationController.php
Normal file
57
Classes/Controller/TranslationController.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
namespace Cjel\TemplatesAide\Controller;
|
||||||
|
|
||||||
|
/***
|
||||||
|
*
|
||||||
|
* This file is part of the "Templates Aide" Extension for TYPO3 CMS.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please read the
|
||||||
|
* LICENSE.txt file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
* (c) 2024 Philipp Dieter <philippdieter@attic-media.net>
|
||||||
|
*
|
||||||
|
***/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Localization\LocalizationFactory;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TranslationController
|
||||||
|
*/
|
||||||
|
class TranslationController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
|
||||||
|
{
|
||||||
|
|
||||||
|
protected static $locallangPath = 'Resources/Private/Language/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* action translations
|
||||||
|
*
|
||||||
|
* @param array $extensions
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function translationsAction($extensions = [])
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
foreach ($extensions as $extension) {
|
||||||
|
$langfilePath = 'EXT:'
|
||||||
|
. GeneralUtility::camelCaseToLowerCaseUnderscored($extension)
|
||||||
|
. '/'
|
||||||
|
. self::$locallangPath
|
||||||
|
. 'locallang.xlf';
|
||||||
|
$languageFactory = GeneralUtility::makeInstance(
|
||||||
|
LocalizationFactory::class
|
||||||
|
);
|
||||||
|
$langfileContent = $languageFactory->getParsedData(
|
||||||
|
$langfilePath,
|
||||||
|
$GLOBALS['LANG']->lang
|
||||||
|
);
|
||||||
|
$langfileResult = [];
|
||||||
|
foreach (reset($langfileContent) as $key => $row) {
|
||||||
|
$langfileResult[$key] = reset($row)['target'];
|
||||||
|
}
|
||||||
|
$result[$extension] = $langfileResult;
|
||||||
|
}
|
||||||
|
$GLOBALS['TSFE']->setContentType('application/json');
|
||||||
|
return json_encode($result);
|
||||||
|
}
|
||||||
|
}
|
20
Classes/Domain/Model/Translation.php
Normal file
20
Classes/Domain/Model/Translation.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
namespace Cjel\TemplatesAide\Domain\Model;
|
||||||
|
|
||||||
|
|
||||||
|
/***
|
||||||
|
*
|
||||||
|
* This file is part of the "Templates Aide" Extension for TYPO3 CMS.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please read the
|
||||||
|
* LICENSE.txt file that was distributed with this source code.
|
||||||
|
*
|
||||||
|
* (c) 2024 Philipp Dieter <philippdieter@attic-media.net>
|
||||||
|
*
|
||||||
|
***/
|
||||||
|
/**
|
||||||
|
* Translation
|
||||||
|
*/
|
||||||
|
class Translation extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
|
||||||
|
{
|
||||||
|
}
|
28
Configuration/FlexForms/flexform_translation.xml
Normal file
28
Configuration/FlexForms/flexform_translation.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<T3DataStructure>
|
||||||
|
<sheets>
|
||||||
|
<sDEF>
|
||||||
|
<ROOT>
|
||||||
|
<TCEforms>
|
||||||
|
<sheetTitle>Function</sheetTitle>
|
||||||
|
</TCEforms>
|
||||||
|
<type>array</type>
|
||||||
|
<el>
|
||||||
|
<switchableControllerActions>
|
||||||
|
<TCEforms>
|
||||||
|
<label>Select function</label>
|
||||||
|
<config>
|
||||||
|
<type>select</type>
|
||||||
|
<items>
|
||||||
|
<numIndex index="0">
|
||||||
|
<numIndex index="0">Translation</numIndex>
|
||||||
|
<numIndex index="1">Translation->translations</numIndex>
|
||||||
|
</numIndex>
|
||||||
|
</items>
|
||||||
|
</config>
|
||||||
|
</TCEforms>
|
||||||
|
</switchableControllerActions>
|
||||||
|
</el>
|
||||||
|
</ROOT>
|
||||||
|
</sDEF>
|
||||||
|
</sheets>
|
||||||
|
</T3DataStructure>
|
@ -23,7 +23,7 @@ return [
|
|||||||
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, ',
|
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, ',
|
||||||
],
|
],
|
||||||
'types' => [
|
'types' => [
|
||||||
'1' => ['showitem' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, , --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access, starttime, endtime'],
|
'1' => ['showitem' => ', --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language, sys_language_uid, l10n_parent, l10n_diffsource, --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access, hidden, starttime, endtime'],
|
||||||
],
|
],
|
||||||
'columns' => [
|
'columns' => [
|
||||||
'sys_language_uid' => [
|
'sys_language_uid' => [
|
||||||
|
120
Configuration/TCA/tx_templatesaide_domain_model_translation.php
Normal file
120
Configuration/TCA/tx_templatesaide_domain_model_translation.php
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?php
|
||||||
|
return [
|
||||||
|
'ctrl' => [
|
||||||
|
'title' => 'LLL:EXT:templates_aide/Resources/Private/Language/locallang_db.xlf:tx_templatesaide_domain_model_translation',
|
||||||
|
'label' => 'uid',
|
||||||
|
'tstamp' => 'tstamp',
|
||||||
|
'crdate' => 'crdate',
|
||||||
|
'cruser_id' => 'cruser_id',
|
||||||
|
'versioningWS' => true,
|
||||||
|
'languageField' => 'sys_language_uid',
|
||||||
|
'transOrigPointerField' => 'l10n_parent',
|
||||||
|
'transOrigDiffSourceField' => 'l10n_diffsource',
|
||||||
|
'delete' => 'deleted',
|
||||||
|
'enablecolumns' => [
|
||||||
|
'disabled' => 'hidden',
|
||||||
|
'starttime' => 'starttime',
|
||||||
|
'endtime' => 'endtime',
|
||||||
|
],
|
||||||
|
'searchFields' => '',
|
||||||
|
'iconfile' => 'EXT:templates_aide/Resources/Public/Icons/tx_templatesaide_domain_model_translation.gif'
|
||||||
|
],
|
||||||
|
'interface' => [
|
||||||
|
'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, ',
|
||||||
|
],
|
||||||
|
'types' => [
|
||||||
|
'1' => ['showitem' => ', --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language, sys_language_uid, l10n_parent, l10n_diffsource, --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access, hidden, starttime, endtime'],
|
||||||
|
],
|
||||||
|
'columns' => [
|
||||||
|
'sys_language_uid' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.language',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'select',
|
||||||
|
'renderType' => 'selectSingle',
|
||||||
|
'special' => 'languages',
|
||||||
|
'items' => [
|
||||||
|
[
|
||||||
|
'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.allLanguages',
|
||||||
|
-1,
|
||||||
|
'flags-multiple'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'default' => 0,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'l10n_parent' => [
|
||||||
|
'displayCond' => 'FIELD:sys_language_uid:>:0',
|
||||||
|
'exclude' => true,
|
||||||
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.l18n_parent',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'select',
|
||||||
|
'renderType' => 'selectSingle',
|
||||||
|
'default' => 0,
|
||||||
|
'items' => [
|
||||||
|
['', 0],
|
||||||
|
],
|
||||||
|
'foreign_table' => 'tx_templatesaide_domain_model_translation',
|
||||||
|
'foreign_table_where' => 'AND {#tx_templatesaide_domain_model_translation}.{#pid}=###CURRENT_PID### AND {#tx_templatesaide_domain_model_translation}.{#sys_language_uid} IN (-1,0)',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'l10n_diffsource' => [
|
||||||
|
'config' => [
|
||||||
|
'type' => 'passthrough',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
't3ver_label' => [
|
||||||
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.versionLabel',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'input',
|
||||||
|
'size' => 30,
|
||||||
|
'max' => 255,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'hidden' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.visible',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'check',
|
||||||
|
'renderType' => 'checkboxToggle',
|
||||||
|
'items' => [
|
||||||
|
[
|
||||||
|
0 => '',
|
||||||
|
1 => '',
|
||||||
|
'invertStateDisplay' => true
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'starttime' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.starttime',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'input',
|
||||||
|
'renderType' => 'inputDateTime',
|
||||||
|
'eval' => 'datetime,int',
|
||||||
|
'default' => 0,
|
||||||
|
'behaviour' => [
|
||||||
|
'allowLanguageSynchronization' => true
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'endtime' => [
|
||||||
|
'exclude' => true,
|
||||||
|
'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.endtime',
|
||||||
|
'config' => [
|
||||||
|
'type' => 'input',
|
||||||
|
'renderType' => 'inputDateTime',
|
||||||
|
'eval' => 'datetime,int',
|
||||||
|
'default' => 0,
|
||||||
|
'range' => [
|
||||||
|
'upper' => mktime(0, 0, 0, 1, 1, 2038)
|
||||||
|
],
|
||||||
|
'behaviour' => [
|
||||||
|
'allowLanguageSynchronization' => true
|
||||||
|
]
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
];
|
@ -14,6 +14,21 @@ plugin.tx_templatesaide_dummy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugin.tx_templatesaide_translationplugin {
|
||||||
|
view {
|
||||||
|
# cat=plugin.tx_templatesaide_translationplugin/file; type=string; label=Path to template root (FE)
|
||||||
|
templateRootPath = EXT:templates_aide/Resources/Private/Templates/
|
||||||
|
# cat=plugin.tx_templatesaide_translationplugin/file; type=string; label=Path to template partials (FE)
|
||||||
|
partialRootPath = EXT:templates_aide/Resources/Private/Partials/
|
||||||
|
# cat=plugin.tx_templatesaide_translationplugin/file; type=string; label=Path to template layouts (FE)
|
||||||
|
layoutRootPath = EXT:templates_aide/Resources/Private/Layouts/
|
||||||
|
}
|
||||||
|
persistence {
|
||||||
|
# cat=plugin.tx_templatesaide_translationplugin//a; type=string; label=Default storage PID
|
||||||
|
storagePid =
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
## EXTENSION BUILDER DEFAULTS END TOKEN - Everything BEFORE this line is overwritten with the defaults of the extension builder
|
## EXTENSION BUILDER DEFAULTS END TOKEN - Everything BEFORE this line is overwritten with the defaults of the extension builder
|
||||||
|
|
||||||
<INCLUDE_TYPOSCRIPT: source="FILE:EXT:templates_aide/Resources/Private/TypoScript/constants.ts">
|
<INCLUDE_TYPOSCRIPT: source="FILE:EXT:templates_aide/Resources/Private/TypoScript/constants.ts">
|
@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
plugin.tx_templatesaide_dummy {
|
plugin.tx_templatesaide_dummy {
|
||||||
view {
|
view {
|
||||||
templateRootPaths.0 = EXT:{extension.shortExtensionKey}/Resources/Private/Templates/
|
templateRootPaths.0 = EXT:templates_aide/Resources/Private/Templates/
|
||||||
templateRootPaths.1 = {$plugin.tx_templatesaide_dummy.view.templateRootPath}
|
templateRootPaths.1 = {$plugin.tx_templatesaide_dummy.view.templateRootPath}
|
||||||
partialRootPaths.0 = EXT:templates_aide/Resources/Private/Partials/
|
partialRootPaths.0 = EXT:templates_aide/Resources/Private/Partials/
|
||||||
partialRootPaths.1 = {$plugin.tx_templatesaide_dummy.view.partialRootPath}
|
partialRootPaths.1 = {$plugin.tx_templatesaide_dummy.view.partialRootPath}
|
||||||
layoutRootPaths.0 = EXT:tx_templatesaide/Resources/Private/Layouts/
|
layoutRootPaths.0 = EXT:templates_aide/Resources/Private/Layouts/
|
||||||
layoutRootPaths.1 = {$plugin.tx_templatesaide_dummy.view.layoutRootPath}
|
layoutRootPaths.1 = {$plugin.tx_templatesaide_dummy.view.layoutRootPath}
|
||||||
}
|
}
|
||||||
persistence {
|
persistence {
|
||||||
@ -24,6 +24,31 @@ plugin.tx_templatesaide_dummy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
plugin.tx_templatesaide_translationplugin {
|
||||||
|
view {
|
||||||
|
templateRootPaths.0 = EXT:templates_aide/Resources/Private/Templates/
|
||||||
|
templateRootPaths.1 = {$plugin.tx_templatesaide_translationplugin.view.templateRootPath}
|
||||||
|
partialRootPaths.0 = EXT:templates_aide/Resources/Private/Partials/
|
||||||
|
partialRootPaths.1 = {$plugin.tx_templatesaide_translationplugin.view.partialRootPath}
|
||||||
|
layoutRootPaths.0 = EXT:templates_aide/Resources/Private/Layouts/
|
||||||
|
layoutRootPaths.1 = {$plugin.tx_templatesaide_translationplugin.view.layoutRootPath}
|
||||||
|
}
|
||||||
|
persistence {
|
||||||
|
storagePid = {$plugin.tx_templatesaide_translationplugin.persistence.storagePid}
|
||||||
|
#recursive = 1
|
||||||
|
}
|
||||||
|
features {
|
||||||
|
#skipDefaultArguments = 1
|
||||||
|
# if set to 1, the enable fields are ignored in BE context
|
||||||
|
ignoreAllEnableFieldsInBe = 0
|
||||||
|
# Should be on by default, but can be disabled if all action in the plugin are uncached
|
||||||
|
requireCHashArgumentForActionArguments = 1
|
||||||
|
}
|
||||||
|
mvc {
|
||||||
|
#callDefaultActionIfActionCantBeResolved = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# these classes are only used in auto-generated templates
|
# these classes are only used in auto-generated templates
|
||||||
plugin.tx_templatesaide._CSS_DEFAULT_STYLE (
|
plugin.tx_templatesaide._CSS_DEFAULT_STYLE (
|
||||||
textarea.f3-form-error {
|
textarea.f3-form-error {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
.. include:: ../Includes.txt
|
.. include:: ../Includes.txt
|
||||||
|
|
||||||
|
|
||||||
.. _configuration:
|
.. _configuration:
|
||||||
|
|
||||||
@ -7,20 +6,17 @@
|
|||||||
Configuration
|
Configuration
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Target group: **Developers, Integrators**
|
How is the extension configured?
|
||||||
|
Aim to provide simple instructions detailing how the extension is configured.
|
||||||
How is the extension configured? Aim to provide simple instructions detailing
|
Always assume that the user has no prior experience of using the extension.
|
||||||
how the extension is configured. Always assume that the user has no prior experience
|
|
||||||
of using your extension.
|
|
||||||
|
|
||||||
Try and provide a typical use case for your extension and detail each of the
|
|
||||||
steps required to get the extension running.
|
|
||||||
|
|
||||||
|
Try and provide a typical use case for your extension
|
||||||
|
and detail each of the steps required to get the extension running.
|
||||||
|
|
||||||
Typical Example
|
Typical Example
|
||||||
===============
|
===============
|
||||||
|
|
||||||
- Do we need to include a static template?
|
- Does the integrator need to include a static template?
|
||||||
- For example add a code snippet with comments
|
- For example add a code snippet with comments
|
||||||
|
|
||||||
Minimal example of TypoScript:
|
Minimal example of TypoScript:
|
||||||
@ -43,12 +39,12 @@ Minimal example of TypoScript:
|
|||||||
TypoScript Reference
|
TypoScript Reference
|
||||||
====================
|
====================
|
||||||
|
|
||||||
When detailing data types or standard TypoScript
|
Possible subsections: Reference of TypoScript options.
|
||||||
features, don't hesitate to cross-link to the TypoScript
|
The construct below show the recommended structure for TypoScript properties listing and description.
|
||||||
Reference.
|
|
||||||
|
|
||||||
Information about how to use cross-references:
|
When detailing data types or standard TypoScript features,
|
||||||
https://docs.typo3.org/typo3cms/HowToDocument/WritingReST/Hyperlinks.html
|
don't hesitate to cross-link to the TypoScript Reference as shown below.
|
||||||
|
|
||||||
|
See :ref:`h2document:how-to-document-hyperlinks` for information about how to use cross-references.
|
||||||
|
|
||||||
See the :file:`Settings.cfg` file for the declaration of cross-linking keys.
|
See the :file:`Settings.cfg` file for the declaration of cross-linking keys.
|
||||||
You can add more keys besides tsref.
|
|
||||||
|
@ -38,6 +38,47 @@
|
|||||||
"relations": []
|
"relations": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"position": [
|
||||||
|
398,
|
||||||
|
234
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name": "New Model Object",
|
||||||
|
"value": {
|
||||||
|
"actionGroup": {
|
||||||
|
"_default0_list": false,
|
||||||
|
"_default1_show": false,
|
||||||
|
"_default2_new_create": false,
|
||||||
|
"_default3_edit_update": false,
|
||||||
|
"_default4_delete": false,
|
||||||
|
"customActions": [
|
||||||
|
"translations"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"name": "Translation",
|
||||||
|
"objectsettings": {
|
||||||
|
"addDeletedField": true,
|
||||||
|
"addHiddenField": true,
|
||||||
|
"addStarttimeEndtimeFields": true,
|
||||||
|
"aggregateRoot": false,
|
||||||
|
"categorizable": false,
|
||||||
|
"description": "",
|
||||||
|
"mapToTable": "",
|
||||||
|
"parentClass": "",
|
||||||
|
"sorting": false,
|
||||||
|
"type": "Entity",
|
||||||
|
"uid": "291507465262"
|
||||||
|
},
|
||||||
|
"propertyGroup": {
|
||||||
|
"properties": []
|
||||||
|
},
|
||||||
|
"relationGroup": {
|
||||||
|
"relations": []
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
@ -77,14 +118,25 @@
|
|||||||
"description": "",
|
"description": "",
|
||||||
"key": "dummy",
|
"key": "dummy",
|
||||||
"name": "dummy"
|
"name": "dummy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"actions": {
|
||||||
|
"controllerActionCombinations": "Translation => translations",
|
||||||
|
"noncacheableActions": "",
|
||||||
|
"switchableActions": ""
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"key": "translationplugin",
|
||||||
|
"name": "translation"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"vendorName": "Cjel"
|
"vendorName": "Cjel"
|
||||||
},
|
},
|
||||||
"wires": [],
|
"wires": [],
|
||||||
|
"storagePath": "\/var\/www\/html\/webroot\/typo3conf\/ext\/",
|
||||||
"log": {
|
"log": {
|
||||||
"last_modified": "2020-04-26 10:03",
|
"last_modified": "2024-02-07 06:12",
|
||||||
"extension_builder_version": "9.10.2",
|
"extension_builder_version": "9.10.6",
|
||||||
"be_user": " (1)"
|
"be_user": " (68)"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,24 +1,25 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||||
<xliff version="1.0">
|
<xliff version="1.0">
|
||||||
<file source-language="en" datatype="plaintext" original="messages" date="2022-04-28T10:23:09Z">
|
<file source-language="en" datatype="plaintext" original="EXT:templates_aide/Resources/Private/Language/locallang" date="2024-02-07T18:12:19Z" product-name="templates_aide">
|
||||||
<header>
|
<header/>
|
||||||
<generator>LFEditor</generator>
|
|
||||||
</header>
|
|
||||||
<body>
|
<body>
|
||||||
<trans-unit id="default">
|
<trans-unit id="tx_templatesaide_domain_model_dummy" resname="tx_templatesaide_domain_model_dummy">
|
||||||
<source><![CDATA[Default]]></source>
|
<source>Dummy</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="disableDragModal">
|
<trans-unit id="tx_templatesaide_domain_model_translation" resname="tx_templatesaide_domain_model_translation">
|
||||||
<source><![CDATA[Disable drag and drop confirmation in page tree]]></source>
|
<source>Translation</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="homepage">
|
<trans-unit id="default" resname="default">
|
||||||
<source><![CDATA[Homepage]]></source>
|
<source>Default</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="subpage">
|
<trans-unit id="disableDragModal" resname="disableDragModal">
|
||||||
<source><![CDATA[Subpage]]></source>
|
<source>Disable drag and drop confirmation in page tree</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="tx_templatesaide_domain_model_dummy">
|
<trans-unit id="homepage" resname="homepage">
|
||||||
<source><![CDATA[Dummy]]></source>
|
<source>Homepage</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="subpage" resname="subpage">
|
||||||
|
<source>Subpage</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
@ -1,15 +1,30 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||||
<xliff version="1.0">
|
<xliff version="1.0">
|
||||||
<file source-language="en" datatype="plaintext" original="messages" date="2020-04-26T22:03:44Z" product-name="templates_aide">
|
<file source-language="en" datatype="plaintext" original="EXT:templates_aide/Resources/Private/Language/locallang_db" date="2024-02-07T18:12:19Z" product-name="templates_aide">
|
||||||
<header/>
|
<header/>
|
||||||
<body>
|
<body>
|
||||||
<trans-unit id="tx_templatesaide_domain_model_dummy">
|
<trans-unit id="tx_templatesaide_domain_model_dummy" resname="tx_templatesaide_domain_model_dummy">
|
||||||
<source>Dummy</source>
|
<source>Dummy</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="tx_templates_aide_dummy.name">
|
<trans-unit id="tx_templatesaide_domain_model_translation" resname="tx_templatesaide_domain_model_translation">
|
||||||
|
<source>Translation</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="tx_templates_aide_dummy.name" resname="tx_templates_aide_dummy.name">
|
||||||
<source>dummy</source>
|
<source>dummy</source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="tx_templates_aide_dummy.description">
|
<trans-unit id="tx_templates_aide_dummy.description" resname="tx_templates_aide_dummy.description">
|
||||||
|
<source></source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="tx_templates_aide_translationplugin.name" resname="tx_templates_aide_translationplugin.name">
|
||||||
|
<source>translation</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="tx_templates_aide_translationplugin.description" resname="tx_templates_aide_translationplugin.description">
|
||||||
|
<source></source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="tx_templates_aide_translation.name" resname="tx_templates_aide_translation.name">
|
||||||
|
<source>translation</source>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="tx_templates_aide_translation.description" resname="tx_templates_aide_translation.description">
|
||||||
<source></source>
|
<source></source>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
</body>
|
</body>
|
||||||
|
@ -55,3 +55,19 @@ pageContentelement {
|
|||||||
no_cache = 1
|
no_cache = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pageTranslation = PAGE
|
||||||
|
pageTranslation {
|
||||||
|
typeNum = 6001
|
||||||
|
10 = USER_INT
|
||||||
|
10 {
|
||||||
|
userFunc = Cjel\TemplatesAide\UserFunc\Translation->render
|
||||||
|
}
|
||||||
|
config {
|
||||||
|
disableAllHeaderCode = 1
|
||||||
|
xhtml_cleaning = 0
|
||||||
|
admPanel = 0
|
||||||
|
debug = 0
|
||||||
|
no_cache = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 230 B |
@ -1 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#666" d="M12.053 11.026c-.238.07-.427.095-.674.095-2.033 0-5.017-7.1-5.017-9.462 0-.87.207-1.16.497-1.41C4.373.54 1.39 1.452.435 2.613c-.207.29-.332.746-.332 1.326C.103 7.628 4.04 16 6.82 16c1.283 0 3.45-2.114 5.233-4.974M10.756 0c2.57 0 5.14.415 5.14 1.865 0 2.943-1.865 6.508-2.818 6.508-1.7 0-3.814-4.725-3.814-7.088C9.264.207 9.68 0 10.756 0"/></svg>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||||
|
<path fill="#666" d="M12.053 11.026c-.238.07-.427.095-.674.095-2.033 0-5.017-7.1-5.017-9.462 0-.87.207-1.16.497-1.41C4.373.54 1.39 1.452.435 2.613c-.207.29-.332.746-.332 1.326C.103 7.628 4.04 16 6.82 16c1.283 0 3.45-2.114 5.233-4.974M10.756 0c2.57 0 5.14.415 5.14 1.865 0 2.943-1.865 6.508-2.818 6.508-1.7 0-3.814-4.725-3.814-7.088C9.264.207 9.68 0 10.756 0"></path>
|
||||||
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 426 B After Width: | Height: | Size: 476 B |
4
Resources/Public/Icons/user_plugin_translation.svg
Normal file
4
Resources/Public/Icons/user_plugin_translation.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||||
|
<path fill="#666" d="M12.053 11.026c-.238.07-.427.095-.674.095-2.033 0-5.017-7.1-5.017-9.462 0-.87.207-1.16.497-1.41C4.373.54 1.39 1.452.435 2.613c-.207.29-.332.746-.332 1.326C.103 7.628 4.04 16 6.82 16c1.283 0 3.45-2.114 5.233-4.974M10.756 0c2.57 0 5.14.415 5.14 1.865 0 2.943-1.865 6.508-2.818 6.508-1.7 0-3.814-4.725-3.814-7.088C9.264.207 9.68 0 10.756 0"></path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 476 B |
4
Resources/Public/Icons/user_plugin_translationplugin.svg
Normal file
4
Resources/Public/Icons/user_plugin_translationplugin.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
|
||||||
|
<path fill="#666" d="M12.053 11.026c-.238.07-.427.095-.674.095-2.033 0-5.017-7.1-5.017-9.462 0-.87.207-1.16.497-1.41C4.373.54 1.39 1.452.435 2.613c-.207.29-.332.746-.332 1.326C.103 7.628 4.04 16 6.82 16c1.283 0 3.45-2.114 5.233-4.974M10.756 0c2.57 0 5.14.415 5.14 1.865 0 2.943-1.865 6.508-2.818 6.508-1.7 0-3.814-4.725-3.814-7.088C9.264.207 9.68 0 10.756 0"></path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 476 B |
30
Tests/Unit/Controller/TranslationControllerTest.php
Normal file
30
Tests/Unit/Controller/TranslationControllerTest.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
namespace Cjel\TemplatesAide\Tests\Unit\Controller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case.
|
||||||
|
*
|
||||||
|
* @author Philipp Dieter <philippdieter@attic-media.net>
|
||||||
|
*/
|
||||||
|
class TranslationControllerTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Cjel\TemplatesAide\Controller\TranslationController
|
||||||
|
*/
|
||||||
|
protected $subject = null;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->subject = $this->getMockBuilder(\Cjel\TemplatesAide\Controller\TranslationController::class)
|
||||||
|
->setMethods(['redirect', 'forward', 'addFlashMessage'])
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
Tests/Unit/Domain/Model/TranslationTest.php
Normal file
34
Tests/Unit/Domain/Model/TranslationTest.php
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
namespace Cjel\TemplatesAide\Tests\Unit\Domain\Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case.
|
||||||
|
*
|
||||||
|
* @author Philipp Dieter <philippdieter@attic-media.net>
|
||||||
|
*/
|
||||||
|
class TranslationTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Cjel\TemplatesAide\Domain\Model\Translation
|
||||||
|
*/
|
||||||
|
protected $subject = null;
|
||||||
|
|
||||||
|
protected function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
$this->subject = new \Cjel\TemplatesAide\Domain\Model\Translation();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function tearDown()
|
||||||
|
{
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function dummyTestToNotLeaveThisFileEmpty()
|
||||||
|
{
|
||||||
|
self::markTestIncomplete();
|
||||||
|
}
|
||||||
|
}
|
@ -9,11 +9,26 @@ call_user_func(
|
|||||||
'Cjel.TemplatesAide',
|
'Cjel.TemplatesAide',
|
||||||
'Dummy',
|
'Dummy',
|
||||||
[
|
[
|
||||||
'Dummy' => 'list'
|
'Dummy' => 'list',
|
||||||
|
'Translation' => 'translations'
|
||||||
],
|
],
|
||||||
// non-cacheable actions
|
// non-cacheable actions
|
||||||
[
|
[
|
||||||
'Dummy' => ''
|
'Dummy' => '',
|
||||||
|
'Translation' => ''
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
|
||||||
|
'Cjel.TemplatesAide',
|
||||||
|
'Translationplugin',
|
||||||
|
[
|
||||||
|
'Translation' => 'translations'
|
||||||
|
],
|
||||||
|
// non-cacheable actions
|
||||||
|
[
|
||||||
|
'Dummy' => '',
|
||||||
|
'Translation' => ''
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -31,6 +46,15 @@ call_user_func(
|
|||||||
list_type = templatesaide_dummy
|
list_type = templatesaide_dummy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
translationplugin {
|
||||||
|
iconIdentifier = templates_aide-plugin-translationplugin
|
||||||
|
title = LLL:EXT:templates_aide/Resources/Private/Language/locallang_db.xlf:tx_templates_aide_translationplugin.name
|
||||||
|
description = LLL:EXT:templates_aide/Resources/Private/Language/locallang_db.xlf:tx_templates_aide_translationplugin.description
|
||||||
|
tt_content_defValues {
|
||||||
|
CType = list
|
||||||
|
list_type = templatesaide_translationplugin
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
show = *
|
show = *
|
||||||
}
|
}
|
||||||
@ -44,6 +68,12 @@ call_user_func(
|
|||||||
['source' => 'EXT:templates_aide/Resources/Public/Icons/user_plugin_dummy.svg']
|
['source' => 'EXT:templates_aide/Resources/Public/Icons/user_plugin_dummy.svg']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$iconRegistry->registerIcon(
|
||||||
|
'templates_aide-plugin-translationplugin',
|
||||||
|
\TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class,
|
||||||
|
['source' => 'EXT:templates_aide/Resources/Public/Icons/user_plugin_translationplugin.svg']
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
## EXTENSION BUILDER DEFAULTS END TOKEN - Everything BEFORE this line is overwritten with the defaults of the extension builder
|
## EXTENSION BUILDER DEFAULTS END TOKEN - Everything BEFORE this line is overwritten with the defaults of the extension builder
|
||||||
|
@ -11,11 +11,20 @@ call_user_func(
|
|||||||
'dummy'
|
'dummy'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
|
||||||
|
'Cjel.TemplatesAide',
|
||||||
|
'Translationplugin',
|
||||||
|
'translation'
|
||||||
|
);
|
||||||
|
|
||||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('templates_aide', 'Configuration/TypoScript', 'Templates Aide');
|
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('templates_aide', 'Configuration/TypoScript', 'Templates Aide');
|
||||||
|
|
||||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('tx_templatesaide_domain_model_dummy', 'EXT:templates_aide/Resources/Private/Language/locallang_csh_tx_templatesaide_domain_model_dummy.xlf');
|
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('tx_templatesaide_domain_model_dummy', 'EXT:templates_aide/Resources/Private/Language/locallang_csh_tx_templatesaide_domain_model_dummy.xlf');
|
||||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_templatesaide_domain_model_dummy');
|
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_templatesaide_domain_model_dummy');
|
||||||
|
|
||||||
|
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('tx_templatesaide_domain_model_translation', 'EXT:templates_aide/Resources/Private/Language/locallang_csh_tx_templatesaide_domain_model_translation.xlf');
|
||||||
|
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_templatesaide_domain_model_translation');
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
## EXTENSION BUILDER DEFAULTS END TOKEN - Everything BEFORE this line is overwritten with the defaults of the extension builder
|
## EXTENSION BUILDER DEFAULTS END TOKEN - Everything BEFORE this line is overwritten with the defaults of the extension builder
|
||||||
@ -75,4 +84,3 @@ $GLOBALS['TYPO3_USER_SETTINGS']['showitem'] = str_replace(
|
|||||||
'recursiveDelete,disableDragModal',
|
'recursiveDelete,disableDragModal',
|
||||||
$GLOBALS['TYPO3_USER_SETTINGS']['showitem'],
|
$GLOBALS['TYPO3_USER_SETTINGS']['showitem'],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
#
|
||||||
|
# Table structure for table 'tx_templatesaide_domain_model_dummy'
|
||||||
|
#
|
||||||
|
CREATE TABLE tx_templatesaide_domain_model_dummy (
|
||||||
|
|
||||||
|
uid int(11) NOT NULL auto_increment,
|
||||||
|
pid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
|
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
crdate int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
cruser_id int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
deleted smallint(5) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
hidden smallint(5) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
starttime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
endtime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
|
t3ver_oid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_id int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_label varchar(255) DEFAULT '' NOT NULL,
|
||||||
|
t3ver_state smallint(6) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_stage int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_count int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_move_id int(11) DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
|
sys_language_uid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
l10n_parent int(11) DEFAULT '0' NOT NULL,
|
||||||
|
l10n_diffsource mediumblob,
|
||||||
|
l10n_state text,
|
||||||
|
|
||||||
|
PRIMARY KEY (uid),
|
||||||
|
KEY parent (pid),
|
||||||
|
KEY t3ver_oid (t3ver_oid,t3ver_wsid),
|
||||||
|
KEY language (l10n_parent,sys_language_uid)
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
#
|
||||||
|
# Table structure for table 'tx_templatesaide_domain_model_translation'
|
||||||
|
#
|
||||||
|
CREATE TABLE tx_templatesaide_domain_model_translation (
|
||||||
|
|
||||||
|
uid int(11) NOT NULL auto_increment,
|
||||||
|
pid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
|
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
crdate int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
cruser_id int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
deleted smallint(5) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
hidden smallint(5) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
starttime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
endtime int(11) unsigned DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
|
t3ver_oid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_id int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_label varchar(255) DEFAULT '' NOT NULL,
|
||||||
|
t3ver_state smallint(6) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_stage int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_count int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
|
||||||
|
t3ver_move_id int(11) DEFAULT '0' NOT NULL,
|
||||||
|
|
||||||
|
sys_language_uid int(11) DEFAULT '0' NOT NULL,
|
||||||
|
l10n_parent int(11) DEFAULT '0' NOT NULL,
|
||||||
|
l10n_diffsource mediumblob,
|
||||||
|
l10n_state text,
|
||||||
|
|
||||||
|
PRIMARY KEY (uid),
|
||||||
|
KEY parent (pid),
|
||||||
|
KEY t3ver_oid (t3ver_oid,t3ver_wsid),
|
||||||
|
KEY language (l10n_parent,sys_language_uid)
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
## EXTENSION BUILDER DEFAULTS END TOKEN - Everything BEFORE this line is overwritten with the defaults of the extension builder
|
Loading…
x
Reference in New Issue
Block a user