Printing HTML code inside Meteor Template - meteor

How can I print HTML code inside a Meteor template using handle/spacebars?
When I try to manipulate the <div> element using a simple variable containing a style="" code, it generates an error. For example:
<div {{style}}>
// Something in here.
</div>
Will fail if {{style}} is something along the line of 'style="something: something;"' set from the Template.helpers.
How can I print HTML code inside the template?

What you're trying to do here in particular:
<div {{style}}>
<!-- Something in here. -->
</div>
With {{style}} evaluating to 'style="key: value;"' is impossible in Blaze, however it will work if {{style}} evaluates to an object {style: "key: value;"}. Alternatively, this will also work:
<div style="{{style}}">
<!-- Something in here. -->
</div>
With {{style}} evaluating to the string key: value.
The triple brace {{{helper}}} cannot be used to insert attributes, but it can otherwise be used to insert arbitrary HTML nodes without escaping. If you use it, be sure you aren't opening up an XSS hole.
See this meteorpad.

I don't know if it's possible to use variables inside an HTML tag, but if want to pass HTML code from your variable to the client, simply use {{{variable}}} instead of {{variable}}.

Related

Data-Link to CSS background-image using a helper function not render

I have a template which renders a background image to CSS within a <div> like this
style="background-image: url({{>~facilityImagePathDisplay(#data)}})"
Visual Studio doesn't like this and it's not a big deal but I wanted to see if there was a proper way to do this. I read through the documentation. Other stack questions and the below was created based off of the docs. This specifically links to all the docs Logic in JsViews css-tag
<div class="tile-image" data-link="css-background-image{:~facilityImagePathDisplay(#data)}" >
The above statement outputs exactly this to the div. <div class="tile-image" data-link="css-background-image{:~facilityImagePathDisplay(#data)}"> so it looks like it's not firing the helper function and rendering anything at all. Am I missing something?
It depends if you are running the link() method of JsViews, or simply the render() method of JsRender.
Your first version will works in both cases, but is simply rendering the CSS style.
The second version would only be used if you are running the link() method of JsViews - for data-binding etc. (So the background image could be dynamically updated if you data-binding triggers a new value).
For the data-link version, you need to makes sure the helper is returning a string that is not just "someUrl", but "url(someUrl)" - to provide the correct CSS data url syntax. In that case, the following should work:
data-link="css-background-image{:~facilityImagePathDisplay(#data)}"
Alternatively you can have the helper return just the "someUrl" string, but then include the "url(" and ")" strings in the template:
data-link="css-background-image{:'url(' + ~facilityImagePathDisplay(#data) + ')'}"

What's a clean way to have a conditional container in handlebars?

