Commit 2cba0bac authored by Richard Haeser's avatar Richard Haeser Committed by Benjamin Franzke
Browse files

[TASK] Set proper title of window in backend

With the introduction of the new backend module web component router,
the title of the backend windows will be set to the title of the
main iframe. Most of the modules didn't provide a proper name though.

For most modules we have a proper name now which will show up in the
title of the backend window, if no title is propagated by the module,
the backend router will fallback to the default backend title.

As the format of the title is quite "personal". If you are used to have
opened more TYPO3 backend windows, you would like to see which
installation you have open. If you only work in one backend, you
might want to see on which module you are currently working. It is
possible to set the order of the title of the backend within your
user settings now. By default it will be title - siteName [version]

Resolves: #94182
Releases: master
Change-Id: I02602650370140217aa252bbd8e29ea4e05d994a
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69172

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Jochen's avatarJochen <rothjochen@gmail.com>
Tested-by: Benjamin Franzke's avatarBenjamin Franzke <bfr@qbus.de>
Reviewed-by: Jochen's avatarJochen <rothjochen@gmail.com>
Reviewed-by: Benjamin Franzke's avatarBenjamin Franzke <bfr@qbus.de>
parent df3b793f
......@@ -17,7 +17,7 @@
export interface ModuleState {
url: string;
title?: string;
title?: string|null;
module?: string;
}
......
......@@ -67,7 +67,7 @@ export class IframeModuleElement extends LitElement {
public connectedCallback(): void {
super.connectedCallback();
if (this.endpoint) {
this.dispatch('typo3-iframe-load', { url: this.endpoint });
this.dispatch('typo3-iframe-load', { url: this.endpoint, title: null });
}
}
......@@ -89,7 +89,7 @@ export class IframeModuleElement extends LitElement {
};
} catch (e) {
console.error('Failed to access contentWindow of module iframe – using a foreign origin?');
return { url: this.endpoint };
return { url: this.endpoint, title: null };
}
}
......@@ -109,7 +109,7 @@ export class IframeModuleElement extends LitElement {
// the `unload` event is dispatched, but has not been changed right now.
new Promise((resolve) => window.setTimeout(resolve, 0)).then(() => {
if (iframe.contentWindow !== null) {
this.dispatch('typo3-iframe-load', { url: iframe.contentWindow.location.href });
this.dispatch('typo3-iframe-load', { url: iframe.contentWindow.location.href, title: null });
}
});
}
......
......@@ -41,6 +41,12 @@ export class ModuleRouter extends LitElement {
@property({type: String, attribute: 'state-tracker'})
stateTrackerUrl: string;
@property({type: String, attribute: 'sitename'})
sitename: string;
@property({type: Boolean, attribute: 'sitename-first'})
sitenameFirst: boolean;
@query('slot', true)
slotElement: HTMLSlotElement;
......@@ -187,6 +193,20 @@ export class ModuleRouter extends LitElement {
const url = new URL(state.url || '', window.location.origin);
const params = new URLSearchParams(url.search);
const title = 'title' in state ? state.title : '';
// update/reset document.title if state.title is not null
// (state.title === null indicates "keep current title")
if (title !== null) {
const titleComponents = [ this.sitename ];
if (title !== '') {
titleComponents.unshift(title);
}
if (this.sitenameFirst) {
titleComponents.reverse();
}
document.title = titleComponents.join(' · ');
}
if (!params.has('token')) {
// non token-urls (e.g. backend install tool) cannot be mapped by
// the main backend controller right now
......@@ -198,11 +218,6 @@ export class ModuleRouter extends LitElement {
const niceUrl = url.toString();
window.history.replaceState(state, '', niceUrl);
const title = state.title || null;
if (title) {
document.title = title;
}
}
}
......@@ -213,6 +213,8 @@ class BackendController
$typo3Version = 'TYPO3 CMS ' . $this->typo3Version->getVersion();
$title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . ' [' . $typo3Version . ']' : $typo3Version;
$moduleTemplate->setTitle($title);
$view->assign('sitename', $title);
$view->assign('sitenameFirstInBackendTitle', ($this->getBackendUser()->uc['backendTitleFormat'] ?? '') === 'sitenameFirst');
// Renders the backend scaffolding
$content = $moduleTemplate->renderContent();
......
......@@ -385,6 +385,8 @@ class EditDocumentController
{
$this->moduleTemplate = $this->moduleTemplateFactory->create($request);
$this->moduleTemplate->setUiBlock(true);
$this->moduleTemplate->setTitle($this->getShortcutTitle($request));
$this->getLanguageService()->includeLLFile('EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf');
// Unlock all locked records
......
......@@ -111,6 +111,7 @@ class HelpController
$this->registerDocheaderButtons($request);
$this->moduleTemplate->setTitle($this->getShortcutTitle($request));
$this->moduleTemplate->setContent($this->view->render());
return new HtmlResponse($this->moduleTemplate->renderContent());
}
......
......@@ -210,6 +210,11 @@ class PageLayoutController
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Recordlist/ClearCache');
$this->moduleTemplate->setTitle(
$this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'),
$this->pageinfo['title'] ?? ''
);
$this->main($request);
return new HtmlResponse($this->moduleTemplate->renderContent());
}
......
......@@ -108,7 +108,6 @@ class SiteConfigurationController
$this->siteFinder->getAllSites(false);
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
$this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Modal');
$this->moduleTemplate->setTitle($this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_siteconfiguration_module.xlf:mlang_labels_tablabel'));
$action = $request->getQueryParams()['action'] ?? $request->getParsedBody()['action'] ?? 'overview';
if (!in_array($action, self::ALLOWED_ACTIONS, true)) {
......@@ -147,6 +146,9 @@ class SiteConfigurationController
}
}
$this->moduleTemplate->setTitle(
$this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_siteconfiguration_module.xlf:mlang_tabs_tab')
);
$this->view->assignMultiple([
'pages' => $pages,
'unassignedSites' => $unassignedSites,
......@@ -214,6 +216,11 @@ class SiteConfigurationController
$this->view->assign('returnUrl', $returnUrl);
$this->view->assign('formEngineHtml', $formResult['html']);
$this->view->assign('formEngineFooter', $formResultCompiler->printNeededJSFunctions());
$this->moduleTemplate->setTitle(
$this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_siteconfiguration_module.xlf:mlang_tabs_tab'),
$siteIdentifier ?? ''
);
}
/**
......
......@@ -201,11 +201,18 @@ class ModuleTemplate
* Set title tag
*
* @param string $title
* @param string $context
* @return self
*/
public function setTitle($title): self
public function setTitle($title, $context = ''): self
{
$this->title = $title;
$titleComponents = [
$title
];
if ($context !== '') {
$titleComponents[] = $context;
}
$this->title = implode(' · ', $titleComponents);
return $this;
}
......
......@@ -64,6 +64,7 @@ class ModuleLayoutViewHelper extends AbstractViewHelper
{
parent::initializeArguments();
$this->registerArgument('name', 'string', 'Name of the module, defaults to the current plugin name, if available', false);
$this->registerArgument('title', 'string', 'Title of the module.', false);
}
public static function renderStatic(
......@@ -90,6 +91,9 @@ class ModuleLayoutViewHelper extends AbstractViewHelper
if (($arguments['name'] ?? null) !== null) {
$moduleTemplate->setModuleName($arguments['name']);
}
if (($arguments['title'] ?? null) !== null) {
$moduleTemplate->setTitle($arguments['title']);
}
$viewHelperVariableContainer->add(self::class, ModuleTemplate::class, $moduleTemplate);
$moduleTemplate->setContent($renderChildrenClosure());
......
......@@ -19,7 +19,7 @@
persistence-identifier="navigation.width"
></typo3-backend-navigation-switcher>
<div class="scaffold-content-module t3js-scaffold-content-module">
<typo3-backend-module-router module="{startupModule.0}" endpoint="{startupModule.1}" state-tracker="{stateTracker}"></typo3-backend-module-router>
<typo3-backend-module-router module="{startupModule.0}" endpoint="{startupModule.1}" state-tracker="{stateTracker}" sitename="{sitename}"{f:if(condition: sitenameFirstInBackendTitle, then: ' sitename-first')}></typo3-backend-module-router>
</div>
<div class="scaffold-content-overlay t3js-scaffold-content-overlay"></div>
</div>
......@@ -10,7 +10,7 @@
*
* The TYPO3 project - inspiring people to share!
*/
var __decorate=this&&this.__decorate||function(e,t,o,n){var r,i=arguments.length,a=i<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,o):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,o,n);else for(var l=e.length-1;l>=0;l--)(r=e[l])&&(a=(i<3?r(a):i>3?r(t,o,a):r(t,o))||a);return i>3&&a&&Object.defineProperty(t,o,a),a};define(["require","exports","lit","lit/decorators","TYPO3/CMS/Core/lit-helper"],(function(e,t,o,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.IframeModuleElement=t.componentName=void 0,t.componentName="typo3-iframe-module";let i=class extends o.LitElement{constructor(){super(...arguments),this.endpoint=""}createRenderRoot(){return this}render(){return this.endpoint?o.html`
var __decorate=this&&this.__decorate||function(e,t,o,n){var r,i=arguments.length,l=i<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,o):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)l=Reflect.decorate(e,t,o,n);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(l=(i<3?r(l):i>3?r(t,o,l):r(t,o))||l);return i>3&&l&&Object.defineProperty(t,o,l),l};define(["require","exports","lit","lit/decorators","TYPO3/CMS/Core/lit-helper"],(function(e,t,o,n,r){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.IframeModuleElement=t.componentName=void 0,t.componentName="typo3-iframe-module";let i=class extends o.LitElement{constructor(){super(...arguments),this.endpoint=""}createRenderRoot(){return this}render(){return this.endpoint?o.html`
<iframe
src="${this.endpoint}"
name="list_frame"
......@@ -20,4 +20,4 @@ var __decorate=this&&this.__decorate||function(e,t,o,n){var r,i=arguments.length
scrolling="no"
@load="${this._loaded}"
></iframe>
`:o.html``}attributeChangedCallback(e,t,o){super.attributeChangedCallback(e,t,o),"endpoint"===e&&o===t&&this.iframe.setAttribute("src",o)}connectedCallback(){super.connectedCallback(),this.endpoint&&this.dispatch("typo3-iframe-load",{url:this.endpoint})}registerUnloadHandler(e){try{e.contentWindow.addEventListener("unload",t=>this._unload(t,e),{once:!0})}catch(e){throw console.error("Failed to access contentWindow of module iframe – using a foreign origin?"),e}}retrieveModuleStateFromIFrame(e){var t;try{return{url:e.contentWindow.location.href,title:e.contentDocument.title,module:null===(t=e.contentDocument.body.querySelector(".module[data-module-name]"))||void 0===t?void 0:t.getAttribute("data-module-name")}}catch(e){return console.error("Failed to access contentWindow of module iframe – using a foreign origin?"),{url:this.endpoint}}}_loaded({target:e}){const t=e;this.registerUnloadHandler(t);const o=this.retrieveModuleStateFromIFrame(t);this.dispatch("typo3-iframe-loaded",o)}_unload(e,t){new Promise(e=>window.setTimeout(e,0)).then(()=>{null!==t.contentWindow&&this.dispatch("typo3-iframe-load",{url:t.contentWindow.location.href})})}dispatch(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}};__decorate([n.property({type:String})],i.prototype,"endpoint",void 0),__decorate([n.query("iframe",!0)],i.prototype,"iframe",void 0),i=__decorate([n.customElement(t.componentName)],i),t.IframeModuleElement=i}));
\ No newline at end of file
`:o.html``}attributeChangedCallback(e,t,o){super.attributeChangedCallback(e,t,o),"endpoint"===e&&o===t&&this.iframe.setAttribute("src",o)}connectedCallback(){super.connectedCallback(),this.endpoint&&this.dispatch("typo3-iframe-load",{url:this.endpoint,title:null})}registerUnloadHandler(e){try{e.contentWindow.addEventListener("unload",t=>this._unload(t,e),{once:!0})}catch(e){throw console.error("Failed to access contentWindow of module iframe – using a foreign origin?"),e}}retrieveModuleStateFromIFrame(e){var t;try{return{url:e.contentWindow.location.href,title:e.contentDocument.title,module:null===(t=e.contentDocument.body.querySelector(".module[data-module-name]"))||void 0===t?void 0:t.getAttribute("data-module-name")}}catch(e){return console.error("Failed to access contentWindow of module iframe – using a foreign origin?"),{url:this.endpoint,title:null}}}_loaded({target:e}){const t=e;this.registerUnloadHandler(t);const o=this.retrieveModuleStateFromIFrame(t);this.dispatch("typo3-iframe-loaded",o)}_unload(e,t){new Promise(e=>window.setTimeout(e,0)).then(()=>{null!==t.contentWindow&&this.dispatch("typo3-iframe-load",{url:t.contentWindow.location.href,title:null})})}dispatch(e,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}};__decorate([n.property({type:String})],i.prototype,"endpoint",void 0),__decorate([n.query("iframe",!0)],i.prototype,"iframe",void 0),i=__decorate([n.customElement(t.componentName)],i),t.IframeModuleElement=i}));
\ No newline at end of file
......@@ -10,7 +10,7 @@
*
* The TYPO3 project - inspiring people to share!
*/
var __createBinding=this&&this.__createBinding||(Object.create?function(t,e,o,r){void 0===r&&(r=o),Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[o]}})}:function(t,e,o,r){void 0===r&&(r=o),t[r]=e[o]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),__decorate=this&&this.__decorate||function(t,e,o,r){var i,n=arguments.length,a=n<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,o,r);else for(var l=t.length-1;l>=0;l--)(i=t[l])&&(a=(n<3?i(a):n>3?i(e,o,a):i(e,o))||a);return n>3&&a&&Object.defineProperty(e,o,a),a},__importStar=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var o in t)"default"!==o&&Object.prototype.hasOwnProperty.call(t,o)&&__createBinding(e,t,o);return __setModuleDefault(e,t),e};define(["require","exports","lit","lit/decorators","../Module"],(function(t,e,o,r,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ModuleRouter=void 0;const n="TYPO3/CMS/Backend/Module/Iframe",a=(t,e)=>!0;let l=class extends o.LitElement{constructor(){super(),this.module="",this.endpoint="",this.addEventListener("typo3-module-load",({target:t,detail:e})=>{const o=t.getAttribute("slot");this.pushState({slotName:o,detail:e})}),this.addEventListener("typo3-module-loaded",({detail:t})=>{this.updateBrowserState(t)}),this.addEventListener("typo3-iframe-load",({detail:t})=>{let e={slotName:n,detail:t};if(e.detail.url.includes(this.stateTrackerUrl+"?state=")){const t=e.detail.url.split("?state=");e=JSON.parse(decodeURIComponent(t[1]||"{}"))}this.slotElement.getAttribute("name")!==e.slotName&&this.slotElement.setAttribute("name",e.slotName),this.markActive(e.slotName,this.slotElement.getAttribute("name")===n?null:e.detail.url,!1),this.updateBrowserState(e.detail),this.parentElement.dispatchEvent(new CustomEvent("typo3-module-load",{bubbles:!0,composed:!0,detail:e.detail}))}),this.addEventListener("typo3-iframe-loaded",({detail:t})=>{this.updateBrowserState(t),this.parentElement.dispatchEvent(new CustomEvent("typo3-module-loaded",{bubbles:!0,composed:!0,detail:t}))})}render(){const t=i.getRecordFromName(this.module).component||n;return o.html`<slot name="${t}"></slot>`}updated(){const t=i.getRecordFromName(this.module).component||n;this.markActive(t,this.endpoint)}async markActive(t,e,o=!0){const r=await this.getModuleElement(t);e&&(o||r.getAttribute("endpoint")!==e)&&r.setAttribute("endpoint",e),r.hasAttribute("active")||r.setAttribute("active","");for(let t=r.previousElementSibling;null!==t;t=t.previousElementSibling)t.removeAttribute("active");for(let t=r.nextElementSibling;null!==t;t=t.nextElementSibling)t.removeAttribute("active")}async getModuleElement(e){let o=this.querySelector(`*[slot="${e}"]`);if(null!==o)return o;try{const r=await new Promise((o,r)=>{t([e],o,r)}).then(__importStar);o=document.createElement(r.componentName)}catch(t){throw console.error({msg:`Error importing ${e} as backend module`,err:t}),t}return o.setAttribute("slot",e),this.appendChild(o),o}async pushState(t){const e=this.stateTrackerUrl+"?state="+encodeURIComponent(JSON.stringify(t));(await this.getModuleElement(n)).setAttribute("endpoint",e)}updateBrowserState(t){const e=new URL(t.url||"",window.location.origin),o=new URLSearchParams(e.search);if(!o.has("token"))return;o.delete("token"),e.search=o.toString();const r=e.toString();window.history.replaceState(t,"",r);const i=t.title||null;i&&(document.title=i)}};l.styles=o.css`
var __createBinding=this&&this.__createBinding||(Object.create?function(t,e,o,r){void 0===r&&(r=o),Object.defineProperty(t,r,{enumerable:!0,get:function(){return e[o]}})}:function(t,e,o,r){void 0===r&&(r=o),t[r]=e[o]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}:function(t,e){t.default=e}),__decorate=this&&this.__decorate||function(t,e,o,r){var i,n=arguments.length,a=n<3?e:null===r?r=Object.getOwnPropertyDescriptor(e,o):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(t,e,o,r);else for(var s=t.length-1;s>=0;s--)(i=t[s])&&(a=(n<3?i(a):n>3?i(e,o,a):i(e,o))||a);return n>3&&a&&Object.defineProperty(e,o,a),a},__importStar=this&&this.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(null!=t)for(var o in t)"default"!==o&&Object.prototype.hasOwnProperty.call(t,o)&&__createBinding(e,t,o);return __setModuleDefault(e,t),e};define(["require","exports","lit","lit/decorators","../Module"],(function(t,e,o,r,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.ModuleRouter=void 0;const n="TYPO3/CMS/Backend/Module/Iframe",a=(t,e)=>!0;let s=class extends o.LitElement{constructor(){super(),this.module="",this.endpoint="",this.addEventListener("typo3-module-load",({target:t,detail:e})=>{const o=t.getAttribute("slot");this.pushState({slotName:o,detail:e})}),this.addEventListener("typo3-module-loaded",({detail:t})=>{this.updateBrowserState(t)}),this.addEventListener("typo3-iframe-load",({detail:t})=>{let e={slotName:n,detail:t};if(e.detail.url.includes(this.stateTrackerUrl+"?state=")){const t=e.detail.url.split("?state=");e=JSON.parse(decodeURIComponent(t[1]||"{}"))}this.slotElement.getAttribute("name")!==e.slotName&&this.slotElement.setAttribute("name",e.slotName),this.markActive(e.slotName,this.slotElement.getAttribute("name")===n?null:e.detail.url,!1),this.updateBrowserState(e.detail),this.parentElement.dispatchEvent(new CustomEvent("typo3-module-load",{bubbles:!0,composed:!0,detail:e.detail}))}),this.addEventListener("typo3-iframe-loaded",({detail:t})=>{this.updateBrowserState(t),this.parentElement.dispatchEvent(new CustomEvent("typo3-module-loaded",{bubbles:!0,composed:!0,detail:t}))})}render(){const t=i.getRecordFromName(this.module).component||n;return o.html`<slot name="${t}"></slot>`}updated(){const t=i.getRecordFromName(this.module).component||n;this.markActive(t,this.endpoint)}async markActive(t,e,o=!0){const r=await this.getModuleElement(t);e&&(o||r.getAttribute("endpoint")!==e)&&r.setAttribute("endpoint",e),r.hasAttribute("active")||r.setAttribute("active","");for(let t=r.previousElementSibling;null!==t;t=t.previousElementSibling)t.removeAttribute("active");for(let t=r.nextElementSibling;null!==t;t=t.nextElementSibling)t.removeAttribute("active")}async getModuleElement(e){let o=this.querySelector(`*[slot="${e}"]`);if(null!==o)return o;try{const r=await new Promise((o,r)=>{t([e],o,r)}).then(__importStar);o=document.createElement(r.componentName)}catch(t){throw console.error({msg:`Error importing ${e} as backend module`,err:t}),t}return o.setAttribute("slot",e),this.appendChild(o),o}async pushState(t){const e=this.stateTrackerUrl+"?state="+encodeURIComponent(JSON.stringify(t));(await this.getModuleElement(n)).setAttribute("endpoint",e)}updateBrowserState(t){const e=new URL(t.url||"",window.location.origin),o=new URLSearchParams(e.search),r="title"in t?t.title:"";if(null!==r){const t=[this.sitename];""!==r&&t.unshift(r),this.sitenameFirst&&t.reverse(),document.title=t.join(" · ")}if(!o.has("token"))return;o.delete("token"),e.search=o.toString();const i=e.toString();window.history.replaceState(t,"",i)}};s.styles=o.css`
:host {
width: 100%;
min-height: 100%;
......@@ -22,4 +22,4 @@ var __createBinding=this&&this.__createBinding||(Object.create?function(t,e,o,r)
min-height: 100%;
width: 100%;
}
`,__decorate([r.property({type:String,hasChanged:a})],l.prototype,"module",void 0),__decorate([r.property({type:String,hasChanged:a})],l.prototype,"endpoint",void 0),__decorate([r.property({type:String,attribute:"state-tracker"})],l.prototype,"stateTrackerUrl",void 0),__decorate([r.query("slot",!0)],l.prototype,"slotElement",void 0),l=__decorate([r.customElement("typo3-backend-module-router")],l),e.ModuleRouter=l}));
\ No newline at end of file
`,__decorate([r.property({type:String,hasChanged:a})],s.prototype,"module",void 0),__decorate([r.property({type:String,hasChanged:a})],s.prototype,"endpoint",void 0),__decorate([r.property({type:String,attribute:"state-tracker"})],s.prototype,"stateTrackerUrl",void 0),__decorate([r.property({type:String,attribute:"sitename"})],s.prototype,"sitename",void 0),__decorate([r.property({type:Boolean,attribute:"sitename-first"})],s.prototype,"sitenameFirst",void 0),__decorate([r.query("slot",!0)],s.prototype,"slotElement",void 0),s=__decorate([r.customElement("typo3-backend-module-router")],s),e.ModuleRouter=s}));
\ No newline at end of file
......@@ -3,7 +3,7 @@
xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
data-namespace-typo3-fluid="true">
<be:moduleLayout>
<be:moduleLayout title="{f:translate(key: 'LLL:EXT:belog/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab')}">
<f:render section="Content" />
</be:moduleLayout>
......
......@@ -246,6 +246,11 @@ class PermissionController extends ActionController
}
$tree->getTree($this->id, $this->depth);
$this->view->assign('viewTree', $tree->tree);
$this->view->getModuleTemplate()->setTitle(
$this->getLanguageService()->sL('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:permissions'),
$this->id !== 0 && isset($this->pageInfo['title']) ? $this->pageInfo['title'] : ''
);
}
/**
......
......@@ -3,7 +3,7 @@
xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers"
data-namespace-typo3-fluid="true">
<be:moduleLayout>
<be:moduleLayout title="{f:translate(key: 'LLL:EXT:beuser/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab')}">
<f:be.pageRenderer
includeRequireJsModules="{
0:'TYPO3/CMS/Backend/ContextMenu',
......
......@@ -91,6 +91,11 @@ class DashboardController extends AbstractController
*/
public function mainAction(): void
{
$this->moduleTemplate->setTitle(
$this->getLanguageService()->sL('LLL:EXT:dashboard/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'),
$this->currentDashboard->getTitle()
);
$this->view->assignMultiple([
'availableDashboards' => $this->dashboardInitializationService->getDashboardsForUser(),
'dashboardPresets' => $this->dashboardPresetRepository->getDashboardPresets(),
......
......@@ -108,6 +108,12 @@ class AbstractModuleController extends AbstractController
->setHref($this->uriBuilder->reset()->uriFor($menuItemConfig['action'], [], $menuItemConfig['controller']))
->setActive($isActive);
$menu->addMenuItem($menuItem);
if ($isActive) {
$this->view->getModuleTemplate()->setTitle(
$this->translate('LLL:EXT:extensionmanager/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'),
$menuItemConfig['label']
);
}
}
$this->view->getModuleTemplate()->getDocHeaderComponent()->getMenuRegistry()->addMenu($menu);
......
......@@ -479,6 +479,10 @@ class FileListController extends ActionController implements LoggerAwareInterfac
$this->view->assign('maxFileSize', GeneralUtility::getMaxUploadFileSize() * 1024);
$this->view->assign('defaultAction', $this->getDefaultAction());
$this->buildListOptionCheckboxes();
$this->view->getModuleTemplate()->setTitle(
$this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:mlang_tabs_tab'),
$this->getModuleHeadline()
);
} else {
return new ForwardResponse('missingFolder');
}
......
......@@ -137,6 +137,12 @@ class FormEditorController extends AbstractBackendController
$addInlineSettings,
$this->prototypeConfiguration['formEditor']['addInlineSettings']
);
$this->view->getModuleTemplate()->setTitle(
$this->getLanguageService()->sL('LLL:EXT:form/Resources/Private/Language/locallang_module.xlf:mlang_tabs_tab'),
$formDefinition['label']
);
$this->view->assign('addInlineSettings', $addInlineSettings);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment