Create the stack template
Each stack requires a Knockout template called
stack.template
to render the stack.
The stack.template
file must reside in the /stack/<stack-type>/templates
directory. Using the stack’s RegionViewModel
object, the stack.template
can access the sub-regions within the stack, via the regions
observable array, and the widgets within each sub-region, via the widgets
observable array for each sub-region.
This section provides some examples to show you how you might create a template that integrates Bootstrap UI controls with a stack’s content. The following code sample shows the stack template for a tabbed container:
<div class="tabbedContainer">
<!-- RENDER Bootstrap tabs -->
<ul class="nav nav-tabs" data-bind="attr: { id: 'tabbedNav-'+id()+'-pills'}">
<!-- ko foreach: regions -->
<li role="presentation" data-bind="css: {active: $index() === 0},
attr: { id: 'tabbedNav-'+$parent.id()+'-pill-'+$index() }">
<a data-toggle="tab" data-bind="
attr: { 'href':'#tabbedContainer-' + $parent.id() + '-tab-' + $index()}">
<span data-bind="text: displayName"></span>
</a>
</li>
<!-- /ko -->
</ul>
<!—RENDER tabbed content --> <div class="tab-content">
<!-- ko foreach: regions -->
<div role="tabpanel" class="stage tab-pane" data-bind="
attr: { id: 'tabbedContainer-'+$parent.id()+'-tab-'+$index() },
css: {active: $index() === 0}">
<!—RENDER widgets in each tab -->
<!-- ko foreach: widgets -->
<div data-bind="
template: {name: templateUrl(),templateSrc: templateSrc()}">
</div>
<!-- /ko -->
</div>
<!-- /ko -->
</div>
</div>
This template includes two ko foreach: regions
bindings. The first iterates over the stack’s sub-regions and creates a tab for each sub-region. The second iterates over the sub-regions again and renders the contents of each tab. The content rendering is accomplished through a ko for each: widgets
binding that iterates over the widgets contained in each sub-region.
Similarly, the following code excerpt shows the rendering of widgets in collapsible panels:
<!-- RENDER displayName from the stack -->
<h2 data-bind="text:displayName"></h2>
<div class="panel-group" id="accordion" role="tablist">
<!-- RENDER stack sub-regions -->
<!-- ko foreach: regions -->
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion"
data-bind="attr: {
'href': '#accordionContainer-' + $parent.id() + '-tab-' + $index()},
text:displayName" aria-expanded="true" aria-controls="collapseOne>
</a>
</h4>
</div>
<div class="panel-collapse collapse" role="tabpanel"
aria-labelledby="headingOne"
data-bind="attr: {
id: 'accordionContainer-'+$parent.id()+'-tab-'+$index() },
css: {in: $index() === 0}">
<div class="panel-body">
<!-- RENDER widgets within each sub-region -->
<!-- ko foreach: widgets -->
<div data-bind="template: {
name: templateUrl(),
templateSrc: templateSrc()}">
</div>
<!-- /ko -->
</div>
</div>
</div>
<!-- /ko -->
</div>
This code iterates over the sub-regions in the stack and renders a collapsible panel for each one. To define the content for each panel, the code iterates over the widgets in each sub-region and renders them using the template defined in the template
data-bind.