8561 Checkboxes and labels are aligned badly if in one line
[Packages/TYPO3.CMS.git] / typo3 / template.php
index 08a04b8..63e5871 100755 (executable)
@@ -140,7 +140,7 @@ require_once(PATH_t3lib.'class.t3lib_ajax.php');
  *
  * @param      string          Input string
  * @return     string          Output string (in the old days this was wrapped in <font> tags)
- * @deprecated
+ * @deprecated since TYPO3 4.0
  */
 function fw($str)      {
        return $str;
@@ -175,7 +175,8 @@ class template {
        var $JScode='';                                 // Additional header code (eg. a JavaScript section) could be accommulated in this var. It will be directly outputted in the header.
        var $JScodeArray = array();             // Similar to $JScode but for use as array with associative keys to prevent double inclusion of JS code. a <script> tag is automatically wrapped around.
        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 HTML 4. You can also set it to 'strict', 'xhtml_trans', or 'xhtml_frames'.
+       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
 
                // Other vars you can change, but less frequently used:
        var $scriptID='';                               // Script ID.
@@ -186,6 +187,7 @@ class template {
        var $form_rowsToStylewidth = 9.58;      // Multiplication factor for formWidth() input size (default is 48* this value).
        var $form_largeComp = 1.33;             // Compensation for large documents (used in class.t3lib_tceforms.php)
        var $endJS=1;                                   // If set, then a JavaScript section will be outputted in the bottom of page which will try and update the top.busy session expiry object.
+       protected $additionalStyleSheets=array();       // Links to additional style sheets
 
                // TYPO3 Colorscheme.
                // If you want to change this, please do so through a skin using the global var $TBE_STYLES
@@ -473,7 +475,7 @@ class template {
                $GET = t3lib_div::_GET();
                $storeArray = array_merge(
                        t3lib_div::compileSelectedGetVarsFromArray($gvList,$GET),
-                       array('SET'=>t3lib_div::compileSelectedGetVarsFromArray($setList,$GLOBALS['SOBE']->MOD_SETTINGS))
+                       array('SET'=>t3lib_div::compileSelectedGetVarsFromArray($setList, (array)$GLOBALS['SOBE']->MOD_SETTINGS))
                );
                $storeUrl = t3lib_div::implodeArrayForUrl('',$storeArray);
                return $storeUrl;
@@ -607,6 +609,19 @@ class template {
         * @see endPage()
         */
        function startPage($title)      {
+                       // 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'];
+                       if (is_array($preStartPageHook)) {
+                               $hookParameters = array(
+                                       'title' => &$title,
+                               );
+                               foreach ($preStartPageHook as $hookFunction)    {
+                                       t3lib_div::callUserFunction($hookFunction, $hookParameters, $this);
+                               }
+                       }
+               }
+
                        // Get META tag containing the currently selected charset for backend output. The function sets $this->charSet.
                $charSet = $this->initCharset();
                $generator = $this->generator();
@@ -618,38 +633,39 @@ class template {
                header ('Content-Type:text/html;charset='.$this->charset);
 
                switch($this->docType)  {
+                       case 'html_3':
+                               $headerStart = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">';
+                               break;
                        case 'xhtml_strict':
-                               $headerStart= '<!DOCTYPE html
+                               $headerStart = '<!DOCTYPE html
        PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <?xml version="1.0" encoding="'.$this->charset.'"?>
 <?xml-stylesheet href="#internalStyle" type="text/css"?>
 ';
-                       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">
-<?xml version="1.0" encoding="'.$this->charset.'"?>
-<?xml-stylesheet href="#internalStyle" type="text/css"?>
-';
-                       break;
+                               break;
                        case 'xhtml_frames':
-                               $headerStart= '<!DOCTYPE html
+                               $headerStart = '<!DOCTYPE html
      PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
 <?xml version="1.0" encoding="'.$this->charset.'"?>
 ';
-                       break;
+                               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 HTML 3.2 Final//EN">';
-                       break;
+                               $headerStart = '<!DOCTYPE html
+     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?xml version="1.0" encoding="'.$this->charset.'"?>
+<?xml-stylesheet href="#internalStyle" type="text/css"?>
+';
                }
 
-               $tabJScode = '';
-               if (!$GLOBALS['BE_USER']->uc['disableTabInTextarea'])   {
-                               // This loads the tabulator-in-textarea feature. It automatically modifies every textarea which is found.
-                       $tabJScode = '<script src="'.$this->backPath.'tab.js" type="text/javascript"></script>';
+               // This loads the tabulator-in-textarea feature. It automatically modifies
+               // every textarea which is found.
+               if (!$GLOBALS['BE_USER']->uc['disableTabInTextarea']) {
+                       $this->loadJavascriptLib('tab.js');
                }
 
                        // Construct page header.
@@ -663,7 +679,6 @@ class template {
        '.$this->docStyle().'
        '.implode("\n", $this->JScodeLibArray).'
        '.$this->JScode.'
-       '.$tabJScode.'
        '.$this->wrapScriptTags(implode("\n", $this->JScodeArray)).'
        <!--###POSTJSMARKER###-->
 </head>
@@ -694,7 +709,7 @@ $str.=$this->docBodyTagBegin().
                $str = $this->sectionEnd().
                                $this->postCode.
                                $this->endPageJS().
-                               t3lib_BEfunc::getSetUpdateSignal().
+                               $this->wrapScriptTags(t3lib_BEfunc::getUpdateSignalCode()).
                                $this->parseTime().
                                ($this->form?'
 </form>':'');
@@ -712,7 +727,7 @@ $str.=$this->docBodyTagBegin().
                $str .= '</html>';
 
                        // Logging: Can't find better place to put it:
-               if (TYPO3_DLOG) t3lib_div::devLog('END of BACKEND session','',0,array('_FLUSH'=>TRUE));
+               if (TYPO3_DLOG) t3lib_div::devLog('END of BACKEND session', 'template', 0, array('_FLUSH' => true));
 
                return $str;
        }
@@ -860,7 +875,7 @@ $str.=$this->docBodyTagBegin().
         *
         * @return      void
         * @internal
-        * @deprecated
+        * @deprecated since TYPO3 4.0
         */
        function middle()       {
        }
@@ -923,7 +938,8 @@ $str.=$this->docBodyTagBegin().
                                        /*###POSTCSSMARKER###*/
                                /*]]>*/
                        </style>
-                       '.($this->styleSheetFile_post?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile_post.'" />':'')
+                       '.($this->styleSheetFile_post?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile_post.'" />':'').'
+                       '.implode("\n", $this->additionalStyleSheets)
                )
                ;
                $this->inDocStyles='';
@@ -934,6 +950,21 @@ $str.=$this->docBodyTagBegin().
        }
 
        /**
+        * Insert additional style sheet link
+        *
+        * @param       string          $key: some key identifying the style sheet
+        * @param       string          $href: uri to the style sheet file
+        * @param       string          $title: value for the title attribute of the link element
+        * @return      string          $relation: value for the rel attribute of the link element
+        * @return      void
+        */
+       function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
+               if (!isset($this->additionalStyleSheets[$key])) {
+                       $this->additionalStyleSheets[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '"' . ($title ? (' title="' . $title . '"') : '') . ' />';
+               }
+        }
+
+       /**
         * Insert post rendering document style into already rendered content
         * This is needed for extobjbase
         *
@@ -973,7 +1004,7 @@ $str.=$this->docBodyTagBegin().
         * @return      string          <meta> tag with name "generator"
         */
        function generator()    {
-               $str = 'TYPO3 '.TYPO3_branch.', http://typo3.com, &#169; Kasper Sk&#229;rh&#248;j 1998-2006, extensions are copyright of their respective owners.';
+               $str = 'TYPO3 '.TYPO3_branch.', http://typo3.com, &#169; Kasper Sk&#229;rh&#248;j 1998-2008, extensions are copyright of their respective owners.';
                return '<meta name="generator" content="'.$str .'" />';
        }
 
@@ -1288,7 +1319,8 @@ $str.=$this->docBodyTagBegin().
         */
        function getDragDropCode($table)        {
                $this->loadJavascriptLib('contrib/prototype/prototype.js');
-               $this->loadJavascriptLib('tree.js');
+               $this->loadJavascriptLib('js/common.js');
+               $this->loadJavascriptLib('js/tree.js');
 
                        // setting prefs for drag & drop
                $this->JScodeArray['dragdrop'] = '
@@ -1493,7 +1525,8 @@ $str.=$this->docBodyTagBegin().
                                $JSinit[] = '
                                                DTM_array["'.$id.'"]['.$c.'] = "'.$id.'-'.$index.'";
                                ';
-                               if ($toggle==1) {
+                                       // If not empty and we have the toggle option on, check if the tab needs to be expanded
+                               if ($toggle == 1 && $isNotEmpty) {
                                        $JSinit[] = '
                                                if (top.DTM_currentTabs["'.$id.'-'.$index.'"]) { DTM_toggle("'.$id.'","'.$index.'",1); }
                                        ';
@@ -1805,9 +1838,161 @@ $str.=$this->docBodyTagBegin().
                        }
                }
        }
-}
 
 
+       /**
+        * Function to load a HTML template file with markers.
+        *
+        * @param       string          tmpl name, usually in the typo3/template/ directory
+        * @return      string          HTML of template
+        */
+       function getHtmlTemplate($filename)     {
+               if ($GLOBALS['TBE_STYLES']['htmlTemplates'][$filename]) {
+                       $filename = $GLOBALS['TBE_STYLES']['htmlTemplates'][$filename];
+               }
+               return ($filename ? t3lib_div::getURL($this->backPath . $filename) : '');
+       }
+
+       /**
+        * Define the template for the module
+        *
+        * @param       string          filename
+        */
+       function setModuleTemplate($filename) {
+                       // Load Prototype lib for IE event
+               $this->loadJavascriptLib('contrib/prototype/prototype.js');
+               $this->loadJavascriptLib('js/iecompatibility.js');
+               $this->moduleTemplate = $this->getHtmlTemplate($filename);
+       }
+
+       /**
+        * Put together the various elements for the module <body> using a static HTML
+        * template
+        *
+        * @param       array           Record of the current page, used for page path and info
+        * @param       array           HTML for all buttons
+        * @param       array           HTML for all other markers
+        * @return      string          Composite HTML
+        */
+       public function moduleBody($pageRecord = array(), $buttons = array(), $markerArray = array(), $subpartArray = array()) {
+                       // Get the HTML template for the module
+               $moduleBody = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###FULLDOC###');
+                       // Add CSS
+               $this->inDocStylesArray[] = 'html { overflow: hidden; }';
+                       // Add JS code to the <head> for IE
+               $this->JScode.= $this->wrapScriptTags('
+                               // workaround since IE6 cannot deal with relative height for scrolling elements
+                       function resizeDocBody()        {
+                               $("typo3-docbody").style.height = (document.body.offsetHeight - parseInt($("typo3-docheader").getStyle("height")));
+                       }
+                       if (Prototype.Browser.IE) {
+                               var version = parseFloat(navigator.appVersion.split(\';\')[1].strip().split(\' \')[1]);
+                               if (version == 6) {
+                                       Event.observe(window, "resize", resizeDocBody, false);
+                                       Event.observe(window, "load", resizeDocBody, false);
+                               }
+                       }
+               ');
+                       // Get the page path for the docheader
+               $markerArray['PAGEPATH'] = $this->getPagePath($pageRecord);
+                       // Get the page info for the docheader
+               $markerArray['PAGEINFO'] = $this->getPageInfo($pageRecord);
+                       // Get all the buttons for the docheader
+               $docHeaderButtons = $this->getDocHeaderButtons($buttons);
+                       // Merge docheader buttons with the marker array
+               $markerArray = array_merge($markerArray, $docHeaderButtons);
+                       // replacing subparts
+               foreach ($subpartArray as $marker => $content) {
+                       $moduleBody = t3lib_parsehtml::substituteSubpart($moduleBody, $marker, $content);
+               }
+                       // replacing all markers with the finished markers and return the HTML content
+               return t3lib_parsehtml::substituteMarkerArray($moduleBody, $markerArray, '###|###');
+
+       }
+
+       /**
+        * Fill the button lists with the defined HTML
+        *
+        * @param       array           HTML for all buttons
+        * @return      array           Containing HTML for both buttonlists
+        */
+       protected function getDocHeaderButtons($buttons) {
+               $markers = array();
+                       // Fill buttons for left and right float
+               $floats = array('left', 'right');
+               foreach($floats as $key) {
+                               // Get the template for each float
+                       $buttonTemplate = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###BUTTON_GROUPS_' . strtoupper($key) . '###');
+                               // Fill the button markers in this float
+                       $buttonTemplate = t3lib_parsehtml::substituteMarkerArray($buttonTemplate, $buttons, '###|###', true);
+                               // getting the wrap for each group
+                       $buttonWrap = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###BUTTON_GROUP_WRAP###');
+                               // looping through the groups (max 6) and remove the empty groups
+                       for ($groupNumber = 1; $groupNumber < 6; $groupNumber++) {
+                               $buttonMarker = '###BUTTON_GROUP' . $groupNumber . '###';
+                               $buttonGroup = t3lib_parsehtml::getSubpart($buttonTemplate, $buttonMarker);
+                               if (trim($buttonGroup)) {
+                                       if ($buttonWrap) {
+                                               $buttonGroup = t3lib_parsehtml::substituteMarker($buttonWrap, '###BUTTONS###', $buttonGroup);
+                                       }
+                                       $buttonTemplate = t3lib_parsehtml::substituteSubpart($buttonTemplate, $buttonMarker, trim($buttonGroup));
+                               }
+                       }
+                               // replace the marker with the template and remove all line breaks (for IE compat)
+                       $markers['BUTTONLIST_' . strtoupper($key)] = str_replace("\n", '', $buttonTemplate);
+               }
+               return $markers;
+       }
+
+       /**
+        * Generate the page path for docheader
+        *
+        * @param       array   Current page
+        * @return      string  Page path
+        */
+       protected function getPagePath($pageRecord) {
+               global $LANG;
+                       // Is this a real page
+               if ($pageRecord['uid']) {
+                       $title = $pageRecord['_thePath'];
+               } else {
+                       $title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
+               }
+                       // Setting the path of the page
+               $pagePath = $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.path', 1) . ': <span class="typo3-docheader-pagePath">' . htmlspecialchars(t3lib_div::fixed_lgd_cs($title, -50)) . '</span>';
+               return $pagePath;
+       }
+
+       /**
+        * Setting page icon with clickmenu + uid for docheader
+        *
+        * @param       array   Current page
+        * @return      string  Page info
+        */
+       protected function getPageInfo($pageRecord) {
+               global $BE_USER;
+                               // Add icon with clickmenu, etc:
+               if ($pageRecord['uid']) {       // If there IS a real page
+                       $alttext = t3lib_BEfunc::getRecordIconAltText($pageRecord, 'pages');
+                       $iconImg = t3lib_iconWorks::getIconImage('pages', $pageRecord, $this->backPath, 'class="absmiddle" title="'. htmlspecialchars($alttext) . '"');
+                               // Make Icon:
+                       $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, 'pages', $pageRecord['uid']);
+               } else {        // On root-level of page tree
+                               // Make Icon
+                       $iconImg = '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/i/_icon_website.gif') . ' alt="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '" />';
+                       if($BE_USER->user['admin']) {
+                               $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, 'pages', 0);
+                       } else {
+                               $theIcon = $iconImg;
+                       }
+               }
+
+                       // Setting icon with clickmenu + uid
+               $pageInfo = $theIcon . '<em>[pid: ' . $pageRecord['uid'] . ']</em>';
+               return $pageInfo;
+       }
+}
+
 
 // ******************************
 // Extension classes of the template class.
@@ -1853,25 +2038,15 @@ class mediumDoc extends template {
 }
 
 
-
-// Include extension to the template class?
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/template.php'])     {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/template.php']);
 }
 
 
 
-// ******************************************************
-// The backend language engine is started (ext: "lang")
-// ******************************************************
-require_once(PATH_typo3.'sysext/lang/lang.php');
-$GLOBALS['LANG'] = t3lib_div::makeInstance('language');
-$GLOBALS['LANG']->init($BE_USER->uc['lang']);
-
-
-
 // ******************************
 // The template is loaded
 // ******************************
 $GLOBALS['TBE_TEMPLATE'] = t3lib_div::makeInstance('template');
-?>
+
+?>
\ No newline at end of file