Go - HTML comments are not rendered - html

I'm building go web application. I found some anomaly on the rendered html page. All of my html comments <!-- --> are suddenly not being rendered. My guess it's because the go version I used (just updated to higher version), because it was fine before I updated it.
This is my code:
<!-- prepare the breadcrumbs -->
<ul class="breadcrumb" data-bind="foreach: viewModel.breadcrumbs">
<!-- ko if: ($index() + 1) < len(viewModel.breadcrumbs()) -->
<li>
<a data-bind="attr: { href: href }">
<i class="fa fa-home"></i>
<span data-bind="text: title"></span>
</a>
</li>
<!-- /ko -->
<!-- ko if: ($index() + 1) == len(viewModel.breadcrumbs()) -->
<li class="active" data-bind="text: title"></li>
<!-- /ko -->
</ul>
And this is the rendered page source:
Because of this issue, many of my KnockoutJS codes which are written using containerless control flow syntax goes crazy, it doesn't work at all.
What should I do to solve this? Thanks in advance

There is a special type in the html/template package: template.HTML. Values of this type in the template are not escaped when the template is rendered.
So you may "mark" your HTML comments as template.HTML and so they will not be escaped or omitted during executing your template.
One way to do this is to register a custom function for your template, a function which can be called from your template which takes a string argument and returns it as template.HTML. You can "pass" all the HTML comments to this function, and as a result, your HTML comments will be retained in the output.
See this example:
func main() {
t := template.Must(template.New("").Funcs(template.FuncMap{
"safe": func(s string) template.HTML { return template.HTML(s) },
}).Parse(src))
t.Execute(os.Stdout, nil)
}
const src = `<html><body>
{{safe "<!-- This is a comment -->"}}
<div>Some <b>HTML</b> content</div>
</body></html>`
Output (try it on the Go Playground):
<html><body>
<!-- This is a comment -->
<div>Some <b>HTML</b> content</div>
</body></html>
So basically after registering our safe() function, transform all your HTML comments to a template action calling this safe() function and passing your original HTML comment.
Convert this:
<!-- Some HTML comment -->
To this:
{{safe "<!-- Some HTML comment -->"}}
Or alternatively (whichever you like):
{{"<!-- Some HTML comment -->" | safe}}
And you're good to go.
Note: If your HTML comment contains quotation marks ('"'), you can / have to escape it like this:
{{safe "<!-- Some \"HTML\" comment -->"}}
Note #2: Be aware that you shouldn't use conditional HTML comments as that may break the context sensitive escaping of html/template package. For details read this.

You can use text/template instead of html/template and do all escaping manually using built-in functions such as html and js (https://golang.org/pkg/text/template/#hdr-Functions). Be aware that this is very error prone though.

Related

Angular ignoring special characters

I'm trying to display a file name but when the name contains special characters it's completely ignored.
This is the code:
<p class="meta-description" [innerHTML]="{{ vm.previewing.filename + ' | ' + vm.previewing.emailSubject }}">
{ vm.previewing.filename }}
<span ng-if="vm.previewing.emailSubject"> | {{ vm.previewing.emailSubject }}</span>
Even adding [innerHTML] is not fixing the issue.
This is what shows up on the page if the file is named 'çx' for example:
<p class="meta-description ng-binding" [innerhtml]="x.pdf | ">
x.pdf
<!-- ngIf: vm.previewing.emailSubject -->
</p>
In case we are talking in AngularJS ,
Do you have the module angular-sanitize enabled ? If so use the ng-bind-html directive to parse special characters or markup to display. Also avoid mixing interpolation and property binding, choose only one to use.
<p class="meta-description" ng-bind-html="vm.previewing.filename + ' | ' + vm.previewing.emailSubject">
<span ng-if="vm.previewing.emailSubject" ng-bind-html="'|'+ vm.previewing.emailSubject"> </span>
A tip to make the code cleaner would be creating those string values on the controller side (like the concatenation of filename and email subject to the p element).
Please bear in mind that the bracket syntax "[]" is for Angular 2-11 property binding and not AngularJS.
Reference:
https://docs.angularjs.org/api/ng/directive/ngBindHtml

angularJS: template via custom directive not showing special characters

