I am currently working on a component that looks like this:
<pre v-highlightjs>
<code>
<slot></slot>
</code>
</pre>
So the problem I have is that when I am writing html inside the slot, this html is rendered and not shown as a string or code-sample in my case. I have tested it with escaped < and > and it works. How can I access the html inside the slot and escape it automatically?
Thank you
EDIT:
I use highlight.js for that component to highlight the code inside my component. highlight.js can highlight html aswell. When I put e.g.
<html><head></head><body></body></html>
inside my slot, the box is shown, but the input is rendered as html. So I want to escape the html-Tags (and other code-snippets) so that it is shown and ofc highlighted. Hope that specifies my problem a bit more.
An important limitation to be aware of is that your HTML is not HTML, it is input to Vue's templating engine, so what a component sees in the slot may not be exactly what is in the HTML file.
Writing a directive to take HTML content and replace it with a text version of that content is pretty straightforward. Putting that in a component is also pretty straightforward. You can see these together in the snippet below.
What you will also see is that the Vue templating engine strips out tags that shouldn't be inside the body: the html, head, and body tags don't make it to the component. Their contents, if any, remain.
If it is important to be able to use those tags (or, for that matter, possibly invalid HTML), you will not be able to do it in a slot. You will need to have the HTML as a data string, which you can easily interpolate using the normal curlies.
new Vue({
el: '#app',
data: {
headContent: 'Something in the head'
},
components: {
htmlEscaper: {
template: '#html-escaper',
directives: {
escapeContent: {
bind(el) {
const html = el.innerHTML;
el.textContent = html;
}
}
}
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<html-escaper>
<html>
<head>
{{ headContent }}
</head>
<some-junk>
Custom tags are ok
</some-junk>
<body>
<div>This part is legit</div>
</body>
</html>
</html-escaper>
</div>
<template id="html-escaper">
<code v-escape-content>
<slot>
</slot>
</code>
</template>
Related
I have a textarea with a v-model named content. If I input some text there, it will be assigned to content.description. Now, I want to pass this to another element, namely to a div, but - here comes the tricky part - if my textarea contains some html-code, I want this html code to be interpreted as an html-code and not as a text.
For example, if I input
Some link
and I pass it to the div, I want it to be rendered as a clickable link, like
some link
and not as
Some link
Is there any way to do it?
We have to use v-html directive inorder to work. Take a look at the documentation Here, check the working snippet.
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})
.as-console-wrapper{
display:none!important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.12/vue.js"></script>
<div id="app-6">
<p v-html="message"></p>
<textarea v-model="message"></textarea>
</div>
You could use Vue v-html directive to insert Html in div.
Working example:
new Vue({
el: '#app',
data: {
html: 'Some link '
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<textarea v-model="html"></textarea>
<div v-html="html"></div>
</div>
Let's say I have a paragraph with some text that I get from some database:
<p>
{{ text }}
</p>
However, this text may contain some references to other pages in my aplication:
Sample text [reference] sample text
So I would like these references to get turned into links to said pages:
<p>
Sample text reference sample text
</p>
I tried using the replace function in the script like this:
text.replace(/\[(.+)\]/,"<a href='/path/to/$1'>$1</a>");
But the characters all get escaped resulting in the anchor html code getting shown on the page.
Is there a way to stop the characters from being escaped, or even another way to turn [references] in the middle of the text into working links to another page?
If you don't want your HTML to be escaped, use the v-html directive.
From the docs:
The double mustaches interprets the data as plain text, not HTML. In
order to output real HTML, you will need to use the v-html directive:
Example:
var app = new Vue({
el: "#app",
data: function() {
return {
text: "See defect <a href='#'>#12345</a> for details"
};
}
});
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.13/dist/vue.min.js"></script>
<div id="app">
<p>{{text}}</p>
<p v-html="text"></p>
</div>
I'm trying to include HTML tags in data rendered by Ractive.js (to auto-subscript chemical symbols, in case anyone cares), but Ractive just inserts the text rather than creating new DOM elements.
A minimal test case, adapted from the 60-second setup guide:
<script id='template' type='text/ractive'>
<p>Hello, {{name}}!</p>
</script>
<script type="text/javscript">
var ractive = new Ractive({
el: 'container',
template: '#template',
data: { name: '<b>world</b>' }
});
As you can see in this JSfiddle, the result is Hello, <b>world</b> rather than the expected "Hello, world"
I'm guessing this is to do with the way Ractive handles expressions.. but I'm not yet at the point where the source makes much sense.
Any thoughts on how I could get the intended behaviour?
Yes! You can use the triple-stache:
<p>Hello, {{{name}}}!</p>
In traditional Mustache, this means 'don't escape the value of name'. Translated to Ractive, it means 'insert the contents as HTML rather than text.
Be aware that the HTML is not sanitised before insertion, so if name came from user input there's potential for XSS and other nasties: http://jsfiddle.net/rich_harris/4jBC8/.
Currently I'm working on a Project with Handlebars (JS Template Engine) and I'm using eclipse for development.
The problem is, that eclipse doesn't offer syntax highlighting for my Handlebars-Templates. My Templates are enclosed in tags. Syntax highlighting in works as expected.
Screenshot:
Is it possible, that Eclipse also highlights this code (at the best with HTML Syntax Coloring)?
If you are using PHP, you can fool Eclipse by adding empty php tag:
<scrip<?php ?>t type="tmpl_handlebars" id="tmpl_places">
<article>
<h1>
...
</h1>
</article>
</script>
You would have to find a plug-in which supports that template engine. The HTML Editor provided by Eclipse uses the value of the type/language attributes to find the classes that provide syntax coloring, content assist, etc. The possibility is there, but out of the box, it only provides for JavaScript.
If you are ready do write a little bit of javascript, you can do this. I don't know the framwork(s) that you are using, so I will suppose that you have jQuery, but you can use the idea without using jQuery if you don't want to.
First, write all your tags that serve as template in divs with the "tmpl_handlebars" css class instead of scripts:
<div class="tmpl_handlebars" id="tmpl_places">
<article>
<h1>Hello, World!</h1>
<p>This is a template...</p>
</article>
</div>
Then, when your page has loaded, dynamically replace the div tags with the script tags, and transfer the id and the content of the div tags to the script.
With jQuery you just have to add this small script in your html head.
$(function() {
$(".tmpl_handlebars").each(function() {
var $this = $(this);
var children = $this.children().detach();
var id = $this.attr("id");
$this.replaceWith(
$('<script type="tmpl_handlebars"/>')
.attr("id", id)
.append(children);
);
});
});
This may work out of the box, but as I'm not a specialist of mustache and handlebars, I don't know exactly when they process the DOM to find the templates, so if you want to be perfectly safe, you should do this third step: Remove the script tags that include these libraries from the static html of your head, and instead, add them dynamically with javascript after the processing of the divs, so your dom is ready when the scripts arrive.
Before the last }); in the code the divs processing, add the following lines to add your scripts:
$("head").append('<script type="text/javascript"'
+ 'src="**LOCATION_OF_DYNAMICALLY_LOADED_FILE**"></script>'");
//etc...
Similar to #Neparkiraj's answer.
If you are using Django, you can add an empty tag to (I believe) "trick" Eclipse into just thinking the line is just "bad" html. Subsequent lines will then be highlighted with html syntax:
<scrip{{NONEXISTANTVAR}}t type="tmpl_handlebars" id="tmpl_places">
<article>
...
</article>
</script>
As the tag is empty, <script type="tmpl_handlebars" id="tmpl_places"> will be perfectly rendered in the final document. Note that, using Django also likely means this code sits in a {% verbatim %} block, so you can combine this code to get:
<scrip{% verbatim %}t type="tmpl_handlebars" id="tmpl_places">
<article>
...
</article>
</script>
{% endverbatim %}
All of this is kind of ugly, but leads to both correct HTML highlighting in eclipse and correct rendering in the document.
I just started using Mustache and I like it so far, but this has me perplexed.
I am using the GitHub gist API to pull down my gists, and part of what I want to do is include the embedding functionality into my page. The problem is Mustache seems to not want to have anything to do with my dynamic script tag.
For example, this works fine:
<div class="gist-detail">
{{id}} <!-- This produces a valid Gist ID -->
</div>
Additionally, this works perfect:
<div class="gist-detail">
<script src='http://gist.github.com/1.js'></script> <!-- Produces the correct embed markup with Gist ID #1 -->
</div>
If I try to pull these together, something goes terribly wrong:
<div class="gist-detail">
<script src='http://gist.github.com/{{id}}.js'></script> <!-- Blows up! -->
</div>
Chrome Inspector shows this:
GET https://gist.github.com/%7B%7Bid%7D%7D.js 404 (Not Found)
... which looks like to me something is weird with escapes or whatnot, so I switch over to the raw syntax:
<div class="gist-detail">
<script src='http://gist.github.com/{{{id}}}.js'></script> <!-- Blows again! -->
</div>
And I get the same result in Inspector:
GET https://gist.github.com/%7B%7B%7Bid%7D%7D%7D.js 404 (Not Found)
How do I get the correct values to embed in the script tag?
EDIT
I am injecting the template as follows (in document.ready:
function LoadGists() {
var gistApi = "https://api.github.com/users/<myuser>/gists";
$.getJSON(gistApi, function (data) {
var html, template;
template = $('#mustache_gist').html();
html = Mustache.to_html(template, {gists: data}).replace(/^\s*/mg, '');
$('.gist').html(html);
});
}
The actually template is inside of a ruby partial, but it is wrapped in a div (not a script tag, is that a problem?) (that's hidden):
<div id="mustache_gist" style="display: none;">
{{#gists}}
<!-- see above -->
{{/gists}}
</div>
I assume a div is ok rather than a script because in either case, I'm pulling the .html(). Is this a bad assumption?
To avoid automatic escaping in Mustache use {{{token}}} instead of {{token}}.
It seems like your template is in HTML and trying to retrieve the template using html() results in a pre-URL-escaped template to be returned. Try placing your template inside a <script type="text/html"> tag instead.
When you embed your template inside an HTML element that excepts more HTML elements as children, it may get processed by the browser as HTML. Escaping may occur. By using a <script> tag with a non-script content type, you're basically telling the browser not to touch your template.
It looks like your script is getting requested before Mustache has a chance to update the src property. What you want to do is define the template in a way that it's not parsed as part of the DOM. A common approach is to define your template inside of a <textarea> tag. This will preserve formatting and prevent character escaping.
<textarea id="gist-detail-template" style="display:none">
<script src='http://gist.github.com/{{id}}.js'></script>
</textarea>
Now, to instantiate the template:
var template = $('#gist-detail-template').val();
var html = Mustache.to_html(template, yourTemplateData);
Here's an official example: http://mustache.github.com/#demo