How to use an HTML minifier with underscore templates - javascript

I have some templates for my frontend code, like:
<div class="row">
<div class="my-header col-md-1">
<!-- comments -->
{{ title }}
</div>
<div class="my-container col-md-11">
{% if (content) { %}
{{ content }}
{% } else { %}
<p>Empty</p>
{% } %}
</div>
</div>
And I'm using grunt-contrib-jst to store them all in a single file and then on another build step will be included in a single JS file and that file is pushed to the CDN. This part is working perfectly, but I want to use the processContent option to minify the HTML template code, which contains Undercore template delimiters (<%...%> replaced with {% ... %}, <%= ... %> replaced with {{ ... }}).
I wanted to use html-minifier but it doesn't actually minimize anything, apparently because it tries to parse the template as HTML-only (and fails because of the templating tags).
Is there any Node package / function that allows me to minimize this kind of templates? I would like to use comments and whitespace in source templates but strip everything unnecessary on the resulting build file.
Right now I have this on my JST settings:
processContent: function (content) {
return content
.replace(/^[\x20\t]+/mg, '')
.replace(/[\x20\t]+$/mg, '')
.replace(/^[\r\n]+/, '')
.replace(/[\r\n]*$/, '\n');
},
...
But I want to minimize everything possible, that's why I tried with html-minifier.
Thanks!

I can't really help with minimising the underscore template delimiters, still trying to find out the best way to do that myself, but you might want to consider running your templates through htmlclean. I use it with r.js and it works really well for stripping out newlines and spaces in the code. Example usage:
var htmlclean = require('htmlclean');
// ...
processContent: function (content) {
return htmlclean(content)
.replace(/^[\x20\t]+/mg, '')
.replace(/[\x20\t]+$/mg, '')
.replace(/^[\r\n]+/, '')
.replace(/[\r\n]*$/, '\n');
},
I've had no problems with using this on HTML that has underscore templates in there. I hope it helps you.

Related

Using {% include 'includes/some.html' %} in django template

I have a template as under:-
<div class= "comment-form m-2">
{% include "includes/comment_reply_form.html" %}</div>
If the user is authenticated then the html shows the form. However if the user is not logged in I want to show a Login button. I am handling the same by the following javascript.
$(".comment-reply-btn").click(function(event){
event.preventDefault();
if (user_is_authenticated === false) {
$(".comment-form").html('{% include "includes/reply.html" %}');
$(this).parent().next(".comment-reply").fadeToggle();
}
else {
$(this).parent().next(".comment-reply").fadeToggle();
}
});
But, instead of including the html in from reply.html, it is showing {% include "includes/reply.html" %} in the webpage. There is no problem with the javascript and if I add
<p> You need to Login </p>
in the following line. It works fine :-
$(".comment-form").html('{% include "includes/reply.html" %}');
But since I need more options in my reply.html I want to add it as includes. I have tried using the escape character "/" in front of { but it didn't help.
not familiar but try
<div class= "comment-form m-2">
<script>
document.write('{% include "includes/comment_reply_form.html" %}')
</script>
</div>
Instead of putting the value from include in your javascript function just put it in the html with with display = none for example
<div id="comment-reply-form-template">
{% include "includes/comment_reply_form.html" %}
Then in your javascript you can always clone the already rendered form when you need to...
Or you could make a custom template tag that will print the html in javascript string style with a bunch of '' + '' + ''
or prehaps look into the new es6 template strings
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/template_strings
I think would work like
`{% include "includes/comment_reply_form.html" %}`
using the ` character

Extending Markdown tags without processing the code

I am working with Hexo - a nodeJS based static blogging CMS, I am extending the hexo API to register a new block tag called tabblock, see here:
hexo.extend.tag.register('tabblock', function (args, content) {
var tabNumber = NumberOfTabs(content);
var isTabbed = (tabNumber !== 0);
console.log("Args: " + content);
// Where my proper logic should go
result = '<h1> TAG </h1>';
return result;
}, { ends: true });
This is the source snippet I am trying to interpret:
{% tabblock %}
``` JavaScript
console.log("Double Tap");
```
``` TypeScript
console.log("Double Tap");
```
{% endtabblock %}
However, the console.log from the function which should be processing that source, outputs this:
Args: <!--0--> <!--1-->
??? I Assume this is because the code is being interpreted as code rather than content? So if I wrap the {% tabblock %} in {% raw %} tags then I get no output at all, however, if I put the raw tags inside the tabblock, then I get this output:
Args: {% raw
How can I get my desired content?
\``` code ```\ is interpreted by Hexo as a code block, that why it output a messy thing. Try with only 2 or 1 backstick, it will works; like this \`` code ``\
I created a tabbed-codeblock tag for Hexo, you should take a look how I did it. As you can see, I wrapped code with the hexo tag and I use this structure to separate code blocks to avoid conflict with source code.
<!-- tab [lang] -->
code
<!-- endtab -->
<!-- tab [lang] -->
code
<!-- endtab -->
Gist : source code of tabbed code block tag + JS code to animate the component in the browser
SO Question - How to implement a tabbed codeblock tag for Hexo : because I created this tag for this question :p Read it, I explained the whole process :)
JSFiddle demo

Django, html tags not interpreted

