This template is a living reference for how to build rich PLEX posts. It shows every major element the system supports: metadata, typography, lists, code blocks with copy buttons, tables, charts, images, callouts, and data or code downloads.
Duplicate blog0.html, rename it (for example,
post42.html), then update the metadata comments at the top plus the content blocks below.
The layout system will auto-discover the file, parse the published date and other fields,
and place it correctly on the index page.
1. Metadata section (top of file)
At the very top of each blog file, add a compact HTML comment block that describes the post:
published— ISO date,YYYY-MM-DDtitle— title that shows on the hero and cardsfields— comma-separated topicsauthor— who wrote the postimage— static image path understatic/images/excerpt— 1–3 sentence summary shown on cards
The loader reads these comments via parse_meta_from_file() and uses them to render hero cards,
list cards, and routing.
2. Basic structure of a PLEX article
All content should live inside a single container:
<div class="post-body-block"> ... </div>
Inside that, use normal HTML headings <h2>, <h3>, paragraphs
<p>, lists, tables, and so on. The CSS handles the typography and spacing.
Example subheadings and lists
A common flow for a technical or analytical post:
- Set the context and problem.
- Describe the method, constraints and trade-offs.
- Show the code, configuration, or data.
- Summarise conclusions and next steps.
For short points, use an unordered list:
- One concept per bullet.
- Keep phrasing simple and direct.
- Use nested bullets only when genuinely needed.
3. Code blocks with copy button
To present code, wrap it in a .code-block container. The header region shows the language
badge and a Copy button; you can change the badge text to match the language.
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
posts = load_posts()
return render_template("index.html", posts=posts)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
Inline code like load_dataset("my_table"),
request.args.get("page") or
url_for("post_detail", slug=...) is wrapped in
<code>...</code> and is styled as a small dark capsule.
Code download links
If you want to provide a downloadable script, use a normal anchor to a static file. For example:
(Create the file at static/downloads/example_script.py so this link resolves.)
4. Tables: static and data-driven
Use the .post-table-wrapper and .post-table classes to render compact numeric
views. The wrapper handles shadows, borders and responsive scrolling.
| Date | Requests | Avg Latency (ms) | Error Rate (%) |
|---|---|---|---|
| 2025-01-01 | 10,240 | 135 | 0.18 |
| 2025-01-02 | 11,380 | 141 | 0.22 |
| 2025-01-03 | 12,015 | 139 | 0.19 |
Data-driven table from CSV
You can also load rows directly from a CSV file in the data/ folder using
load_dataset(), which is injected into the template context:
To demonstrate data-driven tables here, create
data/template_demo_summary.csv with columns
category,value,notes. Once present, this block will render a live table.
5. Charts and timeseries sections
Charts live inside a .chart-frame container with a header, legend, and a body area that
holds an SVG or image. Use .chart-download-link for a CSV download button in the header.
For a live chart, generate data/template_demo_series.csv with your time series and wire it
into your preferred charting tool. The download link above already points at that filename via
download_data().
6. Images and diagrams
Use a <figure> with .post-image-frame to show diagrams, reference images
or concept art. The frame keeps the card-like styling aligned with charts and tables.
7. Data downloads and methodology section
Many posts will include a compact “data methodology” segment at the end, along with links to download the final datasets used in charts and tables.
If present, the following datasets can be downloaded directly:
- template_demo_series.csv — example chart timeseries
- template_demo_summary.csv — example summary table
Data methodology (example)
The following is an example methodology block you can adapt per article:
- Source: Internal PLEX Lab synthetic dataset generator.
- Sampling: Daily aggregates for requests, latency and error rate over a 30-day window.
- Processing: Raw logs aggregated into daily metrics, then exported as CSV.
- Visualisation: Static SVG placeholders in the article; real posts can use charting libraries.
- Integrity: No manual editing of values; all figures computed from source logs or scripts.
You can replace each bullet with your real data sources, filters, and transformation steps. The goal is to give readers enough information to reproduce or verify your findings, using the same CSVs you expose via download links.
8. Final checklist for new posts
- Update the metadata comment block (date, title, fields, author, image, excerpt).
- Keep all content inside a single
.post-body-blockcontainer. - Use headings and lists to break up long sections.
- Wrap code in
.code-blockand use inline<code>sparingly. - Use
.post-table-wrapperand.post-tablefor numeric views. - Use
.chart-framefor charts and time series. - Wrap images in
.post-image-frameand.post-image-caption. - Expose CSV datasets via
download_data()and link with.inline-download-link.
Once your new file is saved under templates/blogs/, the index page will pick it up
automatically on the next reload, ordered by its published date.