-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Confused/missing tags in HTML output #208
Comments
Even though it's not being rendered as XML, I wonder if wrapping it in a CDATA thing would make any difference. Apparently issues with the @TomBZombie - It might be good to add some code resembling this comment somewhere between the load and save calls, though I know it only addresses externally-sourced scripts. |
CDATA wrapping the Javascript does not seem to help. The output I get then becomes:
|
Here's a minimal test script: <?php
$xml = <<<XML
<div>
<script>
var msgs += "<div>";
msgs += "<button>X</button>";
msgs += "</div>";
</script>
</div>
XML;
$document = new \DomDocument();
$document->loadHtml('<' . '?xml encoding="UTF-8">' . $xml, LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
echo $document->saveHtml(); For some reason this gives me the output:
I have no idea where the I think this will have to be reported upstream as I don't think it's something I can fix. |
Ultimately what seems clear to me is that DOMDocument is not able to understand that HTML tags inside of a |
It looks like this is something PHP can't fix: https://bugs.php.net/bug.php?id=74858
I'd recommend following best practice and storing your javascript in external files. There are too many permutations for this fix to be applied inside Transphporm. The bug report on php.net suggests this should work: $xml = <<<XML
<div>
<script>
var msgs += "<div>";
msgs += "<button>X<\/button>";
msgs += "<\/div>";
</script>
</div>
XML; But it doesn't, the backslashes are included in the final output.
Unfortunately I don't think there is a simple solution short of writing a new DOM parser. As a hack it might be possible to regex A better solution is using pure XML as it's handled correctly there. <?php
$xml = <<<XML
<?xml version="1.0"?>
<div>
<script>
var msgs += "<div>";
msgs += "<button>X</button>";
msgs += "</div>";
</script>
</div>
XML;
$document = new \DomDocument();
$document->loadXml($xml);
echo $document->saveXml(); outputs:
tl;dr put edit: I don't know why using loadXML/saveXML works. I'd expected you to need cdata tags for it to work as intended. |
That's a shame. |
It would have to be applied every time output is called so would bypass the cache and create a regex search on every single template load which would be slow. It could be mitigated by You'd also have to write some fairly complex logic because cases like this would break it:
Comments It looks like libXML already fixed this in We could do something like: <script transphporm-libxml-bug-hack="true"> and At minimum, we do need to put a warning somewhere in the documentation though. Ideally this will be fixed in PHP and/or libxml. |
In the case of But I agree that given all of that, the overhead isn't worth it. (My idea for attribute sniffing was to use something that's actually valid, such as |
Wow. So if I'm composing my final page out of multiple templates, each template file needs to be proper XML and contain the That certainly seems preferable to placing all of my Javascript in external files. I do place all shared JS in separate files, but some pages need their own few lines of special JS glue to put it all together. |
I wonder if we can be a bit smarter. We had issues when importing HTML into XML but I'd have thought the other way should be ok. I'll need to test it, but it might be possible to just add the XML tag to the template with the script tag. really though, it'd be better if libxml fixed this as it's clearly a bug their end. |
Apparently $xml = <<<XML
<?xml version="1.0"?>
<div>
<script>
var msgs += "<div>";
msgs += "<button>X<\/button>";
msgs += "<\/div>";
</script>
</div>
XML;
$document = new \DomDocument();
$document->loadHtml($xml, LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED);
echo $document->saveHtml(); |
@garrettw Whoops, did I goof you up by deleting my comment? I noticed that Tom had directly addressed most of my concerns earlier, so I removed it as redundant. The following seems to work for me so far. Is this the proper way to do this? In particular, the repeated uses of Main content in a partial, e.g. <?xml version="1.0"?>
<div>
<!-- bunch of XHTML -->
<script>
<![CDATA[
// Javascript unique to this content/page only.
]]>
</script>
</div> Main content TSS, e.g. main {
content: template("content.xml");
} Some default page layout, e.g. <?xml version="1.0"?>
<!DOCTYPE html>
<html xml:lang="en" lang="en">
<head>
<!-- The usual JS libs, CSS libs and other head elements -->
</head>
<body>
<main>
<!-- main content gets inserted here -->
</main>
</body>
</html> Called with something like: $tpl = new Transphporm\Builder("default.xml", "content.tss"); |
You shouldn't need CDATA tags anywhere, libxml seems to handle <div>
<script>
var msgs += "<div>";
msgs += "<button>X<\/button>";
msgs += "<\/div>";
</script>
</div> edit: Which works with XML or HTML. |
Transphporm throws an exception if I remove the CDATA in my real project.
|
If you're using HTML everywhere (no <?xml tags anywhere) then this works for <div>
<!-- bunch of XHTML -->
<script>
var msgs += "<div>";
msgs += "<button>X<\/button>";
msgs += "<\/div>";
</script>
</div> For xml you don't need the slashes: <?xml version="1.0"?>
<div>
<!-- bunch of XHTML -->
<script>
var msgs += "<div>";
msgs += "<button>X</button>";
msgs += "</div>";
</script>
</div> and works as-is in your example. I can't replicate the error you had, I'm guessing there must be a libxml version difference. Can you run
I get
|
Ok I think I can see what's happening here. XML works because it is well formed and libxml does not do anything special with the script tag. using the XML <script>
var msgs += "<div>";
msgs += "<button>X</button>";
msgs += "</div>";
</script> It generates:
If the javascript isn't well formed XML e.g. |
This is so strange, it might even be a PHP bug:
Produces:
Notice how the
</button>
got swallowed and the closing</div>
got included into the Javascript literal and the final</div>
went missing as well.The text was updated successfully, but these errors were encountered: