How to use markdown(or any other markup -> HTML language) in a template. Is it possible with available JavaScript template engines?
Template:
This is a *sample* question?
![some_image](image/path)
{{screenshot}}
Run first your template engine.
Pass the rendered HTML to the markdown parser.
Run your markdown parser.
I leave you a snippet that uses Mustache as template engine and the JavaScript implementation of CommonMark for Markdown.
In the links above you can find the code that I used for the example.
function loadUser() {
var template = $('#template').html();
var rendered = Mustache.render(template, {
name: "*Luke*"
});
$('#target').html(rendered);
var reader = new commonmark.Parser();
var writer = new commonmark.HtmlRenderer();
var parsed = reader.parse($('#target').html());
var result = writer.render(parsed);
$('#target').html(result);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/3.0.0/mustache.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/commonmark/0.28.1/commonmark.min.js"></script>
<body onload="loadUser()">
<div id="target">Loading...</div>
<script id="template" type="x-tmpl-mustache">
This is an example of **markdown** in a *template*.
Hello {{ name }}!
</script>
</body>
Related
I would like to check using liquid language, if is there somewhere in the page, a script being called twice or more.
For example:
<script src="myscripts.js"></script>
<script src="myscripts.js"></script>
Is it possible using liquid or should I use javascript to validate?
I'm not sure about liquid, but if you wanted to go the JS route, this could work:
//locate all `<script>` tags and save the elements into an array
var scriptTags = [];
document.querySelectorAll('script').forEach(function(tag) {
scriptTags.push(tag)
});
//Put just the URLs of the script tags into an array
var scriptUrls = scriptTags.map(function(tag) {
return tag.src;
});
//Get a list of any URL that appears more than once
var duplicateUrls = scriptUrls.filter(function(url, i) {
return scriptUrls.indexOf(url) != i;
});
console.log(duplicateUrls);
<script src="dupe.js"></script>
<script src="other1.js"></script>
<script src="dupe.js"></script>
<script src="other2.js"></script>
<script src="other3.js"></script>
I've got two items in a data object which should subsitute two expressions within my html file. However this is somehow not working. Do you guys know what I am doing wrong?
<head>
<script src="jquery-1.11.3.js"></script>
<script src="handlebars-v4.0.5.js"></script>
</head>
<body>
<script type="text/x-handlebars-template">
var source = $("#template").html();
var template = Handlebars.compile(source);
var data = {
title:"The Earth seen from Apollo 11",
author:"Ed g2s",
};
var html = template(data);
</script>
<script id="template" type="text/x-handlebars-template">
<h1>{{title}}</h1>
<h3>{{author}}</h3>
</script></body>
I'm just getting started with Handlebars.js and I'm already confused by what should be included in my HTML.
I set up a minimal helloworl HTML file that looks like:
<html>
<body>
<script id="entry-template" type="text/x-handlebars-template">
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
</script>
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/handlebars/handlebars.js"></script>
<script src="bower_components/handlebars/handlebars.runtime.js"></script>
<script type="text/javascript">
var source = $("#entry-template").html();
var template = Handlebars.compile(source);
var context = {title: "My New Post", body: "This is my first post!"};
var html = template(context);
document.write(html);
</script>
</body>
</html>
and I get the following error:
[Error] TypeError: undefined is not a function (evaluating 'Handlebars.compile(source)')
global code (index.html, line 17)
What other dependency should be included for this minimal example to work?
Versions used:
jQuery 2.1.4
handlebars 4.0.2
Your call to bower_components/handlebars/handlebars.runtime.js overwrites what bower_components/handlebars/handlebars.js sets up.
Using handlebars.runtime.js implies that your templates are already compiled and thus the Handlebars object you get does not include a compile function.
Remove <script src="bower_components/handlebars/handlebars.runtime.js"></script>and you should be good to go : http://jsfiddle.net/nikoshr/dr3gwh7u/
<script src="bower_components/jquery/dist/jquery.js"></script>
<script src="bower_components/handlebars/handlebars.js"></script>
<script type="text/javascript">
var source = $("#entry-template").html();
var template = Handlebars.compile(source);
var context = {title: "My New Post", body: "This is my first post!"};
var html = template(context);
$('body').append(html)
</script>
In my application, I make an ajax call that renders this template with js:
<div id="ajax_reply">
<div id="hidden_data" style="display:none;"></div>
<script type="text/javascript">
var data = [];
data.push(['Col1', 'Col2', 'Col3', 'Col4']);
{% for entry in mydata %}
var dCell = [];
dCell.push({{ entry.Col1 }});
dCell.push({{ entry.Col2 }});
dCell.push({{ entry.Col3 }});
dCell.push({{ entry.Col4 }});
data.push(dCell);
{% endfor %}
document.getElementById('hidden_data').innerHTML = JSON.stringify(data);
</script>
</div>
This doesn't work, if I run the resulting js manually in console, it does get inserted into the div, but otherwise, the javascript is never executed. I've searched on SO but couldn't find questions on this exact topic. hidden_data is in scope, any suggestions?
EDIT:
Code seen in console after wrapping in onload (I had to make a few edits but running this manually in console works)
<div id="ajax_reply">
<div id="hidden_data" style="display:none;"></div>
<script type="text/javascript">
window.onload = function() {
var data = [];
data.push(['Col1', 'Col2', 'Col3', 'Col4']);
var dCell = [];
dCell.push('1233');
dCell.push('123312');
dCell.push('1233');
dCell.push('1482.61');
data.push(relation);
var dCell = [];
dCell.push('1231');
dCell.push('2112.0');
dCell.push('1231');
dCell.push('123123.00');
data.push(relation);
document.getElementById('hidden_data').innerHTML = JSON.stringify(relationsData);
};
</script>
</div>
If entry.Col1 contains string 'my text', resulting template will give you lines like this:
dCell.push(my text);
and, i suppose, you need
dCell.push('my text');
Make sure that this is executing after the DOM is loaded.
Try wrapping your script like:
window.onload=function(){
//script here
}
You can see on jsfiddle that this should be working.
Update:
It seems to be a problem with how Django is inserting data since it works with hardcoded sample data. Try the escapejs template filter to handle any potential javascript escaping problems. I've had to debug similar problems before with newlines and '&' symbols in particular.
dCell.push("{{ entry.Col1|escapejs }}");
I'm working with mustache.js for the first time. All the examples I'm finding seem to talk about putting everything inline, but I want my templates in external files so they can be used in multiple places. How do I do that? (I've got jQuery in my stack, if that makes a difference.)
So say I have:
template.html
{{title}} spends {{calc}}
data.js
var data = { title: "Joe", calc: function() { return 2 + 4; } };
index.html
<script type="text/javascript" src="data.js"></script>
<div id="target"></div>
<script type="text/javascript">
var template = ?????? // how do I attach the template?
var html = Mustache().to_html(template, data);
$('#target')[0].innerHTML = html;
</script>
template = $('.template').val();
Where your template is in the DOM...
<textarea class="template">
<h1>{{header}}</h1>
{{#bug}}
{{/bug}}
{{#items}}
{{#first}}
<li><strong>{{name}}</strong></li>
{{/first}}
{{#link}}
<li>{{name}}</li>
{{/link}}
{{/items}}
{{#empty}}
<p>The list is empty.</p>
{{/empty}}
</textarea>
You could also render multiple templates directly into your page...
<script id="yourTemplate" type="text/x-jquery-tmpl">
{{tmpl "#yourTemplate"}}
<div>Something: ${TemplateValue}</div>
</script>