contao/import — Issue #3359: Contao 2.10 libraries Template.php - option Minify the html markup has issues!
Author: importer
Created: 2011-11-29 21:24:24+00:00
State: open
Labels: Defect, frontend

The function minifyHtml()
is being too aggressive and is removing valid jQuery markup

![](

I found that I was seeing JavaScript errors with the Contao option **Minify the markup** (html) set to enabled)

The errors were:

```
Error: $.noConflict is not a function
Error: $(document.body).adopt is not a function
```

The errors do not occur if the Contao option **Minify the markup** is not set

![](

Therefore, I wrote my own 'clean and compress' routine to replace the function minifyHtml()[file = Template.phpin /system/libraries/) and all is well)

I share the code I used:

```
// Modified minifyHtml()
/**
* Minify HTML markup preserving pre, script, style and textarea tags
* `param string
* `return string
*/
public function minifyHtml($strHtml)
{
// The feature has been disabled
if (

![]($GLOBALS['TL_CONFIG']['minifyMarkup'])
{
return $strHtml;
}

// New Code: Compact the gathered content: strip and clean
$compactor = new Compactor(array());
$strHtml = $compactor->squeeze($strHtml);

return $strHtml;
}
```

The I added the following code to the end of Template.php
just before the closing ?>

```
class Compactor
{
/**
* Holds the options array
* `access private
* `var array
*/
private $_options	= array(
'minify'	=> true, // double spaces, double line breaks, empty symbols at the beginning of every string and spaces before tag ends
'unobtrusive_all'	=> false, // Put all scripts right before

'html_tidy'	=> true, // Don't use RegExp everywhere where it's possible
'minify_aggressive'	=> false // Shrink HTML code to 1 string, CPU intensive
);

/**
* Constructor
*/
function __construct($options=array())
{
$this->setOption($options);
}

/**
* Sets an option in the option array();
*
* `access public
* `param mixed $varname Can take the form of an array of options to set a string of an option name.
* `param mixed $varvalue The value of the option you are setting.
**/
public function setOption($varname, $varvalue=null)
{
$keys = array_keys($this->_options);
if(gettype($varname) == 'array')
{
foreach($varname as $name=>$value)
{
if(in_array($name, $keys))
{
$this->_options[$name] = $value;
}
}
}
else
{
if(in_array($varname, $keys))
{
$this->_options[$varname] = $varvalue;
}
}
}

/**
* Safely trims whitespace from an HTML page
* Adapted from smarty code http://www.smarty.net/
**/
public function squeeze($source) {
if ()empty($this->_options['minify']) ||

![](empty($this->_options['unobtrusive_all'])) {
if ()empty($this->_options['html_tidy'])) {
$_script_blocks = array(array(), array(), array(),
array(), array(), array());
// Pull out the script, textarea and pre blocks
$this->trimwhitespace_find('',
'`@`WBO:TRIM:SCRIPT0`@`', $source, $_script_blocks[0]);
$this->trimwhitespace_find('',
'`@`WBO:TRIM:SCRIPT1`@`', $source, $_script_blocks[1]);
$this->trimwhitespace_find('',
'`@`WBO:TRIM:SCRIPT2`@`', $source, $_script_blocks[2]);
$this->trimwhitespace_find('',
'`@`WBO:TRIM:SCRIPT3`@`', $source, $_script_blocks[3]);
$this->trimwhitespace_find('trimwhitespace_find('',
'`@`WBO:TRIM:SCRIPT5`@`', $source, $_script_blocks[5]);
} else {
preg_match_all("

![]((||||_options['minify'])) {
$source = trim(preg_replace('/((?<)\?>)\n)[\s]+/m', '\1', $source));
// replace ' >' with '>', remove \r symbols
$source = str_replace(array(' >', "\r"), array('>', ''), $source);
}
// one-strig-HTML takes about 20-50ms
if (

![](empty($this->_options['minify_aggressive'])) {
// ' />' with '/>' breaks System - Cache in Joomla)
$source = str_replace(' />', '/>', $source);
// replace breaks with nothing for block tags
$source = preg_replace("`[\s\t\r\n]**(]**)?>[\s\t\r\n]+`si", "$1$2$3>", $source);
// replace breaks with space for inline tags
$source = preg_replace("`(]*)?>[\s\t\r\n]+`si", "$1$2$3> ", $source);
}
// replace multiple spaces with single one
// $source = preg_replace("/[\s\t\r\n]+/", " ", $source);
// replace script, textarea, pre blocks
if ()empty($this->_options['unobtrusive_all']) ||

![](empty($this->_options['minify'])) {
$before_body = '';
if ()empty($this->_options['html_tidy'])) {
for ($i = 0; $i < 6; $i++) {
$_block = $_script_blocks[$i];
if (count($_block)) {
$before_body .=
$this->trimwhitespace_replace("`@`WBO:TRIM:SCRIPT" .
$i . "`@`", $_block, $source);
}
}
} else {
$before_body =
$this->trimwhitespace_replace("`@`WBO:TRIM:SCRIPT`@`",
$_script_blocks, $source);
}
// move all scripts to

if (

![](empty($before_body)) {
if ()empty($this->_options['html_tidy']) &&
($bodypos = strpos($source, "

"))) {
$source = substr_replace($source,
$before_body, $bodypos, 0);
} elseif (

![](empty($this->_options['html_tidy']) &&
($bodypos = strpos($this->content, "

"))) {
$source = substr_replace($source,
$before_body, $bodypos, 0);
} else {
$source = preg_replace('`(

)`is',
$before_body . "$1", $source);
// some engines do not set

if ()strpos($source, $before_body)) {
$source .= $before_body;
}
}
}
}
// remove website host
if (

![](empty($this->_options['minify_aggressive'])) {
// fix for base tag
preg_match_all("`]+>`is", $source, $matches);
$basetag = false;
if (count($matches) && count($matches[0])) {
$basetag = $matches[0][0];
}
if ($basetag) {
$source = str_replace($basetag, '`@`WSSBASE`@`', $source);
}
$source = preg_replace("`(src|href)=(['\"])(http[ .
$this->https . ](//))(www\.)?" .
$this->host . "/*`", "$1=$2/", $source);
if ($basetag) {
$source = str_replace('`@`WSSBASE`@@', $basetag, $source);
}
}
return $source;
}

/**
* Helper function for trimwhitespace, finds all blocks
*
**/
function trimwhitespace_find ($block_begin, $block_end, $spot, &$subject, &$return) {
$len = strlen($block_end);
while ($posbegin = strpos($subject, $block_begin)) {
if ((($posend = strpos($subject, $block_end)) )== false) && ($posend > $posbegin)) {
$return[] = substr($subject, $posbegin, $posend - $posbegin + $len);
$subject = substr_replace($subject, $spot, $posbegin, $posend - $posbegin + $len);
} else {
break;
}
}
}

/**
* Helper function for trimwhitespace
*
**/
function trimwhitespace_replace ($search_str, $replace, &$subject) {
$_len = strlen($search_str);
$_pos = 0;
$_to_body = '';
for ($_i=0, $_count = count($replace); $_i<$_count; $_i++) {
if (($_pos = strpos($subject, $search_str, $_pos)) !== false) {
$subject = substr_replace($subject, $replace[$_i], $_pos, $_len);
} else {
break;
}
}
return $_to_body;
}

}
```

Peter

Related issues: #3415

--- _Originally created by peterbowey on August 12th, 2011, at 04:09pm (ID 3359)_