How to preserve javascript in heist template from escaping?

437 Views Asked by At

I'm using Snap framework with Heist templating engine. The problem is that Heist corrupts javascript code inlined into html:

<script type="text/javascript">alert('hello');</script> 

Transformed into:

<script type="text/javascript">alert(&apos;hello&apos;);</script>

How can I tell Heist to preserve contents of the script tag?

Edit: I just implemented such splice:

verbatimSplice :: MonadIO m => Splice m
verbatimSplice = do
    node <- getParamNode       -- get <script> node
    stopRecursion              -- stop recursive processing of splices
    lift $ liftIO $ print node -- show me the node
    return [node]              -- return <script> as is

But binding this splice to script tag does not help. It prints

Element "script" [("type","text/javascript")] [Text "alert('hello');"]

so, I think, html entity substitution takes place after running all splices.

2

There are 2 best solutions below

1
On BEST ANSWER

Heist uses hexpat for its processing. I believe the issue here is that hexpat uses expat, which requires well-formed XML. Unfortunately HTML documents with inline javascript aren't valid, so it escapes them. We're aware of this problem. The solution is to switch to an HTML5 parser instead of an XML parser. Unfortunately there are no good HTML5 parsing libraries for Haskell.

Until that happens, the solution is to move all your javascript out of templates into external files. We realize this is not an adequate solution for the long term. We're planning to either write one or switch to one eventually. Contributions in this area would be greatly appreciated.

Update:

As of February 2011, Heist has switched from using hexpat to using our own custom HTML parsing library called XmlHtml which solves this problem.

1
On

Ideally you would wrap your script in CDATA tags

<script>
//<!CDATA[
  alert('hello');
//]]>
</script>

which would make it valid XML.

Alas, Heist seems to ignore these.