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, this 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.