Fixed bug #15686: Call the list module through the dispatcher instead directly (Thank...
[Packages/TYPO3.CMS.git] / typo3 / template.php
index 5c823e2..2f15932 100644 (file)
@@ -169,6 +169,7 @@ class template {
        var $postCode='';                               // Additional 'page-end' code could be accommulated in this var. It will be outputted at the end of page before </body> and some other internal page-end code.
        var $docType = '';                              // Doc-type used in the header. Default is xhtml_trans. You can also set it to 'html_3', 'xhtml_strict' or 'xhtml_frames'.
        var $moduleTemplate = '';               // HTML template with markers for module
+       protected $moduleTemplateFilename = ''; // the base file (not overlaid by TBE_STYLES) for the current module, useful for hooks when finding out which modules is rendered currently
 
                // Other vars you can change, but less frequently used:
        var $scriptID='';                               // Script ID.
@@ -215,6 +216,14 @@ class template {
                'visual' => 'stylesheets/visual/',
        );
 
+       /**
+        * JavaScript files loaded for every page in the Backend
+        * @var array
+        */
+       protected $jsFiles = array(
+               'modernizr' => 'contrib/modernizr/modernizr.min.js',
+       );
+
                // DEV:
        var $parseTimeFlag = 0;                 // Will output the parsetime of the scripts in milliseconds (for admin-users). Set this to false when releasing TYPO3. Only for dev.
 
@@ -314,6 +323,11 @@ class template {
                        $this->pageRenderer->enableConcatenateFiles();
                        $this->pageRenderer->enableCompressCss();
                        $this->pageRenderer->enableCompressJavascript();
+
+                               // add all JavaScript files defined in $this->jsFiles to the PageRenderer
+                       foreach ($this->jsFiles as $file) {
+                               $this->pageRenderer->addJsFile($GLOBALS['BACK_PATH'] . $file);
+                       }
                }
                if (intval($GLOBALS['TYPO3_CONF_VARS']['BE']['debug']) === 1) {
                        $this->pageRenderer->enableDebugMode();
@@ -373,12 +387,13 @@ class template {
         */
        function viewPageIcon($id,$backPath,$addParams='hspace="3"')    {
                global $BE_USER;
-               $str = '';
                        // If access to Web>List for user, then link to that module.
-               $str .= t3lib_extMgm::createListViewLink(
-                       $id,
-                       '&returnUrl=' . rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')),
-                       $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showList', TRUE)
+               $str = t3lib_BEfunc::getListViewLink(
+                       array(
+                               'id' => $id,
+                               'returnUrl' => t3lib_div::getIndpEnv('REQUEST_URI'),
+                       ),
+                       $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.showList')
                );
 
                        // Make link to view page
@@ -511,13 +526,13 @@ class template {
                } else $mMN='';
 
                $onClick = 'top.ShortcutManager.createShortcut('
-                       .$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeShortcut')).', '
+                       .$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeBookmark')).', '
                        .'\''.$backPath.'\', '
                        .'\''.rawurlencode($modName).'\', '
                        .'\''.rawurlencode($pathInfo['path']."?".$storeUrl).$mMN.'\''
                .');return false;';
 
-               $sIcon = '<a href="#" onclick="' . htmlspecialchars($onClick).'" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeShortcut', TRUE) . '">'
+               $sIcon = '<a href="#" onclick="' . htmlspecialchars($onClick).'" title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeBookmark', TRUE) . '">'
                        . t3lib_iconworks::getSpriteIcon('actions-system-shortcut-new') . '</a>';
                return $sIcon;
        }
@@ -676,10 +691,11 @@ class template {
         * This includes the proper header with charset, title, meta tag and beginning body-tag.
         *
         * @param       string          HTML Page title for the header
+        * @param       boolean         flag for including CSH
         * @return      string          Returns the whole header section of a HTML-document based on settings in internal variables (like styles, javascript code, charset, generator and docType)
         * @see endPage()
         */
-       function startPage($title)      {
+       function startPage($title, $includeCsh = TRUE) {
                        // hook pre start page
                if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preStartPageHook'])) {
                        $preStartPageHook =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preStartPageHook'];
@@ -729,18 +745,18 @@ class template {
        PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
                                break;
+                       case 'xhtml_trans':
+                               $headerStart = '<!DOCTYPE html
+     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
+                               // The fallthrough is intended as HTML5, as this is the default for the BE since TYPO3 4.5
                        case 'html_5':
+                       default:
                                $headerStart = '<!DOCTYPE html>' . LF;
                                $htmlTag = '<html>';
                                // disable rendering of XHTML tags
                                $this->getPageRenderer()->setRenderXhtml(FALSE);
                                break;
-                               // The fallthrough is intended as XHTML 1.0 transitional is the default for the BE.
-                       case 'xhtml_trans':
-                       default:
-                               $headerStart = '<!DOCTYPE html
-     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
                }
 
                $this->pageRenderer->setHtmlTag($htmlTag);
@@ -752,7 +768,9 @@ class template {
                }
 
                        // include the JS for the Context Sensitive Help
-               $this->loadCshJavascript();
+               if ($includeCsh) {
+                       $this->loadCshJavascript();
+               }
 
                        // Get the browser info
                $browserInfo = t3lib_utility_Client::getBrowserInfo(t3lib_div::getIndpEnv('HTTP_USER_AGENT'));
@@ -764,7 +782,7 @@ class template {
                $xmlStylesheet = '<?xml-stylesheet href="#internalStyle" type="text/css"?>';
 
                        // Add the XML prologue for XHTML doctypes
-               if ($this->docType !== 'html_3' && $this->docType !== 'html_5') {
+               if (strpos($this->doctype, 'xhtml') !== FALSE) {
                                // Put the XML prologue before or after the doctype declaration according to browser
                        if ($browserInfo['browser'] === 'msie' && $browserInfo['version'] < 7) {
                                $headerStart = $headerStart . LF . $xmlPrologue;
@@ -899,6 +917,22 @@ $str.=$this->docBodyTagBegin().
        }
 
        /**
+        * Shortcut for render the complete page of a module
+        *
+        * @param  $title  page title
+        * @param  $content  page content
+        * @param bool $includeCsh  flag for including csh code
+        * @return string complete page
+        */
+       public function render($title, $content, $includeCsh = TRUE)  {
+               $pageContent = $this->startPage($title, $includeCsh);
+               $pageContent .= $content;
+               $pageContent .= $this->endPage();
+
+               return $this->insertStylesAndJS($pageContent);
+       }
+
+       /**
         * Returns the header-bar in the top of most backend modules
         * Closes section if open.
         *
@@ -1578,21 +1612,9 @@ $str.=$this->docBodyTagBegin().
         */
        protected function loadCshJavascript() {
                $this->pageRenderer->loadExtJS();
-               $this->pageRenderer->addExtOnReadyCode('
-                       Ext.getBody().on({
-                               click: {
-                                       delegate: "a",
-                                       scope:this,
-                                       fn:function(event, link) {
-                                               var element = Ext.fly(link);
-                                               if (element.hasClass("typo3-csh-link") || element.hasClass("t3-help-link")) {
-                                                       event.stopEvent();
-                                                       top.TYPO3.ContextHelpWindow.open(link.rel);
-                                               }
-                                       }
-                               }
-                       });
-               ');
+               $this->pageRenderer->addJsFile($this->backPath .'../t3lib/js/extjs/contexthelp.js');
+               $this->pageRenderer->addJsFile($this->backPath . 'ajax.php?ajaxID=ExtDirect::getAPI&namespace=TYPO3.CSH', NULL, FALSE);
+               $this->pageRenderer->addExtDirectCode();
        }
 
        /**
@@ -1695,15 +1717,15 @@ $str.=$this->docBodyTagBegin().
         * @param       string          Identification string. This should be unique for every instance of a dynamic menu!
         * @param       integer         If "1", then enabling one tab does not hide the others - they simply toggles each sheet on/off. This makes most sense together with the $foldout option. If "-1" then it acts normally where only one tab can be active at a time BUT you can click a tab and it will close so you have no active tabs.
         * @param       boolean         If set, the tabs are rendered as headers instead over each sheet. Effectively this means there is no tab menu, but rather a foldout/foldin menu. Make sure to set $toggle as well for this option.
-        * @param       integer         Character limit for a new row.
+        * @param       integer         Character limit for a new row, 0 by default, because this parameter is deprecated since TYPO3 4.5
         * @param       boolean         If set, tab table cells are not allowed to wrap their content
         * @param       boolean         If set, the tabs will span the full width of their position
         * @param       integer         Default tab to open (for toggle <=0). Value corresponds to integer-array index + 1 (index zero is "1", index "1" is 2 etc.). A value of zero (or something non-existing) will result in no default tab open.
         * @param       integer         If set to '1' empty tabs will be remove, If set to '2' empty tabs will be disabled
         * @return      string          JavaScript section for the HTML header.
         */
-       function getDynTabMenu($menuItems,$identString,$toggle=0,$foldout=FALSE,$newRowCharLimit=50,$noWrap=1,$fullWidth=FALSE,$defaultTabIndex=1,$dividers2tabs=2)     {
-               // load the static code, if not already done with the function below
+       public function getDynTabMenu($menuItems, $identString, $toggle = 0, $foldout = FALSE, $newRowCharLimit = 0, $noWrap = 1, $fullWidth = FALSE, $defaultTabIndex = 1, $dividers2tabs = 2) {
+                       // load the static code, if not already done with the function below
                $this->loadJavascriptLib('js/tabmenu.js');
 
                $content = '';
@@ -1722,10 +1744,12 @@ $str.=$this->docBodyTagBegin().
                        $tabRows=0;
                        $titleLenCount = 0;
                        foreach($menuItems as $index => $def) {
-                               $index+=1;      // Need to add one so checking for first index in JavaScript is different than if it is not set at all.
+                                       // Need to add one so checking for first index in JavaScript
+                                       // is different than if it is not set at all.
+                               $index += 1;
 
                                        // Switch to next tab row if needed
-                               if (!$foldout && ($titleLenCount>$newRowCharLimit | ($def['newline'] === true && $titleLenCount > 0))) {
+                               if (!$foldout && (($newRowCharLimit > 0 && $titleLenCount > $newRowCharLimit) | ($def['newline'] === TRUE && $titleLenCount > 0))) {
                                        $titleLenCount=0;
                                        $tabRows++;
                                        $options[$tabRows] = array();
@@ -1739,7 +1763,7 @@ $str.=$this->docBodyTagBegin().
 
                                $isEmpty = !(strcmp(trim($def['content']),'') || strcmp(trim($def['icon']),''));
 
-                               // "Removes" empty tabs
+                                       // "Removes" empty tabs
                                if ($isEmpty && $dividers2tabs == 1) {
                                        continue;
                                }
@@ -1849,9 +1873,11 @@ $str.=$this->docBodyTagBegin().
         * (as long as it is called before $this->startPage())
         * The return value is not needed anymore
         *
+        * @deprecated since TYPO3 4.5, as the getDynTabMenu() function includes the function automatically since TYPO3 4.3
         * @return      string          JavaScript section for the HTML header. (return value is deprecated since TYPO3 4.3, will be removed in TYPO3 4.5)
         */
        function getDynTabMenuJScode()  {
+               t3lib_div::logDeprecatedFunction();
                $this->loadJavascriptLib('js/tabmenu.js');
                // return value deprecated since TYPO3 4.3
                return '';
@@ -1865,183 +1891,10 @@ $str.=$this->docBodyTagBegin().
         * @param       boolean         If set, there will be no button for swapping page.
         * @return      void
         */
-       function getVersionSelector($id,$noAction=FALSE)        {
-
-               if ($id>0)      {
-                       if (t3lib_extMgm::isLoaded('version') && $GLOBALS['BE_USER']->workspace==0)     {
-
-                                       // Get Current page record:
-                               $curPage = t3lib_BEfunc::getRecord('pages',$id);
-                                       // If the selected page is not online, find the right ID
-                               $onlineId = ($curPage['pid']==-1 ? $curPage['t3ver_oid'] : $id);
-                                       // Select all versions of online version:
-                               $versions = t3lib_BEfunc::selectVersionsOfRecord('pages', $onlineId, 'uid,pid,t3ver_label,t3ver_oid,t3ver_wsid,t3ver_id');
-
-                                       // If more than one was found...:
-                               if (count($versions)>1) {
-                                       $selectorLabel = '<strong>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.label', TRUE) . '</strong>';
-
-                                               // Create selector box entries:
-                                       $opt = array();
-                                       foreach($versions as $vRow)     {
-                                               if ($vRow['uid'] == $onlineId) {
-                                                               //Live version
-                                                       $label = '[' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.live', TRUE) . ']';
-                                               } else {
-                                                       $label = $vRow['t3ver_label'] . ' (' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionId', TRUE) . ' ' . $vRow['t3ver_id'] .
-                                                               ($vRow['t3ver_wsid'] != 0 ? ' ' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:workspaceId', TRUE) . ' ' . $vRow['t3ver_wsid'] : '') . ')';
-                                               }
-
-                                               $opt[] = '<option value="' . htmlspecialchars(t3lib_div::linkThisScript(array('id' => $vRow['uid']))) . '"' .
-                                                       ($id == $vRow['uid'] ? ' selected="selected"' : '') . '>' .
-                                                       htmlspecialchars($label) . '</option>';
-                                       }
-
-                                               // Add management link:
-                                       $management = '<input type="button" value="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.mgm', TRUE) . '" onclick="window.location.href=\'' .
-                                                       htmlspecialchars($this->backPath . t3lib_extMgm::extRelPath('version') . 'cm1/index.php?table=pages&uid=' . $onlineId) . '\';" />';
-                                               // Create onchange handler:
-                                       $onChange = "window.location.href=this.options[this.selectedIndex].value;";
-
-                                               // Controls:
-                                       if ($id == $onlineId) {
-                                               $controls .= '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/blinkarrow_left.gif','width="5" height="9"') .
-                                                       ' class="absmiddle" alt="" /> <strong>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.online', TRUE) .
-                                                       '</strong>';
-                                       } elseif (!$noAction) {
-                                               $controls .= '<a href="' . $this->issueCommand('&cmd[pages][' . $onlineId . '][version][swapWith]=' . $id .
-                                                       '&cmd[pages][' . $onlineId . '][version][action]=swap', t3lib_div::linkThisScript(array('id' => $onlineId))) .
-                                                       '" class="nobr">' . t3lib_iconWorks::getSpriteIcon('actions-version-swap-version', array(
-                                                               'title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.swapPage', TRUE),
-                                                               'style' => 'margin-left:5px;vertical-align:bottom;'
-                                                       )) . '<strong>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.swap', TRUE) . '</strong></a>';
-                                       }
-
-                                               // Write out HTML code:
-                                       return '
-
-                                               <!--
-                                                       Version selector:
-                                               -->
-                                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
-                                                       <tr>
-                                                               <td>' . $selectorLabel . '</td>
-                                                               <td>
-                                                                       <select onchange="' . htmlspecialchars($onChange) . '">
-                                                                               ' . implode('', $opt) . '
-                                                                       </select></td>
-                                                               <td>' . $controls . '</td>
-                                                               <td>' . $management . '</td>
-                                                       </tr>
-                                               </table>
-                                       ';
-                               }
-                       } elseif ($GLOBALS['BE_USER']->workspace !== 0) {
-
-                                       // Write out HTML code:
-                               switch($GLOBALS['BE_USER']->workspace) {
-                                       case 0:
-                                               $wsTitle = $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:live', TRUE);
-                                       break;
-                                       case -1:
-                                               $wsTitle = $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:draft', TRUE);
-                                       break;
-                                       default:
-                                               $wsTitle = $GLOBALS['BE_USER']->workspaceRec['title'];
-                                       break;
-                               }
-
-                               if (t3lib_BEfunc::isPidInVersionizedBranch($id) == 'branchpoint') {
-                                       return '
-
-                                               <!--
-                                                       Version selector:
-                                               -->
-                                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
-                                                       <tr>
-                                                               <td>' . $selectorLabel . '</td>
-                                                               <td>Workspace: "' . htmlspecialchars($wsTitle) . '"</td>
-                                                               <td><em>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.inBranch', TRUE) . '</em></td>
-                                                       </tr>
-                                               </table>
-                                       ';
-                               } else {
-                                               // Get Current page record:
-                                       $curPage = t3lib_BEfunc::getRecord('pages', $id);
-                                               // If the selected page is not online, find the right ID
-                                       $onlineId = ($curPage['pid']==-1 ? $curPage['t3ver_oid'] : $id);
-                                               // The version of page:
-                                       $verPage = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, 'pages', $onlineId);
-
-                                       if (!$verPage) {
-
-                                               if (!count(t3lib_BEfunc::countVersionsOfRecordsOnPage($GLOBALS['BE_USER']->workspace, $onlineId))) {
-                                                       if ($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(0)) {
-
-                                                               $onClick = $this->issueCommand('&cmd[pages][' . $onlineId . '][version][action]=new&cmd[pages][' . $onlineId . '][version][treeLevels]=0',
-                                                                       t3lib_div::linkThisScript(array(
-                                                                               'id' => $onlineId
-                                                                       )));
-                                                               $onClick = 'window.location.href=\'' . $onClick . '\'; return false;';
-                                                                       // Write out HTML code:
-                                                               return '
-
-                                                                       <!--
-                                                                               No version yet, create one?
-                                                                       -->
-                                                                       <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
-                                                                               <tr>
-                                                                                       <td>' . $selectorLabel . '</td>
-                                                                                       <td>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:workspace', TRUE) . ': "' . htmlspecialchars($wsTitle) . '"</td>
-                                                                                       <td>
-                                                                                               <input type="button" value="New version of page" name="_" onclick="' . htmlspecialchars($onClick) . '" /></td>
-                                                                               </tr>
-                                                                       </table>
-                                                               ';
-                                                       }
-                                               } elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['elementVersioningOnly'] == FALSE && $GLOBALS['TYPO3_CONF_VARS']['BE']['newPagesVersioningType'] == 0) {
-                                                               // only add this info if old/deprecated newPagesVersioning is allowed
-                                                       return '
-
-                                                               <!--
-                                                                       Version selector:
-                                                               -->
-                                                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
-                                                                       <tr>
-                                                                               <td>' . $selectorLabel . '</td>
-                                                                               <td>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:workspace', TRUE) . ': "' . htmlspecialchars($wsTitle) . '"</td>
-                                                                               <td><em>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.versionsFound', TRUE) . '</em></td>
-                                                                       </tr>
-                                                               </table>
-                                                       ';
-                                               }
-                                       } elseif ($verPage['t3ver_swapmode']==0) {
-                                               $onClick = $this->issueCommand('&cmd[pages][' . $onlineId . '][version][action]=swap&cmd[pages][' .
-                                                       $onlineId . '][version][swapWith]=' . $verPage['uid'],
-                                                       t3lib_div::linkThisScript(array(
-                                                               'id' => $onlineId
-                                                       )));
-                                               $onClick = 'window.location.href=\'' . $onClick . '\'; return false;';
-
-                                                       // Write out HTML code:
-                                               return '
-
-                                                       <!--
-                                                               Version selector:
-                                                       -->
-                                                       <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
-                                                               <tr>
-                                                                       <td>' . $selectorLabel . '</td>
-                                                                       <td>' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:workspace', TRUE) . ': "' . htmlspecialchars($wsTitle) . '"</td>
-                                                                       <td>
-                                                                               <input type="button" value="' . $GLOBALS['LANG']->sL('LLL:EXT:version/locallang.xml:versionSelect.publish', TRUE) .
-                                                                                       '" onclick="' . htmlspecialchars($onClick) . '" /></td>
-                                                               </tr>
-                                                       </table>
-                                               ';
-                                       }
-                               }
-                       }
+       public function getVersionSelector($id, $noAction = FALSE) {
+               if (t3lib_extMgm::isLoaded('version')) {
+                       $versionGuiObj = t3lib_div::makeInstance('tx_version_gui');
+                       return $versionGuiObj->getVersionSelector($id, $noAction);
                }
        }
 
@@ -2053,6 +1906,9 @@ $str.=$this->docBodyTagBegin().
         * @return      string          HTML of template
         */
        function getHtmlTemplate($filename)     {
+                       // setting the name of the original HTML template
+               $this->moduleTemplateFilename = $filename;
+
                if ($GLOBALS['TBE_STYLES']['htmlTemplates'][$filename]) {
                        $filename = $GLOBALS['TBE_STYLES']['htmlTemplates'][$filename];
                }
@@ -2075,7 +1931,7 @@ $str.=$this->docBodyTagBegin().
         *
         * @param       string          filename
         */
-       function setModuleTemplate($filename) {
+       public function setModuleTemplate($filename) {
                        // Load Prototype lib for IE event
                $this->pageRenderer->loadPrototype();
                $this->loadJavascriptLib('js/iecompatibility.js');
@@ -2124,27 +1980,35 @@ $str.=$this->docBodyTagBegin().
                        $moduleBody = t3lib_parsehtml::substituteSubpart($moduleBody, $marker, $content);
                }
 
+                       // adding flash messages
                if ($this->showFlashMessages) {
-                               // adding flash messages
                        $flashMessages = t3lib_FlashMessageQueue::renderFlashMessages();
                        if (!empty($flashMessages)) {
-                               $flashMessages = '<div id="typo3-messages">' . $flashMessages . '</div>';
+                               $markerArray['FLASHMESSAGES'] = '<div id="typo3-messages">' . $flashMessages . '</div>';
+
+                                       // if there is no dedicated marker for the messages present
+                                       // then force them to appear before the content
+                               if (strpos($moduleBody, '###FLASHMESSAGES###') === FALSE) {
+                                       $moduleBody = str_replace(
+                                               '###CONTENT###',
+                                               '###FLASHMESSAGES######CONTENT###',
+                                               $moduleBody
+                                       );
+                               }
                        }
+               }
 
-                       if (strstr($moduleBody, '###FLASHMESSAGES###')) {
-                                       // either replace a dedicated marker for the messages if present
-                               $moduleBody = str_replace(
-                                       '###FLASHMESSAGES###',
-                                       $flashMessages,
-                                       $moduleBody
-                               );
-                       } else {
-                                       // or force them to appear before the content
-                               $moduleBody = str_replace(
-                                       '###CONTENT###',
-                                       $flashMessages . '###CONTENT###',
-                                       $moduleBody
-                               );
+                       // Hook for adding more markers/content to the page, like the version selector
+               if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['moduleBodyPostProcess'])) {
+                       $params = array(
+                               'moduleTemplateFilename' => &$this->moduleTemplateFilename,
+                               'moduleTemplate' => &$this->moduleTemplate,
+                               'moduleBody' => &$moduleBody,
+                               'markers' => &$markerArray,
+                               'parentObject' => &$this
+                       );
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['moduleBodyPostProcess'] as $funcRef) {
+                               t3lib_div::callUserFunction($funcRef, $params, $this);
                        }
                }
 
@@ -2360,8 +2224,8 @@ class frontendDoc extends template {
 }
 
 
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/template.php'])     {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/template.php']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/template.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/template.php']);
 }
 
 
@@ -2372,4 +2236,4 @@ if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/templ
 $GLOBALS['TBE_TEMPLATE'] = t3lib_div::makeInstance('template');
 
 
-?>
\ No newline at end of file
+?>