I would like to know if there is a better way to approach the following the problem.
A have several possible layers of modules that may each contain style, link or script tags. The reason for this is to so that styles, link and script specific to the module that they belong to may be defined directly in the template which results in invalid HTML.
A simple example of this could be the module Index defining a specific style criteria for its contents (shown below).
<style type="text/css">
#mod-index p {
color: red;
}
</style>
<div id="mod-index">
<p>Index</p>
</div>
Now left untouched embedding this template into the master template results in the below HTML.
...
<body>
<div id="container">
<style type="text/css">
#mod-index p {
color: red;
}
</style>
<div id="mod-index">
<p>Index</p>
</div>
</div>
</body>
</html>
So my current solution to this problem is upon getting the HTML string using the below code to extract and move all script, style and link tags defined in the body to the head.
...
/*
* move all style, link and script tags w/ contents to head
*/
GLOBAL $s;
$s = array();
$strHTML = preg_replace_callback('/(<style.*?>.*?<\\/style>|<link.*?>|<script.*?>.*?<\\/script>)/si',create_function('$m','GLOBAL $s;$s[] = $m[0];return "";'),$strHTML);
if(!empty($s)) $strHTML = preg_replace('/<\\/head>/',implode("\
",$s)."\
</head>",$strHTML,1);
echo $strHTML;
The below code included would then yield the below from the previous example.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Home</title>
<style type="text/css">
#mod-index p {
color: red;
}
</style>
</head>
<body>
<div id="container">
<div id="mod-index">
<p>Index</p>
</div>
</div>
</body>
</html>
Notice how the style tag and its contents have been correctly moved to head of the document - perfect.
However, the primary problem I have with the solution is that it isn’t 100% concrete. Given user content that “may” match patterns the entire page would break. So I’m wondering if perhaps there is a more concrete way to achieve the above without breaking page when user content may match the patterns?
The below represents a concrete solution to the problem but its not very pretty or easy to understand for those lacking PHP knowledge whereas, the previous cleanly and automatically modifies everything.
<?php
$this->addCss(
'<style type="text/css">
#mod-index p {
color: red;
}
</style>';
);
?>
<div id="mod-index">
<p>Index</p>
</div>