[FEATURE] Speed-up Backend with CardLayout
authorKay Strobach <typo3@kay-strobach.de>
Fri, 15 Jul 2011 18:03:26 +0000 (20:03 +0200)
committerXavier Perseguers <typo3@perseguers.ch>
Wed, 27 Jul 2011 13:45:42 +0000 (15:45 +0200)
This patch adds a cardlayout to the Backend.
BE Modules may register themselves to the page renderer and add cards
directly to the layout.

To achieve that, a new way of adding JavaScript to the BE is available.
$GLOBALS['TBE_MODULES']['_JSINIT']['key'] = 'JSCODE';

This way changing the module is quite fast.

To keep old behaviour the iframe is loaded with the module root
url if the module item of an already opened module is clicked.

The Extension Manager or the About module can be simply reworked to support
that feature.

Other new features like the dashboard depend on this change too.

API hints:

JavaScript
 - in old times we used:
   TYPO3.Backend.ContentContainer.setUrl(uri);

   Now please use
   TYPO3.ModuleMenu.App.openInContentFrame(uri, params);
   The "new" function was available before and knows the current
   module. This function uses the correct iframe - if it is allowed to
   load the module.

PHP
 - added new Parameter to t3lib_extMgm::addModule to disable the card
   autocreation on demand

Change-Id: I2bf206b7154c20575b0d2ce72150621b2dfbdb35
Resolves: #12664
Releases: 4.6, 4.5
Reviewed-on: http://review.typo3.org/3370
Reviewed-by: Philipp Gampe
Tested-by: Philipp Gampe
Tested-by: Soren Malling
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
t3lib/class.t3lib_extmgm.php
t3lib/js/extjs/components/pagetree/javascript/actions.js
typo3/backend.php
typo3/js/extjs/iframepanel.js
typo3/js/extjs/viewportConfiguration.js
typo3/js/modulemenu.js