I am loading a text from the DB of a django project to display it in the template.
In the text stored within the data base, I added some HTML tags but it seems like the browser cannot interprete this html tags.
Here is my template:
<div>
<!-- body_text = "<strong>Hello</strong> word" -->
{{ entry.body_text }}
</div>
And I got the raw text: <strong>Hello</strong> word instead of
<strong>Hello</strong> word
What I am doing wrong?
If you don't want your HTML to be escaped, use safe filter:
{{ entry.body_text|safe }}
django doc about safe filter.
You can also try this:
{% autoescape off %}
{{ your_html_content }}
{% endautoescape %}
From django docs for autoescape:
Controls the current auto-escaping behavior. This tag takes either
on or off as an argument and that determines whether auto-escaping is in effect inside the block. The block is closed with
an endautoescape ending tag.
When auto-escaping is in effect, all variable content has HTML
escaping applied to it before placing the result into the output (but
after any filters have been applied). This is equivalent to manually
applying the escape filter to each variable.
As pointed out in the other answer, you can also use safe filter which:
Marks a string as not requiring further HTML escaping prior to output.
When autoescaping is off, this filter has no effect.
See here: safe filter.
Read more about django template tags and filters: Django Built-in template tags and filters

Render an embedded partial template from a pre-compiled template using handlebars?

I have a pre-compiled handlebars template that is rendering as expected.
I've decided to add an embedded (not pre-compiled) partial reference to the template that I'm pre-compiling but the content of the partial is not rendering properly.
The end result is that the contents of the embedded partial are included in the rendered HTML (I suppose my partial is "partially" working :-D ), but:
the name of the partial is also included on each line
the expression in the partial is not populated with my data
This is the HTML that is rendered. The 3 lines from the partial named templateBodyItemNumberPartial are listed below (the partial name seems to be prefixed to each line of output) and no data is rendered in the <span>:
<div class="templateBodyItem">
templateBodyItemNumberPartial
templateBodyItemNumberPartial <span class="templateBodyItemNumber"></span>
templateBodyItemNumberPartial
this is my body text
<div class="templateBodyItemFooter">this is my footer text</div>
</div>
This is the main, pre-compiled template that references the templateBodyItemNumberPartial partial:
{{! templates/nameWithPartial.handlebars }}
{{! precompiled via: handlebars ./templates/nameWithPartial.handlebars -f external_template_with_partial.js }}
<div class="templateBodyItem">
{{> templateBodyItemNumberPartial }}
{{ templateBodyItem }}
<div class="templateBodyItemFooter">{{ templateBodyFooter }}</div>
</div>
This is the .html file where I define/register the partial and invoke my pre-compiled nameWithPartial template:
<script type="text/javascript" src="./handlebars-v2.0.0-alpha.4.js"></script>
<script type="text/javascript" src="./external_template_with_partial.js"></script>
<script id="templateBodyItemNumberPartial" type="text/x-handlebars-template">
<span class="templateBodyItemNumber">{{ templateBodyItemNumber }}</span>
</script>
var templateBodyObject = {
templateBodyItemNumber : 4 ,
templateBodyItem : 'this is my body text' ,
templateBodyFooter : 'this is my footer text'
};
// verify that the partial html is what I think it should be
console.log( $( '#templateBodyItemNumberPartial' ).html() );
//=> <span class="templateBodyItemNumber">{{ templateBodyItemNumber }}</span>
Handlebars.registerPartial( 'templateBodyItemNumberPartial' , $( '#templateBodyItemNumberPartial' ).html() );
var templateHtml = Handlebars.templates.nameWithPartial( templateBodyObject );
I'm attempting to use an embedded partial just to test how partials work in handlebars.
Can anyone confirm if this functionality is supported OR do I have to use pre-compiled partials if my main template that references the partial is pre-compiled?
Many thanks!
BTW, I'm running Win7 Pro 64-bit but hopefully that's not the issue...
This issue seems to be solved by rolling back handlebars to #1.3.0.
I changed one line of code above from:
<script type="text/javascript" src="./handlebars-v2.0.0-alpha.4.js"></script>
to:
<script type="text/javascript" src="./handlebars-v1.3.0.js"></script>
Then I rolled back the handlebars CLI to #1.3.0:
$ npm install -g handlebars#1.3.0
and re-compiled the external template:
$ handlebars ./templates/name_with_partial.handlebars -f external_template_with_partial.js
I'm guessing there is either an issue with partials and #v2.0.0-alpha.4 OR the partials functionality in this latest version has changed. I deserve what I get for using something with "alpha" in the name. :)
Oh well, thanks for listening.

Is there any way to load, minimize and combine different javascript files for different templates in Django?

Now, I put some common javascript files in PIPELINE_JS settings. But I also want to load more specific js files based on each individual template. I know I can simply add a script tag to include corresponding js files in each template, but that would add additional request to server, which is not a good idea I think. The ideal way I want to do is to use PIPELINE to load, minimize and combine different js files based on different templates. Is there any way to do this?
Yes, It is very simple:
PIPELINE_JS = {
'stats': {
'source_filenames': (
'js/jquery.js',
'js/application.js',
),
'output_filename': 'js/stats.js',
},
'logged_in': {
'source_filenames': (
'js/jquery.js',
'js/collections/*.js',
'js/application.js',
),
'output_filename': 'js/logged_in.js',
},
#and so on..
}
and while including in the template,
{% load compressed %}
{% compressed_js 'stats' %}
In another template where you wish to import the other target,
{% load compressed %}
{% compressed_js 'logged_in' %} {# or whichever you wish to import #}
Read the documentation for better understanding.

Categories

Resources