When there is a link present, we want something like this HTML:
<img src="{{src}}"></img>
When there is no link present, we want something like this HTML:
<img src="{{src}}"></img>
Is there a clean way to do this? I consider the following solution bad, because it's dangerous to have to separately remember to open and close the <a> tag:
{{#if url}}<a href="{{url}}" title="{{title}}" target="_blank">{{/if}}
<img src="{{src}}">
{{#if url}}</a>{{/if}}
I considered using a block helper, but can't think of how to do so without adding more complexity. Maybe something like:
{{#linkWrap url}}<img src="{{src}}">{{/linkWrap}}
But then it's hard to see how we set the title and target and everything gets awkward.
I think you are on the right track, but I would recommend using a Handlebars Partial Block instead of a Block Helper. This will allow to pass one piece of template (the block) to another piece of template by which it will be wrapped (the partial).
Handlebars provides us with {{> #partial-block }} as a way to render a block of template within a partial. We can use this to create our "linkWrap" partial:
{{#if link}}
<a href="{{link.url}}" target="{{link.target}}" title="{{link.title}}">
{{> #partial-block}}
</a>
{{else}}
{{> #partial-block}}
{{/if}}
This gives us a clean and simple partial that will allow us to wrap any section of our template with a link as long as we have a link object to pass to our partial. Note that I have opted to use an object to represent the link so that I can pass a single parameter to the partial instead of passing the url, title, etc. properties individually.
For anywhere we wish to render a link around some markup in our template, we can do so in the following way:
{{#> linkWrap link=link}}
<img src="{{image.src}}">
{{/linkWrap}}
If the link object is null or undefined, the img element will be rendered without a parent anchor element.
I have created a supplementary fiddle for reference.

Insert custom HTML in page DOM with Google Tag Manager

I've implemented GTM on my website. I'm wondering if is possible to add custom HTML/JS in a specific position of the DOM.
This is what I've inserted in my page:
<div class="myClass">
<p>foo</p>
<script>
dataLayer.push({'event':'myEvent'})
</script>
</div>
and on GTM I've set up a tag with this html:
<div class="test">this is a test</div>
<iframe src="www.foo.com" />
which is triggered on myEvent.
Unfortunatly this is not working correctly, my tag is inserted at the bottom of my web page and not inside the myClass div.
Am I doing something wrong or this is just not allowed by GTM?
Thanks.
"Not allowed" is perhaps a bit strong (as you can see it works to some extent), but tags that change visual aspects of the page are generally not recommended.
If you want to insert HTML at a specific location it would be better to create the element dynamically via javascript and append it to an existing element, so your HTML tag would look something like (untested):
<script>
var myDiv = document.createElement('div');
myDiv.setAttribute('class','test');
var container = document.querySelector('.myClass');
container.append(myDiv);
</script>
You would need to make sure that the element you append to is unique (if possible add an id rather than a class name). Tags are executed asynchronously, so it's a bit hard to say at which point in the loading process the HTML is appended (this will cause a reflow in the DOM which is an expensive operation for the client, so you do not want to do this too often).

Wrapper for custom Content Part - Orchard CMS

Using the Orchard admin I created a new Content Part called 'Spotlight Wrapper' with 3 HTML fields. I then created a Content Type Called 'Template 1' and assigned 'Spotlight Wrapper' to it. I then created a new 'Template 1' content item called 'Home Page'. I then created a file called Fileds_Contrib.Html-Spotlight Wrapper.cshtml to wrap each HTML field in the 'Spotlight Wrapper' with an and this is working. I have now added:
<Place Parts_SpotlightWrapper="Content:before;Wrapper=Parts_SpotlightWrapper" />
And created :
Views\Parts.SpotlightWrapper.cshtml
in an attempt to wrap the entire 'Spotlight Wrapper' Content Part in a but cannot seem to get it to work?
You declared a wrapper which I guess would lead to circular reference, as you try to wrap the Parts_SpotlightWrapper shape with itself. Wrappers are just separate pieces of Razor (cshtml) code that act as a parent for a given shape.
To achieve the behavior you want you should create a separate .cshtml file (eg. MyWrapper.cshtml) containing the necessary wrapper HTML code and attach it to your existing part like this:
<Place Parts_SpotlightWrapper="Content:before;Wrapper=MyWrapper" />
The wrapper code could look eg. like this:
<ul>
#Display(Model.Child)
</ul>
Btw - Try to look how it's done in Orchard.Widgets. There are two wrappers Widget.Wrapper and Widget.ControlWrapper that wrap the Widget shape. Declarations of those are not inside the Placement.info file (as you did), but hardcoded in Shapes.cs shape definition, though the final effect is perfectly the same. The technique with the Placement.info was just introduced later as a shortcut.
HTH

Dynamically generated HTML in C# to be formatted

I have an ASP.NET web forms site with a rather large menu. The HTML for the menu is dynamically generated via a method in the C# as a string. I.e., what is being returned is something like this:
<ul><li><a href='default.aspx?param=1&anotherparam=2'>LINK</a></li></ul>
Except it is a lot bigger, and the lists are nested up to 4 deep.
This is written to the page via a code block.
However, instead of returning a flat string from the method I would like to return it as formatted HTML, so when rendered it looks like this:
<ul>
<li>
<a href='default.aspx?param=1&anotherparam=2'>LINK</a>
</li>
</ul>
I thought about loading the html into an XmlDocument but it doesn't like the & character found in the query strings (in the href attribute values).
The main reason for doing this is so I can more easily debug the generated HTML during development.
Anyone have any ideas?
Maybe you can work with an HtmlTextWriter? It has Indenting capabilities and it may actually be a cleaner thing as you could write straight into the output stream, which should be more "in the flow" than generating a string in memory etc.
Is there a reason you want to do this? This implicitly minified HTML will perform slightly better anyway. If you do still need to render the HTML for pretty display, you will either need to incorporate indentation into the logic that generates the output HTML or build your content using ASP.NET controls and then call Render().
Try loading the HTML into the HTML Agilty Pack. It is an HTML parser that can deal with HTML fragments (and will be fine with & in URLs).
I am not sure if it can output pretty printed (what you call "formatted") HTML, but that would be my first approach.
I like to use format strings for this sort of thing, your HTML output would be generated with;
String.Format("<ul>{0}\t<li>{0}\t\t<a href='{2}'>{3}</a>{0}\t</li>{0}</ul>",
System.Environment.NewLine,
myHrefVariable,
myLinkText);

Resources