I'm trying to make my first AngularJS project and I stumbled upon a little issue...
I tried to create a custom directive (see apps.js extract) and copied some code into a separate html (see wishlist.html).
The custom directive works: the template file is included. BUT special characters like ë or € aren't shown via the custom directive and they are shown if I use the same code in the index.html.
Can somebody explain me why I get this behaviour and how to avoid it?
Thanks!
S.
index.html:
...
<body class="container" ng-app="gimmiApp">
<!-- Test with custom directive -->
<div ng-controller="WishlistController as wishlist">
<wishlist></wishlist>
</div>
<!-- Test without custom directive -->
<div ng-controller="WishlistController as wishlist">
<h1>Ideeën</h1>
<div class="row" ng-repeat="wish in wishlist.wishes">
<h3>{{wish.title}}
<em>{{wish.price | currency : "€" : 2 }}</em>
</h3>
</div>
</div>
</body>
...
wishlist.html
<h1>Ideeën</h1>
<div class="row" ng-repeat="wish in wishlist.wishes">
<h3>{{wish.title}}
<em>{{wish.price | currency : "€" : 2 }}</em>
</h3>
</div>
app.js:
...
app.directive('wishlist', function(){
return {
restrict: 'E',
templateUrl: 'views/wishlist.html'
};
});
...
This is what I get...
I found the problem!
My file wasn't encoded in UTF-8. Change my file's character set to UTF-8 solved my problem.

Why is HTML I put in a Mongodb document as JSON displaying as text on the webpage?

I have a mongo database with a document that contains some html in it, and when I try to take it and put it on a webpage, it just displays as the actual text and not the html. Here is the json with the html:
db.games.insert({
title: "Minecraft",
background: "/images/minecraft.jpg",
code: "<div id=\"gameBackround\" class=\"col-lg-2 popular-games view view-first\" style=\"background-image:url( /images/gameArt/minecraft.jpg )\"> <div class=\"mask\"> <h2>Minecraft</h2> <p>Amount of groups playing this title now: 11,075</p> Join Lobby </div> </div> <style> </style>"
})
and here is how I display it on the page:
<template name="example">
{{code}}
</template>
Use should use triple curly braces to escape html code returned from a helper.
<template name="example">
{{{code}}}
</template>
Here is an example.

How do I check if the result of an expression is NULL in HTML and if it is, display nothing?

<script id="namesAutoCompleteTemplate" type="text/x-kendo-tmpl">
<div class="k-widget k-grid" id="Grid">
<div class="k-grid-content">
<h3>${data.NameFirstInitLast}</h3>
<p>Person ID: ${data.PersonId}</p>
<p>Member Number: ${data.MemberNumber}</p>
<p>Member Status: ${data.MemberStatus}</p>
<p>Category: ${data.PrimaryCategoryCode}</p>
</script>
If the result of any of the expressions above (e.g. ${data.PersonId} = NULL, then display '' or nothing).
How would I go about doing this?
I gather from your <script/> tag that you are using a Kendo UI template? Therefore, the # character is used as an escape sequence in Kendo templates, so that you can insert JavaScript code to be evaluated by Kendo's templating engine. Here is an example of what you're probably looking to achieve:
<script id="namesAutoCompleteTemplate" type="text/x-kendo-tmpl">
<div class="k-widget k-grid" id="Grid">
<div class="k-grid-content">
# if (data) { #
<h3>${data.NameFirstInitLast}</h3>
<p>Person ID: ${data.PersonId}</p>
<p>Member Number: ${data.MemberNumber}</p>
<p>Member Status: ${data.MemberStatus}</p>
<p>Category: ${data.PrimaryCategoryCode}</p>
# } #
</div>
</div>
</script>
On a side note, I'm not fond of the ${} syntax, and Kendo is not very consistent with which of the three types of escape character sequences to use in their own documentation. I would suggest sticking with #=data.property# and/or #:data.property# as a matter of consistency. But, that's just my opinion. :)

Indenting generated markup in Jekyll/Ruby

