Handlebars reference component one directory up - ember.js

I have the following code:
{{#tabs-controls initial='content' modal="true" title="Hotspots" tabs=tabs style="on-ground" as |uniqueTarget currentTab|}}
<div class="tab-pane active" id="content-{{uniqueTarget}}" role="tabpanel">
//... Code
</div>
{{/tabs-controls}}
However tabs-controls is a component that lives outside the directory of the component calling it.
-components
-tabs-control
-hotspots
-hotspots-container
-hotspots-content
-template.hbs
I've tried:
{{#../tabs-control}}
{{#../..tabs-control}}
Both again without the pound sign...All I get are compiler errors.
What is the right way to achieve this?

This sort of relative path in Handlebars is more about navigating the rendering contexts than about file layout. Using the example from the Handlebars documentation, if you were using the context-switching version of each you could do:
{{permalink}}
{{#each arrayOfObjects}}
{{..permalink}} <!-- you are accessing the permalink property above -->
{{permalink}} <!-- you are accessing the permalink property of the of the object being "eached" -->
{{/each}}
However, this doesn't apply to Ember since the context-switching forms of helpers were removed.
The way to think about the path to components is that /components is the root, so if you have /components/tabs-control, the way you call it is {{tabs-control}}. If you want to render /components/hotspots/hotspots-container, the way to do it is {{hotspots/hotspots-container}}.

Related

how to call an element in another layer hbs

There are two hbs files, one is under another layer, for example:
testA.hbs contains,
<div>
{{/testB.hbs}}
</div>
<div id="area">
Hello, world
</div>
At testB.js, I want to call the id area which is presented at testA.hbs. How can I achieve this?
Based on my understanding on what you need, you want to pass the property id from one template test-a to another template test-b.
So in order to make a property id available to your template test-b, you must pass it in like this {{test-b id="area"}}
Now you can access the property id in your
test-b.hbs as {{id}}
test-b.js as this.get('id')
Have a look at my ember-twiddle for a working example. Replicated the same scenario with two components.

Inner renderings not displaying

In a page, I have a rendering with a placeholder, Offcanvas.cshtml
<div data-ads-offcanvas-id="#Model.Id" class="ads-offcanvas #Html.GetCssStyles()">
#{
<a data-ads-offcanvas-trigger-id="#Model.Id" class="ads-close-button" href="#0">X</a>
#Html.Sitecore().Placeholder(LayoutHelper.GetPlaceholder(Placeholders.AccordionSection, Model.Id))
}
and inside that rendering, I plan to put another rendering with a placeholder named Modal.cshtml
<div data-ads-modal-container="#Model.Id" class="ads-modal-container">
<div class="ads-modal-dialog">
<div class="ads-close-box">
<a data-ads-modal-id="#Model.Id" href="#0">X</a>
</div>
<div class="ads-modal-content">
#Html.Sitecore().Placeholder(LayoutHelper.GetPlaceholder(Placeholders.AccordionSection, Model.Id))
</div>
</div>
So it looks like:
-Offcanvas
+-Modal
++-Text content
When I put text content inside the Modal rendering, the content is not rendered. I'm guessing that it only renders that first few renderings and fail to do so when the renderings became highly nested.
Is there a solution to render components to the very-most child?
Thanks guys!
EDIT:
Here's the code for GetPlaceholder:
public static string GetPlaceholder(string name, Guid id)
{
return $"{name}_{id}";
}
Dynamic placeholders are a bit more complicated than generating a unique placeholder key. The generated key still needs to resolve back to a real placeholder that is defined in Sitecore.
Check out the Integrated Dynamic Placeholder module.
This will provide an Html helper similar to your current implementation:
#Html.Sitecore().DynamicPlaceholder("[Placeholder Name]")

Replace string in HTMLbars/Handlebars expression with component

I've got a blog. Each blog-posts can have multiple downloads. For the downloads I created a component downloads
Currently I render them at the end of each post like this:
{{#each download in sortedDownloads }}
<p>
<a class="dl-button" {{ action "incDownload" download }}>
{{ download.name }} ({{ download.size}}MB)
</a> - {{ download.downloadcount }} Hits
</p>
{{/each}}
I'd like to be able to write something like [downloads] in the post content itself (which is simply rendered via {{{post.parsedBody}}}and replace it with a partial like the above one.
Is this possible or do you have a better way to achieve this?
This does not really look achievable by using either outlet or yield, since the post content will not be interpreted by the render engine.
What should be working though is to have the placeholder in your content just as you mentioned it, and replace it by some identifiable HTML placeholder in your post.parsedBody.
You could then create a View on didInsertElement, and call that view's appendTo() method to render the downloads inside the placeholder.
One could say writing some jquery-ish elements also works, but I think inserting arbitrary elements in the views tree is horrible and goes against the Ember way of managing views tree.
Cheers!

Sitecore Cache from Standard Value

One sublayout (.ascx) is using datasource from its template standard value.
Whenever I enable the cacheable setting with varyByData and varyByParm, I can't get all field values in __Standard Value of its template.
I checked cache.aspx page and it shows:
**web[standardValues]________0________0________0________10MB<br />
MaxSize is 10MB, but zero Count, zero Size and zero Delta information.**
Any ideas of how to solve this?
=============Update=============
I have fields in a template for CSS class names, such as h1, ul class, etc ... and all names initially set in its "__Standard Values".
Then, I have an item which calls the template's standard values as data-source.
This is another my post and it will help you more.
Sitecore Cache Issue
Could I know what the problem is?
=============Update 2=============
Current .cs file to get field values.
<asp:View ID="viewNormalMode" runat="server">
<nav class='<% Response.Write(myDataSourceItem.Fields["Nav Bar Class"]); %>'>
<h1 class='<% Response.Write(myDataSourceItem.Fields["Label h1 Class"]); %>'>
<i class='<% Response.Write(myDataSourceItem.Fields["Label i Class"]); %>'></i>
<% Response.Write(myDataSourceItem.Fields["Nav Bar Label"]); %>
</h1>
<ul class='<% Response.Write(myDataSourceItem.Fields["ul Class"]); %>'>
<asp:Literal ID="linkObjects" runat="server"></asp:Literal>
</ul>
</nav>
</asp:View>
Hope I understand correctly.
How Sitecore Cache work on sublayouts: Let take a main navigation (as sublayout) when you enable the cacheable setting global or from page to page you will get this result:
How your navigation looked at first page access after AppPool restart or application DLL update will look the same way on all other pages having cache on sublayout (even if you use another data source or something else, the code is cached/not executed).
But I think you have another bigger problem, move your fields for selection from Presentation Sublayouts on Data Template (Items) you will have huge problems on Locales. Beside you can add from code your classes as this:
You know your Layout, case you are in it, and you know you Context Item or your page definition Item, base on template name (Context.Item.TemplateName == "Article") put your CSS classes

How to extensively configure an Ember.Component

I am creating an Ember.Component which displays a CRUD table. As the component shall be reusable it needs a lot configuration, such as columns to display, pagination options, etc. ...
At the moment I am inserting the component using handlebars:
<div class="some-div">
{{power-table items=this.model columns='...'}}
</div>
I wouldn't want to use this nice way of inserting a component. However, it is pot really possible to extensively configure a component here, is it? I found out it's not even possible to pass an object as parameter, e.g. the following it not possible:
<div class="some-div">
{{power-table items=this.model columns=[id, name, foo, bar] }}
</div>
How and where should I configure the component?
What you can do is that instead of setting columns=[id,name,foo,bar] in the handlebar like this:
<div class="some-div">
{{power-table items=this.model columns=[id, name, foo, bar] }}
</div>
You can set the columns property in the controller for the handlebar template and use the name of the property in the handlebar file. So all the logic would come from the controller and the handlebar would just tell which property is accessible in the component and by what name. So the controller for the enclosing template would be the best place to heavily configure the component. Have a look at the following page for more info:
http://emberjs.com/guides/components/passing-properties-to-a-component/
I am not sure if I understood your problem correctly.