mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
136 lines
5.9 KiB
Twig
136 lines
5.9 KiB
Twig
{# @copyright Copyright (C) 2010-2023 Combodo SARL #}
|
|
{# @license http://opensource.org/licenses/AGPL-3.0 #}
|
|
<!DOCTYPE html>
|
|
<html lang="{{ aPage.aMetadata.sLang }}">
|
|
<head>
|
|
<meta charset="{{ aPage.aMetadata.sCharset }}">
|
|
{# This block can be used to add your own meta tags by extending the default template #}
|
|
{% block iboPageExtraMetas %}
|
|
{% endblock %}
|
|
{% if aPage.aMetadata.sBaseUrl is defined or aPage.aMetadata.sBaseTarget is defined %}
|
|
<base {% if aPage.aMetadata.sBaseUrl is defined %}href="{{ aPage.aMetadata.sBaseUrl }}"{% endif %} {% if aPage.aMetadata.sBaseTarget is defined %}target="{{ aPage.aMetadata.sBaseTarget }}"{% endif %}>
|
|
{% endif %}
|
|
<title>{{ aPage.sTitle }}</title>
|
|
{% if aPage.sFaviconUrl is defined %}
|
|
<link rel="shortcut icon" href="{{ aPage.sFaviconUrl|add_itop_version|raw }}">
|
|
{% endif %}
|
|
<link rel="search" type="application/opensearchdescription+xml" title="iTop" href="{{ aPage.sAbsoluteUrlAppRoot }}pages/opensearch.xml.php">
|
|
{# Main fonts have to be preloaded to avoid blocking content rendering #}
|
|
{% for aPreloadedFont in aPage.aPreloadedFonts %}
|
|
<link rel="preload" href="{{ aPreloadedFont['font'] }}" as="font" type="font/{{ aPreloadedFont['type'] }}" crossorigin>
|
|
{% endfor %}
|
|
{# Stylesheets MUST be loaded before any scripts otherwise we may face problems such as
|
|
- Visual glitches
|
|
- jQuery scripts spurious problems (like failing on a 'reload') #}
|
|
{% block iboPageCssFiles %}
|
|
{% for aCssFileData in aPage.aCssFiles %}
|
|
{% if aCssFileData['condition'] != '' %}<!--[if {{ aCssFileData['condition'] }}]>{% endif %}
|
|
<link type="text/css" href="{{ aCssFileData['link']|add_itop_version|raw }}" rel="stylesheet">
|
|
{% if aCssFileData['condition'] != '' %}<![endif]-->{% endif %}
|
|
{% endfor %}
|
|
{% endblock %}
|
|
|
|
{% block iboPageCssInline %}
|
|
{# We put each styles in a dedicated style tag to prevent massive failure if 1 style is broken (eg. missing semi-colon, bracket, ...) #}
|
|
{% for sCssInline in aPage.aCssInline %}
|
|
<style>
|
|
{{ sCssInline|raw }}
|
|
</style>
|
|
{% endfor %}
|
|
{% endblock %}
|
|
|
|
{% block iboPageJsInlineEarly %}
|
|
{% for sJsInline in aPage.aJsInlineEarly %}
|
|
{# We put each scripts in a dedicated script tag to prevent massive failure if 1 script is broken (eg. missing semi-colon or non closed multi-line comment) #}
|
|
<script type="text/javascript">
|
|
{{ sJsInline|raw }}
|
|
</script>
|
|
{% endfor %}
|
|
{% endblock %}
|
|
</head>
|
|
<body data-gui-type="backoffice">
|
|
{% if aPage.isPrintable %}<div class="printable-content" style="width: 27.7cm;">{% endif %}
|
|
{% block iboPageBodyHtml %}
|
|
<div id="ibo-page-container">
|
|
{{ render_block(oLayout, {aPage: aPage}) }}
|
|
</div>
|
|
{% endblock %}
|
|
{% if aPage.isPrintable %}</div>{% endif %}
|
|
|
|
{% block iboDeferredBlocks %}
|
|
{% for oBlock in aDeferredBlocks %}
|
|
{{ render_block(oBlock, {aPage: aPage}) }}
|
|
{% endfor %}
|
|
{% endblock %}
|
|
|
|
{% block iboPageTemplates %}
|
|
{% endblock %}
|
|
|
|
<script type="text/javascript">
|
|
{# JS files can either be loaded initially or requested by an XHR response #}
|
|
{# - For the initial page, all files are loaded before running inline snippets #}
|
|
{# - For XHR responses, we need to ensure that all required files are fully loaded before running inline snippets #}
|
|
|
|
/**
|
|
* @var {Map} aLoadedJsFilesRegister
|
|
* Register of all JS files loaded in this page, including the Promise corresponding to the loading state of each file.
|
|
* A JS file MUST NOT be loaded more than once as it could compromise settings / plugins loaded after the first time.
|
|
*/
|
|
const aLoadedJsFilesRegister = new Map();
|
|
/**
|
|
* @var {Map} aLoadedJsFilesResolveCallbacks
|
|
* Resolve callbacks of JS files registered in aLoadedJsFilesRegister. Used -mostly in AjaxPage- to know when a file is done loading so the depending snippets can run
|
|
*/
|
|
const aLoadedJsFilesResolveCallbacks = new Map();
|
|
{% for sJsFile in aPage.aJsFiles %}
|
|
aLoadedJsFilesRegister.set("{{ sJsFile|raw }}", new Promise(function(resolve) {
|
|
aLoadedJsFilesResolveCallbacks.set("{{ sJsFile|raw }}", resolve);
|
|
// Resolve promise right away as these files are loaded immediately before any inline JS is executed
|
|
aLoadedJsFilesResolveCallbacks.get("{{ sJsFile|raw }}")();
|
|
}));
|
|
{% endfor %}
|
|
</script>
|
|
|
|
{% block iboPageJsFiles %}
|
|
{% for sJsFile in aPage.aJsFiles %}
|
|
<script type="text/javascript" src="{{ sJsFile|add_itop_version|raw }}"></script>
|
|
{% endfor %}
|
|
{% endblock %}
|
|
|
|
{% block iboPageJsInlineScripts %}
|
|
{% if aPage.aJsInlineOnInit is not empty or aPage.aJsInlineOnDomReady is not empty %}
|
|
<script type="text/javascript">
|
|
{# TODO 3.0.0: How to do this in native JS? #}
|
|
$(document).ready(function () {
|
|
{% block iboPageJsInlineOnInit %}
|
|
{% for sJsInline in aPage.aJsInlineOnInit %}
|
|
{{ sJsInline|raw }}
|
|
{% endfor %}
|
|
{% endblock %}
|
|
|
|
{% block iboPageJsInlineOnDomReady %}
|
|
setTimeout(function () {
|
|
{% for sJsInline in aPage.aJsInlineOnDomReady %}
|
|
{{ sJsInline|raw }}
|
|
{% endfor %}
|
|
}, 50);
|
|
{% endblock %}
|
|
});
|
|
</script>
|
|
{% endif %}
|
|
{% block iboPageJsInlineLive %}
|
|
{% for sJsInline in aPage.aJsInlineLive %}
|
|
{# We put each scripts in a dedicated script tag to prevent massive failure if 1 script is broken (eg. missing semi-colon or non closed multi-line comment) #}
|
|
<script type="text/javascript">
|
|
{{ sJsInline|raw }}
|
|
</script>
|
|
{% endfor %}
|
|
{% endblock %}
|
|
{% endblock %}
|
|
|
|
{% block iboCapturedOutput %}
|
|
{{ aPage.sCapturedOutput|raw }}
|
|
{% endblock %}
|
|
|
|
</body>
|
|
</html> |