Well this is probably kind of a silly question but I'm wondering if there's any way to have the generated markup in Jekyll to preserve the indentation of the Liquid-tag. World doesn't end if it isn't solvable. I'm just curious since I like my code to look tidy, even if compiled. :)
For example I have these two:
base.html:
<body>
<div id="page">
{{content}}
</div>
</body>
index.md:
---
layout: base
---
<div id="recent_articles">
{% for post in site.posts %}
<div class="article_puff">
<img src="/resources/images/fancyi.jpg" alt="" />
<h2>{{post.title}}</h2>
<p>{{post.description}}</p>
Read more
</div>
{% endfor %}
</div>
Problem is that the imported {{content}}-tag is rendered without the indendation used above.
So instead of
<body>
<div id="page">
<div id="recent_articles">
<div class="article_puff">
<img src="/resources/images/fancyimage.jpg" alt="" />
<h2>Gettin' down with responsive web design</h2>
<p>Everyone's talking about it. Your client wants it. You need to code it.</p>
Read more
</div>
</div>
</div>
</body>
I get
<body>
<div id="page">
<div id="recent_articles">
<div class="article_puff">
<img src="/resources/images/fancyimage.jpg" alt="" />
<h2>Gettin' down with responsive web design</h2>
<p>Everyone's talking about it. Your client wants it. You need to code it.</p>
Read more
</div>
</div>
</div>
</body>
Seems like only the first line is indented correctly. The rest starts at the beginning of the line... So, multiline liquid-templating import? :)
Using a Liquid Filter
I managed to make this work using a liquid filter. There are a few caveats:
Your input must be clean. I had some curly quotes and non-printable chars that looked like whitespace in a few files (copypasta from Word or some such) and was seeing "Invalid byte sequence in UTF-8" as a Jekyll error.
It could break some things. I was using <i class="icon-file"></i> icons from twitter bootstrap. It replaced the empty tag with <i class="icon-file"/> and bootstrap did not like that. Additionally, it screws up the octopress {% codeblock %}s in my content. I didn't really look into why.
While this will clean the output of a liquid variable such as {{ content }} it does not actually solve the problem in the original post, which is to indent the html in context of the surrounding html. This will provide well formatted html, but as a fragment that will not be indented relative to tags above the fragment. If you want to format everything in context, use the Rake task instead of the filter.
-
require 'rubygems'
require 'json'
require 'nokogiri'
require 'nokogiri-pretty'
module Jekyll
module PrettyPrintFilter
def pretty_print(input)
#seeing some ASCII-8 come in
input = input.encode("UTF-8")
#Parsing with nokogiri first cleans up some things the XSLT can't handle
content = Nokogiri::HTML::DocumentFragment.parse input
parsed_content = content.to_html
#Unfortunately nokogiri-pretty can't use DocumentFragments...
html = Nokogiri::HTML parsed_content
pretty = html.human
#...so now we need to remove the stuff it added to make valid HTML
output = PrettyPrintFilter.strip_extra_html(pretty)
output
end
def PrettyPrintFilter.strip_extra_html(html)
#type declaration
html = html.sub('<?xml version="1.0" encoding="ISO-8859-1"?>','')
#second <html> tag
first = true
html = html.gsub('<html>') do |match|
if first == true
first = false
next
else
''
end
end
#first </html> tag
html = html.sub('</html>','')
#second <head> tag
first = true
html = html.gsub('<head>') do |match|
if first == true
first = false
next
else
''
end
end
#first </head> tag
html = html.sub('</head>','')
#second <body> tag
first = true
html = html.gsub('<body>') do |match|
if first == true
first = false
next
else
''
end
end
#first </body> tag
html = html.sub('</body>','')
html
end
end
end
Liquid::Template.register_filter(Jekyll::PrettyPrintFilter)
Using a Rake task
I use a task in my rakefile to pretty print the output after the jekyll site has been generated.
require 'nokogiri'
require 'nokogiri-pretty'
desc "Pretty print HTML output from Jekyll"
task :pretty_print do
#change public to _site or wherever your output goes
html_files = File.join("**", "public", "**", "*.html")
Dir.glob html_files do |html_file|
puts "Cleaning #{html_file}"
file = File.open(html_file)
contents = file.read
begin
#we're gonna parse it as XML so we can apply an XSLT
html = Nokogiri::XML(contents)
#the human() method is from nokogiri-pretty. Just an XSL transform on the XML.
pretty_html = html.human
rescue Exception => msg
puts "Failed to pretty print #{html_file}: #{msg}"
end
#Yep, we're overwriting the file. Potentially destructive.
file = File.new(html_file,"w")
file.write(pretty_html)
file.close
end
end
We can accomplish this by writing a custom Liquid filter to tidy the html, and then doing {{content | tidy }} to include the html.
A quick search suggests that the ruby tidy gem may not be maintained but that nokogiri is the way to go. This will of course mean installing the nokogiri gem.
See advice on writing liquid filters, and Jekyll example filters.
An example might look something like this: in _plugins, add a script called tidy-html.rb containing:
require 'nokogiri'
module TextFilter
def tidy(input)
desired = Nokogiri::HTML::DocumentFragment.parse(input).to_html
end
end
Liquid::Template.register_filter(TextFilter)
(Untested)