Comments (8)
Why was this issue closed? Not escaping by default is really bad and leads to all kinds of vulnerabilities which could easily be avoided. Why does html
need to be nestable and why does it block this feature?
from hiccup.
If you can figure out a way of doing this without significantly impacting performance, I'm all ears :)
Metadata can't be added to strings, and Hiccup functions frequently return strings of HTML, e.g.
(defhtml foo [x]
[:div.foo x])
from hiccup.
Metadata can't be added to strings
Because the reason to add metadata to a string is to mark that the string should not be escaped automatically, I think there is some other way to mark.
For example, (raw s) would convert s to:
- a map {:raw true, :content s}
- or an object of a special class MyRawString
then on rendering check if the input has the mark.
Because we are outputting HTML elements, another way is to mark the entire element to be raw:
[:div {:raw true, :style "some style"} anything]
"raw" is not a common HTML attribute, so I think it would be OK.
from hiccup.
The problem with this approach is that the html macro would have to return (raw s) as well, e.g.
(html [:span "foo"])
=> {:raw true, :content "<span>foo</span>"}
This needs to be the case so that we can embed one HTML inside another:
(defhtml foo [x]
[:span.foo x])
(html [:div (foo "hello")])
=> <div><span class="foo">hello</span></div>
from hiccup.
How about the option style approach?
[:div {:raw true, :style "some style"} anything]
I feel that it works and it is more elegant than the (raw s) approach.
from hiccup.
No, it wouldn't really work. The problem is that this:
(html [:div (html [:span "foo"])])
Needs to produce the same output as:
(html [:div [:span "foo"]])
And this output needs to be indistinguishable from a string.
from hiccup.
There are several issues that can only be solved by a redesign of the Hiccup compiler. I was in two minds whether to keep them all, or whether to close all but one, since they're all facets of the same problem. In the end, I chose to keep issue #7 up and close the rest.
As to why it's not possible with the current architecture, consider the following code:
(defn foo [x]
(html [:div.foo x]))
(defn bar [x]
(html [:div.bar (foo x)]))
If we automatically escape all strings, then the result of (bar "baz")
will be:
<div class="bar"><div class="foo">baz</div></div>
Instead of:
<div class="bar"><div class="foo">baz</div></div>
You might very well say that we could just require that the html
macro is only at the top level, i.e.
(defn foo [x]
[:div.foo x])
(defn bar [x]
(html [:div.bar (foo x)]))
The problem with this approach is that (a) it breaks existing code, and (b) Hiccup can no longer pre-compile foo
. It has to parse the body each time, making it significantly slower.
So what's the solution?
Well, the only real solution is for html
not to return a string, but I haven't worked out an efficient design for that yet. It might be that a performance hit is just something we need to take, but I'd like to explore all options first.
from hiccup.
Thanks a lot for the detailed reply! In my case I'd much prefer a safe over a fast version. I have started hacking up a custom solution which does the trick. Perhaps it would make sense if I polished it some more and then released it as a separate project? I don't want to fragment the library space too much though so if you are working on the issue and are willing to change Hiccup's default behavior in such a breaking way, let me know and I'll happily use my custom solution until that new Hiccup version comes around :-)
from hiccup.
Related Issues (20)
- Feature request for `[:<>]` HOT 4
- Shouldn't this line call the html function in hiccup2.core? HOT 1
- Hi How to write hiccup code for observable embed code in Roam ? HOT 3
- Null pointer exception with `:class` attribute containing vector nil HOT 3
- Replace license.html with license.txt (for artifact scanners) HOT 9
- Passing nil query param values to to url-encode throws exception
- New version? HOT 15
- :script async HOT 1
- Clojerl support HOT 2
- Historical question: Why is hiccup called hiccup? HOT 2
- link to api docs in project description is broken HOT 3
- Please remove.
- Fragment equivalent for the back end. HOT 2
- *escape-strings?* HOT 1
- hiccup.core/h not backward-compatible HOT 1
- Getting RuntimeException: no such var util/raw-string HOT 2
- Parameters for iframe src attribute HOT 8
- clj-kondo exported config HOT 4
- void-tags might not be complete HOT 3
- "Method code too large!" when compiling the hiccup2.core/html macro HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from hiccup.