from-markdown takes a hand-written summary such as SUMMARY.md and sets it in the full report's dress: the same cover, header, footers, table of contents, headings and grids. The shared macros move to macros.html.j2 so both templates draw from them, and layout.render_pdf takes the template and document title to use. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
101 lines
3.1 KiB
Django/Jinja
101 lines
3.1 KiB
Django/Jinja
{#
|
|
The SAST/SCA report, after the design sample in `sample_report_template/`.
|
|
|
|
This file places content and nothing else: every dimension, colour and rule lives in `report.css`.
|
|
Each section is guarded by the data it needs, so a report of a scan that ran half the pipeline is
|
|
the same document with fewer sections rather than a document full of empty tables.
|
|
|
|
The context this expects is described by `layout.CONTEXT`, and `sample.sample_context()` builds a
|
|
complete one.
|
|
#}
|
|
{% from "macros.html.j2" import value, facts, card, distribution, grid %}
|
|
|
|
{# ------------------------------------------------------------------------------------------ #}
|
|
|
|
<div class="page-header"><img src="{{ cover.logo }}" alt="CipherCell" /></div>
|
|
<span class="footer-scan">Scan: {{ cover.scan_id }}</span>
|
|
<span class="footer-date">{{ cover.footer_date }}</span>
|
|
|
|
<div class="cover-mark">
|
|
<img src="{{ cover.logo }}" alt="CipherCell" />
|
|
</div>
|
|
|
|
<div class="cover-title">{{ cover.title }}</div>
|
|
|
|
{{ facts(cover.identity) }}
|
|
|
|
{% if cover.severity_ledger %}
|
|
<h2>{{ cover.severity_ledger.title }}</h2>
|
|
<table class="ledger">
|
|
{% for row in cover.severity_ledger.rows %}
|
|
<tr{% if row.total %} class="total"{% endif %}>
|
|
<td>{{ row.label }}</td>
|
|
<td>{{ row.count }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
{% endif %}
|
|
|
|
{% if contents %}
|
|
<h1 style="break-before: page">Table of Contents</h1>
|
|
<ol class="toc">
|
|
{% for entry in contents %}
|
|
<li><a href="#{{ entry.id }}">{{ entry.title }}</a></li>
|
|
{% endfor %}
|
|
</ol>
|
|
{% endif %}
|
|
|
|
{% if project %}
|
|
<h1 id="{{ project.id }}" style="break-before: page">{{ project.title }}</h1>
|
|
{{ facts(project.overview, wide=true) }}
|
|
|
|
{% if project.languages %}
|
|
<h2>{{ project.languages.title }}</h2>
|
|
<table class="ledger">
|
|
{% for row in project.languages.rows %}
|
|
<tr{% if row.total %} class="total"{% endif %}>
|
|
<td>{{ row.label }}</td>
|
|
<td>{{ row.share }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</table>
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
{% if summary %}
|
|
<h1 id="{{ summary.id }}"{% if not project %} style="break-before: page"{% endif %}>{{ summary.title }}</h1>
|
|
{{ facts(summary.overview, wide=true) }}
|
|
|
|
{% for block in summary.distributions %}
|
|
<h2>{{ block.title }}</h2>
|
|
{{ distribution(block.rows, block.legend) }}
|
|
{% endfor %}
|
|
|
|
{% for metric in summary.metrics or [] %}
|
|
{{ card(metric.title, metric.rows, metric.note) }}
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
{% if critical %}
|
|
<h2 id="{{ critical.id }}" style="break-before: page">{{ critical.title }}</h2>
|
|
{{ grid(critical.table) }}
|
|
{% endif %}
|
|
|
|
{% for section in sections %}
|
|
<h1{% if section.id %} id="{{ section.id }}"{% endif %}{% if section.new_page %} style="break-before: page"{% endif %}>{{ section.title }}</h1>
|
|
|
|
{% for group in section.groups %}
|
|
<h2>{{ group.title }}</h2>
|
|
{% if group.note %}<p class="note">{{ group.note }}</p>{% endif %}
|
|
|
|
{% for entry in group.cards %}
|
|
{{ card(entry.title, entry.rows) }}
|
|
{% endfor %}
|
|
|
|
{% if group.table %}
|
|
{% if group.table.title %}<h2>{{ group.table.title }}</h2>{% endif %}
|
|
{{ grid(group.table) }}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endfor %}
|