How can I wrap widget templates in Meteor? - meteor

Say I have a widget that is going to display a graph and another widget that will display a table in a typical dashboard. Because of the consistency of the widget's outter controls, I want to put the bootstrap panel in a template that displays consistently for all widgets, similar to the template below:
<template name="widgetBox">
<div class="col-xs-12 col-sm-6 col-md-4">
<div class="panel panel-default">
<div class="panel-heading">
{{this.title}}
<span class="pull-right clickable" data-effect="fadeOut"><i class="fa fa-chevron-down"></i></span>
</div>
<div class="panel-body">
<!-- I want the widget to go here -->
</div>
</div>
</div>
</template>
I'm not sure how to do this by iterating over a collection, because I would like to control the appearance of each of the widget bodies with their own template. For instance two table view widgets might share a template that includes sorting or filtering, while two graph widgets would have completely different requirements and layout.
Is it possible to use boilerplate html like the "widgetBox" template above while placing another template inside the panel-body?

When you want one outer template to reuse multiple inner templates you can either use a router and a {{> yield}} pattern or use dynamic templates
The former is typically used for master page layouts although you can have multiple yield's inside a layout.
The latter may be better suited for widgets.
{{> Template.dynamic template=myTemplateName [data=data] }}
where myTemplateName is the name of a helper function that returns a string corresponding to the name of a template you've created.

Related

dynamicComponent Stencil

