Hi,
I experienced the following issue with 1.0.0-rc-3
I have a partial which is nested in another partial.
When I am using {{{htmlText}}} (a SafeString) in the deeply nested partial and I have the string '<a>link</a>' in it, errors in the DOM hierarchy of both partials are occuring. The rendered HTML is wrong.
When I am removing just this link - it works. It works also with other HTML tags except <a></a>.
The problem seems to be another surrounding a-tag. I changed the DOM hierarchy (both versions are valid though) and it works now.
Closing as it sounds like this is resolved.
Sorry to resurrect this, but I'm having the issue as well.
It looks as though an anchor that wraps a block-level element is prematurely closed in the rendered version.
Markup:
<a href="#" title="Wrapper">
<ul>
<li>
Something
</li>
</ul>
</a>
Renders as:
<a href="#" title="Wrapper">
</a>
<ul>
<li>
Something
</li>
</ul>
I have the same issue as manikrathee described - please fix this! The original resolution the asker used was a workaround - I'm working with a requirement that needs nested a tags.
@manikrathee, @DarthDerrr, this is not a Handlebars issue, it's actually per HTML5 spec. (Something about inline elements not being able to contain block elements.)
As you can see in this fiddle,
<a href="https://flickr.com">
<div>
Foo!
<a href="https://github.com">Bar!</a>
</div>
</a>
Renders out to:
<div>
<a href="https://flickr.com">
Foo!
</a>
<a href="https://github.com">Bar!</a>
</div>
I wish I could explain why, but sadly I cannot.
@ericsoco I'm not sure that's correct. AFAIK, in HTML5, it is valid to wrap anchors around block-level elements. See also: http://html5doctor.com/block-level-links-in-html-5/
Edited to add link to spec:
http://www.w3.org/TR/html5/text-level-semantics.html#the-a-element
@manikrathee You're right. Looks like the problem I'm seeing is with nested anchor tags; your example does not have this in the markup, so is a separate issue.
I'm curious if we have a resolution for this... I'm running into the same issue.
Try it in a browser -- what does it render? I wouldn't think that Handlebars should affect this at all because it builds strings and not a DOM.
When I wrap a collection of elements around the anchor tag, the anchor tag doesn't encapsulate
the children, as the HTML tree suggests.
For example:
{{foreach data}}
<a href="#">
<aside>...</aside>
</a>
{{/foreach}}
... renders:
<a href="#"></a>
<article>...</article>
Have you had a look at the HTML source-code. Because what you see in the dev-tools is mostly the interpretation of the browser. Btw, there is no foreach
-builtin-helper in the Handlebars core. It should read {{#each}}...{/each}
with a #
Yes, the source code is what I had included above. My apologies, the forEach
method is a helper within the Ghost
library. Pretty much the same functionality. I really have no idea how to get the nested children to be wrapped by an <a>
Source:
HTML:
Hey @FarhadG what happens if you take the handlebars helpers away and code the same thing in plain HTML? I think you'll find the same thing happens, and it's due to invalid HTML nothing to do with handlebars.
Without that, it actually does what I expect for it to do. My intention is basically have an entire block of elements be able to be hyperlinked. If there's a better way or workaround, I'm open to suggestions.
Source:
HTML:
console.log( require("handlebars").compile("{{#each posts}}<a href=\"#\"><article class=\"grid item\"><div class=\"post-inside\"><h1>hello</h1></div></article></a>{{/each}}")({posts:[0]}) )
produces:
<a href="#"><article class="grid item"><div class="post-inside"><h1>hello</h1></div></article></a>
I think this is a Ghost problem.
If you view my comment from earlier, that was done within middleman and produced the same issue.
On Thu, Jul 28, 2016 at 1:11 PM -0700, "Steven Vachon" [email protected] wrote:
console.log( require("handlebars").compile("{{#each posts}}hello
produces:
I think this is a Ghost problem.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
@manikrathee
console.log( require("handlebars").compile("{{#each posts}}<a href=\"#\" title=\"Wrapper\"><ul><li>Something</li></ul></a>{{/each}}")({posts:[0]}) )
produces:
<a href="#" title="Wrapper"><ul><li>Something</li></ul></a>
I understand. I'm calling out that this isn't isolated to Ghost.
On Fri, Jul 29, 2016 at 9:07 AM -0700, "Steven Vachon" [email protected] wrote:
@manikrathee
console.log( require("handlebars").compile("{{#each posts}}
{{/each}}")({posts:[0]}) )
produces:
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
It has not be reproduced in this thread.
If there's a reproducible difference between handlebars's {{#each}}
and Ghost's {{#foreach}}
that's a Ghost bug and should be raised on https://github.com/TryGhost/Ghost. I have not been able to find one whilst testing out the cases shown in this thread.
So far as I can tell, every reported issue in this thread is due to creating illegal HTML structures by nesting handlebars helpers which create interactive content.
HTML5 does not allow interactive content inside of an tag (see this stackoverflow).
It doesn't matter if you use {{#each}}
or {{#foreach}}
, if you view source you will see the HTML structure that you expect (even if it is illegal) but if you use chrome to inspect elements on the page you will see the browser changes where it renders the end of the </a>
in order to create a valid HTML structure.
Case in point is the fiddle linked in the first response on this thread. View the frame source and you will see:
But if you inspect using chrome, you will see:
To demonstrate further, see this fiddle I created
The first example has no handlebars and is essentially the same as the previous fiddle. The browser will not render this HTML as desired because of the nested tags.
The next two examples show an each loop in handlebars, looping over some content. In the first example, the content being output is plain text & the browser renders it as desired. In the second example we use triple-braces to render HTML which contains an tag, making the HTML structure invalid and so the browser will compensate.
Here's what the chrome inspector shows:
.
Fundamentally, you cannot nest <a>
tags. Specifically to Ghost, if you want to loop over posts and wrap the content in an <a>
tag you cannot nest the {{content}}
helper within the loop. The {{excerpt}}
helper will provide an HTML-free version of the content which can be looped over and nested within an <a>
tag.
If there are further questions around how to theme Ghost, I highly recommend visiting the #themes channel on Ghost's slack rather than posting in this thread.
Most helpful comment
If there's a reproducible difference between handlebars's
{{#each}}
and Ghost's{{#foreach}}
that's a Ghost bug and should be raised on https://github.com/TryGhost/Ghost. I have not been able to find one whilst testing out the cases shown in this thread.So far as I can tell, every reported issue in this thread is due to creating illegal HTML structures by nesting handlebars helpers which create interactive content.
HTML5 does not allow interactive content inside of an tag (see this stackoverflow).
It doesn't matter if you use
{{#each}}
or{{#foreach}}
, if you view source you will see the HTML structure that you expect (even if it is illegal) but if you use chrome to inspect elements on the page you will see the browser changes where it renders the end of the</a>
in order to create a valid HTML structure.Case in point is the fiddle linked in the first response on this thread. View the frame source and you will see:
But if you inspect using chrome, you will see:
To demonstrate further, see this fiddle I created
The first example has no handlebars and is essentially the same as the previous fiddle. The browser will not render this HTML as desired because of the nested tags.
The next two examples show an each loop in handlebars, looping over some content. In the first example, the content being output is plain text & the browser renders it as desired. In the second example we use triple-braces to render HTML which contains an tag, making the HTML structure invalid and so the browser will compensate.
Here's what the chrome inspector shows:
Fundamentally, you cannot nest
<a>
tags. Specifically to Ghost, if you want to loop over posts and wrap the content in an<a>
tag you cannot nest the{{content}}
helper within the loop. The{{excerpt}}
helper will provide an HTML-free version of the content which can be looped over and nested within an<a>
tag.If there are further questions around how to theme Ghost, I highly recommend visiting the #themes channel on Ghost's slack rather than posting in this thread.