<%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 %>
${_('Loading...')}
${next.body()}
<%def name="title()"> ${VIEW['label']|h} - ${APP['label']|h} - Splunk ${cherrypy.config.get('version_label')|h} <%def name="head(enable_viewport=True)"> % if VIEW.get("refresh", -1) and int(VIEW.get('refresh')) > -1: % endif % if APP['id'] == 'search' and enable_viewport is True: % endif <%def name="body_element_open()"> <% bodyCSSClasses = [ 'splTemplate-' + os.path.split(self.filename)[-1].split('.')[0], 'splView-' + VIEW['id'] ] if VIEW['objectMode'] == 'SimpleForm': bodyCSSClasses.append('splFormSearch') if endpoint_path: bodyCSSClasses.append('splManager-' + endpoint_path.replace('/','_')) bodyCSSClasses.append('splApp-%s' % APP['id']) for release in splunkReleaseVersionParts: bodyCSSClasses.append('splVersion-%s' % release) bodyCSSClasses = ' '.join(bodyCSSClasses) %> <%def name="css()"> <%coreCSSFiles = [ "/static/css/view.css", "/static/css/skins/default/default.css", "/static/css/splunk-components.css", '/static/css/print.css', '/static/css/tipTip.css', '/static/css/jquery.iphone-style-checkboxes.css' ] %> <%lib:stylesheet_tags files="${coreCSSFiles}" /> <%lib:stylesheet_tags files="${cssFiles}" /> <%def name="custom_css()"> <%lib:stylesheet_tags files="${customCssFiles}" /> <%lib:stylesheet_tags files="${printCssFiles}" media="print"/> <%! datepicker_cache = {} %> <%def name="datepicker_js()"> ## Locate the correct i18n data for the datepicker plugin <% staticdir = cherrypy.config.get('staticdir') lang = i18n.current_lang_url_component() path = datepicker_cache.get(lang) if path is None: path = False path1 = 'js/contrib/jquery.ui.datepicker/jquery.ui.datepicker-%s.js' % lang path2 = 'js/contrib/jquery.ui.datepicker/jquery.ui.datepicker-%s.js' % lang[:2] for testpath in (path1, path2): if os.path.exists(os.path.join(staticdir, testpath)): path = '/static/' + testpath break datepicker_cache[lang] = path if path: script_tags(files=[path]) %> <%def name="js()"> <% coreJsFiles = startup.generateJSManifest() %> ## start: core js <%lib:script_tags files="${coreJsFiles}" /> ## dynamic view dependency js <%lib:script_tags files="${jsFiles}" /> ## i18n files for the jquery datepicker <% datepicker_js() %> <% params = {} paramConfig = { 'sticky': {}, 'persistable': {} } # process every module for panelName in modules: for module in modules[panelName]: # generate module configuration dict params[module.get('id')] = module.get('params', dict()) # output persistence data, if available if module['stickyParams']: paramConfig['sticky'][module['id']] = module['stickyParams'] if module['persistableParams']: paramConfig['persistable'][module['id']] = module['persistableParams'] %> ## required params js ## buffered inline js <%lib:get_script_blocks /> <%def name="js_initialization()"> <%lib:script_tags files="${['/static/js/init.js']}" /> <%lib:script_tags files="${customJsFiles}" /> <%def name="buildModule(module)"><% attributesToEmit = {"id":1,"parentmodule":1} %> ## 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])) : % endfor
<%call expr="buildModule(modules[panelName][i])">
% 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)"> % endfor ##% if countModule != False: ## <%call expr="buildModule(countModule)"> ##% endif % else : % for module in modules[panelName] : <%call expr="buildModule(module)"> % endfor % endif ## 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)">
% endif <%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. <%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])">
% endfor
% endif ## 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(); % if panelName.startswith('panel_row') : ## check dashboard.html for the rows limit. ## the limit is currently set to 50 rows this.messenger.send("error", "splunk", sprintf(_("Unable to load all the panels: a dashboard can have maximum of '50' rows."))); % else : this.messenger.send("error", "splunk", sprintf(_("found an invalid value for layoutPanel - '%s'."), "${panelName}")); % endif // a misconfigured hierarchy can often derail the module loading, so the 'Loading' string can get stuck there. $("#loading").hide(); % endif % endfor