index c07f335..1f08af8 100644 (file)
@@ -774,9 +774,10 @@ final class t3lib_extMgm {
         * @param       string          $sub is the submodule key. If $sub is not set a blank $main module is created.
         * @param       string          $position can be used to set the position of the $sub module within the list of existing submodules for the main module. $position has this syntax: [cmd]:[submodule-key]. cmd can be "after", "before" or "top" (or blank which is default). If "after"/"before" then submodule will be inserted after/before the existing submodule with [submodule-key] if found. If not found, the bottom of list. If "top" the module is inserted in the top of the submodule list.
         * @param       string          $path is the absolute path to the module. If this value is defined the path is added as an entry in $TBE_MODULES['_PATHS'][  main_sub  ] = $path; and thereby tells the backend where the newly added modules is found in the system.
+        * @param       boolean         $addJsAutomatically adds automatically the card for this module the TYPO3 BE - if you use ExtJS you may disable this option
         * @return      void
         */
-       public static function addModule($main, $sub = '', $position = '', $path = '') {
+       public static function addModule($main, $sub = '', $position = '', $path = '', $addJsAutomatically = TRUE) {
                if (isset($GLOBALS['TBE_MODULES'][$main]) && $sub) {
                        // if there is already a main module by this name:
 
@@ -825,6 +826,15 @@ final class t3lib_extMgm {
                        // Adding path:
                if ($path) {
                        $GLOBALS['TBE_MODULES']['_PATHS'][$main . ($sub ? '_' . $sub : '')] = $path;
+                       if ($addJsAutomatically) {
+                               $GLOBALS['TBE_MODULES']['_JSINIT'][$main . ($sub ? '_' . $sub : '')]  = '
+                                       TYPO3.Viewport.ContentCards.addContentCard("' . $main . ($sub ? '_' . $sub : '') . '",
+                                               {
+                                                       xtype: "iframePanel"
+                                               }
+                                       );
+                               ';
+                       }
                }
        }
 
@@ -1707,4 +1717,4 @@ $GLOBALS[\'TYPO3_LOADED_EXT\'] = unserialize(stripslashes(\'' . addslashes(seria
        }
 }
 
-?>
\ No newline at end of file
+?>
index 1dbb5b0..b831603 100644 (file)
@@ -703,8 +703,8 @@ TYPO3.Components.PageTree.Actions = {
 
                fsMod.recentIds['web'] = node.attributes.nodeData.id;
 
-               TYPO3.Backend.ContentContainer.setUrl(
-                       TS.PATH_typo3 + currentSubScript + separator + 'id=' + node.attributes.nodeData.id
+               TYPO3.ModuleMenu.App.openInContentFrame(
+                       currentSubScript + separator + 'id=' + node.attributes.nodeData.id
                );
        },
 
index b13cb28..334a529 100644 (file)
@@ -153,6 +153,13 @@ class TYPO3backend {
                }
 
                $this->executeHook('constructPostProcess');
+
+                       // Add previously generated JS to the backend
+               if (is_array($GLOBALS['TBE_MODULES']['_JSINIT'])) {
+                       foreach ($GLOBALS['TBE_MODULES']['_JSINIT'] as $value) {
+                               $this->js .= $value;
+                       }
+               }
        }
 
        /**
index ccd968a..db27083 100644 (file)
@@ -39,7 +39,7 @@ TYPO3.iframePanel = Ext.extend(Ext.Panel, {
        src: Ext.isIE && Ext.isSecure ? Ext.SSL_SECURE_URL : 'about:blank',
        maskMessage: ' ',
        doMask: true,
-
+       border: false,
                // component build
        initComponent: function() {
                this.bodyCfg = {
@@ -81,8 +81,36 @@ TYPO3.iframePanel = Ext.extend(Ext.Panel, {
        setUrl: function(source) {
                this.setMask();
                this.body.dom.src = source;
+               if (this.ownerCt) {
+                       if (this.ownerCt.hasLayout) {
+                               if (this.ownerCt.layout.setActiveItem) {
+                                       this.ownerCt.layout.setActiveItem(this.id);
+                               }
+                       }
+               }
        },
+       setUrlIfChanged: function(source) {
+               currentSource = this.getUrl();
+               currentSource = currentSource.substr(currentSource.length-source.length);
+
+                       // Some modules generate wrong url with unneeded string at the end
+               if (currentSource.substr(currentSource.length-1) == '?' ||
+                       currentSource.substr(currentSource.length-1) == '&') {
+                       currentSource = currentSource.substr(0,currentSource.length)
+               }
+               if (currentSource.substr(0,1) == '/') {
+                       currentSource = currentSource.substr(1);
+               }
+               if (source.substr(source.length-1) == '?' ||
+                       source.substr(source.length-1) == '&') {
+                       source = source.substr(0,source.length-1)
+               }
 
+                       // Check if new uri should be loaded
+               if (source != currentSource) {
+                       this.setUrl(source);
+               }
+       },
        resetUrl: function() {
                this.setMask();
                this.body.dom.src = this.src;
index 7bda328..c3b9d9c 100644 (file)
  ***************************************************************/
 
 Ext.ns('TYPO3');
+Ext.ns('TYPO3.Viewport.Panels');
+
+/**
+ * The Cards Configuration for the BE Module Cards
+ *
+ *
+ * @author Kay Strobach    <typo3@kay-strobach.de>
+ */
+
+TYPO3.Viewport.ContentCards = {
+       /**
+        * Add a card to either the config or if already rendered to the wrapper
+        */
+       addContentCard: function(name,config) {
+               config.id='typo3-card-'+name;
+               if (Ext.ready) {
+                       Ext.getCmp('typo3-contentContainerWrapper').add(config);
+               } else {
+                       this.cards.push(config);
+               }
+       },
+       cards:[
+               {
+                       id: 'typo3-contentContainer',
+                       border: false,
+                       xtype: 'iframePanel',
+                       name: 'content'
+               }
+               /**
+                * New items need to be appended here
+                * cards id needs to be prepended with typo3-card- the rest of the id is the
+                * be module name as passed it is normally in TYPO3
+                *
+                * Example for the EM:
+                *
+                *{
+                *      xtype: 'iframePanel',
+                *      src: 'mod.php?M=tools_em',
+                *      id: 'typo3-card-tools_em'
+                *}
+                *
+                */
+       ]
+};
 
 /**
  * The backend viewport configuration
  *
  * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @author Kay Strobach    <typo3@kay-strobach.de>
  */
+
+
 TYPO3.Viewport.configuration = {
        layout: 'border',
        id: 'typo3-viewport',
@@ -49,15 +96,12 @@ TYPO3.Viewport.configuration = {
                        layout: 'fit',
                        region: 'west',
                        id: 'typo3-module-menu',
-                       collapsible: false,
-                       collapseMode: null,
                        floatable: true,
                        hideCollapseTool: true,
                        split: true,
                        useSplitTips: true,
                        splitTip: top.TYPO3.LLL.viewPort.tooltipModuleMenuSplit,
                        enableChildSplit: true,
-                       border: false,
                        autoScroll: true
                },
                {
@@ -105,16 +149,15 @@ TYPO3.Viewport.configuration = {
                                                        border: false,
                                                        hidden: true,
                                                        floatable: true,
-                                                       xtime: 'iframePanel',
+                                                       xtype: 'iframePanel',
                                                        width: 5
                                                },
                                                {
-                                                       id: 'typo3-contentContainer',
+                                                       id: 'typo3-contentContainerWrapper',
+                                                       layout: 'card',
                                                        region: 'center',
-                                                       anchor: '100% 100%',
-                                                       border: false,
-                                                       xtype: 'iframePanel',
-                                                       name: 'content'
+                                                       activeItem: 0,
+                                                       items: TYPO3.Viewport.ContentCards.cards
                                                }
                                        ]
                                },
index 3ea88d9..ce02b24 100644 (file)
@@ -238,7 +238,22 @@ TYPO3.ModuleMenu.App = {
                                TYPO3.Backend.NavigationContainer.hide();
                                TYPO3.Backend.NavigationDummy.show();
                        }
-                       this.openInContentFrame(record.originalLink, params);
+                       if (Ext.getCmp('typo3-card-' + record.name)) {
+                                       // Check wether the panel is an iframe or not - if it is try to set the uri
+                               if (Ext.getCmp('typo3-card-' + record.name).getXType() == 'iframePanel') {
+                                               // Handle click on already opened module and evt. force reload
+                                       if (Ext.getCmp('typo3-contentContainerWrapper').layout.activeItem.id == 'typo3-card-' + record.name) {
+                                               Ext.getCmp('typo3-card-'+record.name).setUrl(url + (params ? (url.indexOf('?') !== -1 ? '&' : '?') + params : ''));
+                                       } else {
+                                               url = record.originalLink;
+                                               Ext.getCmp('typo3-card-'+record.name).setUrlIfChanged(url + (params ? (url.indexOf('?') !== -1 ? '&' : '?') + params : ''));
+                                       }
+                               }
+                                       // Independed of the xtype activate the module
+                               Ext.getCmp('typo3-contentContainerWrapper').layout.setActiveItem('typo3-card-' + record.name);
+                       } else {
+                               this.openInContentFrame(record.originalLink, params);
+                       }
                        this.loadedModule = mod;
                        this.highlightModuleMenuItem(mod);
 
@@ -287,7 +302,7 @@ TYPO3.ModuleMenu.App = {
 
                        // backwards compatibility
                top.nav = component;
-               
+
                TYPO3.Backend.NavigationContainer.show();
                this.loadedNavigationComponentId = navigationComponentId;
        },
@@ -306,10 +321,22 @@ TYPO3.ModuleMenu.App = {
 
        openInContentFrame: function(url, params) {
                if (top.nextLoadModuleUrl) {
-                       TYPO3.Backend.ContentContainer.setUrl(top.nextLoadModuleUrl);
+                       urlToLoad = top.nextLoadModuleUrl;
                        top.nextLoadModuleUrl = '';
                } else {
-                       TYPO3.Backend.ContentContainer.setUrl(url + (params ? (url.indexOf('?') !== -1 ? '&' : '?') + params : ''));
+                       urlToLoad = url + (params ? (url.indexOf('?') !== -1 ? '&' : '?') + params : '');
+               }
+                       // Make shourtcut to card
+               relatedCard = Ext.getCmp('typo3-contentContainerWrapper').get('typo3-card-' + this.loadedModule);
+                       // Decide where to load module, either in card or compatibility card
+               if (relatedCard) {
+                       if (relatedCard.getXType() == 'iframePanel') {
+                               relatedCard.setUrlIfChanged(urlToLoad);
+                       }
+                       Ext.getCmp('typo3-contentContainerWrapper').layout.setActiveItem('typo3-card-' + this.loadedModule);
+               } else {
+                       TYPO3.Backend.ContentContainer.setUrl(urlToLoad);
+                       Ext.getCmp('typo3-contentContainerWrapper').layout.setActiveItem(0);
                }
        },