%inherit file="//layout/base.html" />
<%namespace name="lib" file="//lib.html" import="*" />
<%!
import os
import logging
import splunk.appserver.mrsparkle.lib.startup as startup
import splunk.appserver.mrsparkle.lib.i18n as i18n
import cherrypy
logger = logging.getLogger('splunk.appserver.templates.view')
successfullyRenderedPanels = {}
%>
<%def name="addPanelToSuccessfullyRenderedPanels(panelName)">
<%
successfullyRenderedPanels[panelName] = 1
%>
%def>
\
% if "templatePath" in module :
<% logger.debug('rendering module %s' % module['templatePath']) %>\
<%include file="${module['templatePath']}" args="module=module"/>\
% endif
%def>
## generates the markup for all modules within the given panel. Currently used by all view templates.
<%def name="buildPanelContents(modules, panelName)"><%
successfullyRenderedPanels[panelName] = 1
# TODO - Remove this once the params stanza is implemented everywhere
for module in modules[panelName]:
if module.has_key('params'):
for param in module['params']:
if not module.has_key(param):
module[param] = module['params'][param]
%>\
% if (panelName=="splSearchControls-inline") :
% for i in range(len(modules[panelName])) :
<%call expr="buildModule(modules[panelName][i])">%call> |
% endfor
% elif (panelName=="pageControls") :
<%countModule = False %>
% for module in modules[panelName] :
## This is hacky way to render the count module AFTER the pager module.
##<% if module.get('className') == 'Count' and VIEW['id'] == 'flashtimeline':
## countModule = module
## continue
##%>
<%call expr="buildModule(module)">%call>
% endfor
##% if countModule != False:
## <%call expr="buildModule(countModule)">%call>
##% endif
% else :
% for module in modules[panelName] :
<%call expr="buildModule(module)">%call>
% endfor
% endif
%def>
## much simpler rendering used by the top masthead modules. Currently used by all view templates.
<%def name="buildSimplePanelContainer(modules, panelName)">
% if (panelName in modules) :
<%call expr="buildPanelContents(modules, panelName)">%call>
% endif
%def>
<%doc>
This is used by the row x column layouts in dashboard.html and in builder.html
for the given row number, it will generate the internal html and overall
layout for the layoutPanels in that row.
The complexity here is considerable.
Although a lot of this is delegated to next.getDashboardPanel(), the full picture
is as follows:
this template builds a row of N * layoutPanels (where N<4 currently)
each of the N layoutPanels. can contain
-- M * "ungrouped" modules
-- P * "groups" (where P<4) each of which can contain Q actual modules.
dashboard.html uses the full range available here. See comments in that file.
builder.html has no use for the "grouped" modules so it only has the "ungrouped" ones.
%doc>
<%def name="getFloatLayoutRow(modules, row)">
<%
# this is our data structure for the panels that are defined in this row.
# the false values are placeholders.
# this ends up being a 2D matrix, where for each i, panelNamesByColumn[i] is a flat
# list of all the panelName strings (both grouped and ungrouped) for that column that
# contain 1 or more modules in the given view.
panelNamesByColumn = [false, false, false]
for col in range(1,4) :
basePanelName = 'panel_row' + str(row) + '_col'
namesInThisPanel = [];
# get the panel names for 'ungrouped' panels, (if there are any defined in the view)
if (modules.get(basePanelName + str(col))) :
panelName = basePanelName + str(col)
namesInThisPanel.append(panelName)
successfullyRenderedPanels[panelName] = 1
## move on to getting the grouped panels, if there are any.
baseGroupName = basePanelName + str(col) + "_grp"
group = 1
# if there's a gap here at the grp level, like if there's grp1, grp2, and grp7,
# then we will ignore the 7 here.
# the problem will get picked up later when we cross-check successfullyRenderedPanels[]
while (modules.get(baseGroupName + str(group))) :
panelName = baseGroupName + str(group)
namesInThisPanel.append(panelName)
successfullyRenderedPanels[panelName] = 1
group = group + 1
# we only keep getting them until we reach a column with nothing at all.
# if there's a gap at the col level, the error will be picked up later.
# (when we cross-check successfullyRenderedPanels[])
if (len(namesInThisPanel) == 0) :
break;
else :
panelNamesByColumn[col-1] = namesInThisPanel
# now that we know what we're dealing with, we have to set some css classes on the overall row.
rowClasses = ["layoutRow", "equalHeightRow", "splClearfix", basePanelName]
if (row==1) :
rowClasses.append("firstRow")
if (panelNamesByColumn[2]) :
rowClasses.append("threeColRow")
elif (panelNamesByColumn[1]) :
rowClasses.append("twoColRow")
elif (panelNamesByColumn[0]) :
rowClasses.append("oneColRow")
numberOfColumns = len(panelNamesByColumn)
%>
% if panelNamesByColumn[0]:
% for col in range(numberOfColumns) :
<%
if (not panelNamesByColumn[col]):
break;
cellClasses = ["layoutCell"]
if (col==0) :
cellClasses.append("firstCell")
if (col==numberOfColumns-1) :
cellClasses.append("lastCell")
%>
<%call expr="next.getDashboardPanel(modules, panelNamesByColumn[col])">%call>
% endfor
% endif
%def>
## we check that all the layoutPanels we had ended up with a home. If not we tell the user.
% for panelName in modules :
% if (panelName not in successfullyRenderedPanels) :
<%call expr="lib.add_script_block()">
this.messenger = Splunk.Messenger.System.getInstance();
this.messenger.send("error", "splunk", sprintf(_("found an invalid value for layoutPanel - '%s'."), "${panelName}"));
// a misconfigured hierarchy can often derail the module loading, so the 'Loading' string can get stuck there.
$("#loading").hide();
%call>
% endif
% endfor