In my Stencil theme, I am including a few different size charts for products which I intend to include by just changing the path to the size chart document. I found dynamicComponent in the Stencil docs and I thought I understood the way it worked. In my higher level partial, I am binding the string to component in this way - (product.html)
<div class="container" itemscope itemtype="http://schema.org/Product">
{{> components/products/product-view schema=true sizeChart='components/products/size_charts/tshirt.html'}}
{{#if product.videos.list.length}}
{{> components/products/videos product.videos}}
{{/if}}
{{#if settings.show_product_reviews}}
{{> components/products/reviews reviews=product.reviews product=product urls=urls}}
{{/if}}
</div>
(product-view.html)
{{#if sizeChart}}
<div class="tab-content" id="tab-sizeChart">
{{dynamicComponent sizeChart}}
</div>
{{/if}}
Where all I wish to change is the variable sizeChart in future theme maintenance. When the page renders, the place where I wrote the dynamicComponent is blank.
I used if conditionals instead of dynamicComponent. It wasn't what I thought it was.

add button is missing for Content:Toolbar

The add button that appears over the 2sxc items is missing all of a sudden. It was there a couple days agao but now when I log into any portal in my DNN instance the "+" or add button is missing
here is a screen shot:
As you can see, the change layout and edit buttons are there. Not sure why the add button disappeared.
This is true for apps that I import from the 2sxc.org website as well. So I know its not just my template becasue it also happens on all the apps I have created which use different templates.
But to be thorough, here is my template code, its token based:
<div class="kr-gallery animation">
<p>Hover or touch image and click brush icon for more details</p>
<div class="isotope_grid isotope_grid2">
<div class="isotope_main animation" data-min-width="230">
<repeat repeat="Content in Data:Default">
<div class="isotope_item kr-gallery-item sc-element">[Content:Toolbar]
<div class="photo"><a href="[Tab:FullUrl]/details/[Content:EntityId]"> <img alt="" src="[Content:Image]?h=500" />
<span class="fa fa-paint-brush"></span></a>
</div>
</div>
</repeat>
</div>
</div>
</div>
Any idea why this is?
UPDATE:
Here is my visual query:
SOLUTION:
Based on answer, I switched to razor because I am using a custom query. Here is my simple template code now:
#* this will show an "add" button if the current user is an editor *#
#Edit.Toolbar(actions: "new", contentType: "Image")
#{
// get all images as delived from the standard query
var images = AsDynamic(Data["Default"]);
}
<div class="kr-gallery animation">
<p>Hover or touch image and click brush icon for more details</p>
<div class="isotope_grid isotope_grid2">
<div class="isotope_main animation" data-min-width="230">
#foreach(var img in images)
{
<div class="isotope_item kr-gallery-item sc-element">#img.Toolbar
<div class="photo"><a href="#Link.To(parameters: "details=" + img.EntityId)"> <img alt="#img.Title" src="#img.Image?h=500" />
<span class="fa fa-paint-brush"></span></a>
</div>
</div>
}
</div>
</div>
</div>
The missing + is by design, because editors are used to the + adding an item right after the previous one. This behavior cannot be guaranteed with a query, as the order of things is determined by the query. It is even possible, that adding an item will not show up, if a query-parameter hides that item.
So the design pattern is to provide a separate + button. The easiest way is in razor, I believe the code is something like
#Edit.Toolbar(actions: "new", contentType: "your-content-type-name")
In Tokens it's a bit more messy, and you cannot conditionally check if a user has edit-permissions.
So I recommend you go the edit.toolbar way
You can also find an example of this in the blog app: http://2sxc.org/en/apps/app/dnn-blog-app-for-dnn-dotnetnuke
I could be wrong but did you recently experiment with the visual query designer? Because this could be the cause.
The most common reason is when you use a pipeline (visual query) to deliver data to a template, which is not assigned to this instance. Reason is that "add" in a instance-list of items add it to a specific position (like right after the first one). This isn't the same when you use data like a data base - as there is no sorting in that scenario. So if this is the cause, I'll help you more.

Meteor with iron-router cant get slick carousel working

I am using iron-router, i have a route "models" which has a list of items. When the user clicks one of these items a new route "model" is used, the name of the selected item is passed as a param and used to load data about that model from the database.
I want to use slick carousel, using an array of images returned from the database (based on the param).
<div id="carousel">
{{#each images}}
<div class="item">
<img src="/images/{{this}}" alt="">
</div>
{{/each}}
</div>
Where should I call the slick init?
Generally speaking, you should initialize plugins in a template's onRendered callback. In your case, that won't work because onRendered will fire before any of the images are inserted into the DOM. With other carousel plugins I've seen, the following strategy works:
Move each item to its own template (carouselItem).
Add an onRendered callback to carouselItem so that the plugin will be initialized after each item is added to the DOM.
I haven't tried this with slick carousel, but it would look something like this:
<template name="carousel">
<div id="carousel">
{{#each images}}
{{> carouselItem}}
{{/each}}
</div>
</template>
<template name="carouselItem">
<div class="item">
<img src="/images/{{this}}">
</div>
</template>
Template.carouselItem.onRendered(function() {
$('#carousel').slick();
});
Assuming slick carousel can be initialized multiple times, this approach should work. Be aware that one possible downside is that the plugin will refresh whenever images is updated. One way to fix that is to use the {reactive: false} option in your find.
Usually you would call a plugin on an element in Template.myTemplate.onRendered:
Template.xxx.onRendered(function() {
$('#carousel').slick();
});`

How do I properly implement Bootstrap carousel in Meteor?

I'm migrating some code to blaze and have hit a problem with the bootstrap carousel that I can't seem to get over.
I had the following pre blaze to set one of the carousel items active to kick the whole thing off
<div class="item {{#if active_sponsor}}active{{/if}}">
As documented, this no longer works with blaze, so I've tried modifying it to the only thing I can think of which is
{{#if active_sponsor}}
<div class="item {{#if active_sponsor}}active{{/if}}">
{{else}}
<div class="item">
{{/if}}
This all lives within an {{each sponsors}} block.
Sadly, this fails to run with an error saying unexpected {{else}} (or, if I remove the {{else}} unexpected {{/if}}
What's the correct way to do this. I'm using exactly the same pattern earlier to change a
From "Using Blaze" on github :
https://github.com/meteor/meteor/wiki/Using-Blaze#conditional-attributes-with-no-value-eg-checked-selected
So you should use this form instead, assuming that active_sponsor is the property to look for in the current data context.
Template.whatever.helpers({
isActive:function(){
return this.active_sponsor?"active":"";
}
});
<div class="item {{isActive}}">
</div>

What do i need to add to render each articles in my meteor Articles collection?

I want to render each article in my meteor Articles collection.
(File located in myProject/collections/collections.js so it should be available for both client and server)
Code in collections.js:
Articles = new Meteor.Collection('articles');
I've got the autopublish package installed and and i have inserted an object in the Article collection via the Chrome console and verified the insert via the console with: Articles.findOne()
Articles.insert({name: 'HTML5', description: 'HTML5 for beginners', src: 'https://www.youtube.com/watch?v=9gTw2EDkaDQ'})
What i have got so far is:
<head>
<title>Articles</title>
</head>
<body>
{{> main}}
</body>
My main template is the one that won't show the articles.
<template name="main">
<div class="container-fluid">
{{#each articles}}
{{> article}}
{{/each}}
</div>
</template>
And my article template which should be rendered for each of the objects in my Articles collection, looks like this:
<template name="article">
<div class="item well span4">
<iframe height="{{height}}" src="{{src}}"></iframe>
<hr>
<h4 class="muted">{{name}}</h4>
<p>{{description}}</p>
</div>
</template>
What do i need to add to render this article? And what would i have to do to render the article if i were remove the autopublish package?
What do i need to add to render this article?
You need to tell what your main template how to calculate the field articles. You simply do that by calling the helpers method on the template.
And what would i have to do to render the article if i were remove the
autopublish package?
You would need to create a publish, so the clients can get the documents in the collection by subscribing to it.

Resources