01 — Lesson Anatomy#
Every lesson is a markdown file in docs/. This page explains the structure of a lesson file, the block types available, and how the Dynatrace app processes each section.
Lesson file structure#
docs/
index.md ← Welcome page (nav entry 1)
00-getting-started.md ← Lesson 0 (this template's orientation)
01-lesson-anatomy.md ← Lesson 1 (this file)
02-interactive-blocks.md ← Lesson 2
03-example-lesson.md ← Lesson 3
04-publishing-validation.md ← Lesson 4
cleanup.md ← Cleanup page
resources.md ← Resources page
snippets/ ← Reusable content includes
img/ ← Images
Anatomy of a lesson page#
# Section N — Title
Optional intro paragraph. Describe what the learner will do and why.
<!-- STEP_SETUP (optional — runs framework functions before page renders)
commands:
- mySetupFunction
-->
## Concept or context heading
Explanation text. Use code blocks, diagrams, admonitions freely.
```bash
# Copy-paste-ready command the learner runs in the Terminal tab
kubectl get pods -n my-namespace
Validation#
The check below runs <command> and verifies <condition>.
---
## Block types (quick reference)
### `shell-verification` — runs a shell command in the Orbital container
```markdown
<!-- LAB_QUESTION
type: shell-verification
question: "Verify the cluster node is Ready"
buttonText: "Check Cluster"
command: "kubectl get nodes --no-headers 2>/dev/null | grep -c ' Ready'"
expect:
operator: gt
value: 0
hint: "Wait 30 seconds after the environment starts and try again."
explanation: "Cluster node is Ready — you are good to proceed."
-->
multiple-choice — inline knowledge check#
<!-- LAB_QUESTION
type: multiple-choice
question: "What does `kubectl rollout restart` do?"
options:
- "Triggers a rolling restart of all pods in a deployment — new pods start before old ones terminate"
- "Deletes all pods in the namespace immediately"
- "Reloads the Kubernetes API server configuration"
- "Restarts the k3d cluster host process"
correct: 0
explanation: "A rolling restart replaces pods gradually, keeping the application available throughout."
-->
dql-verification — runs a DQL query against the learner's Dynatrace tenant#
<!-- LAB_QUESTION
type: dql-verification
question: "Verify Dynatrace is collecting logs from your namespace"
buttonText: "Check DT Logs"
dql: |
fetch logs
| filter k8s.namespace.name == "my-namespace"
| filter timestamp > now() - 10m
| limit 1
expect:
operator: not-empty
hint: "Generate some logs first by interacting with the app, then wait 2 minutes."
explanation: "Dynatrace is collecting logs from your namespace."
-->
STEP_SETUP — runs functions before the page renders (no button shown)#
boundScenarioId — attaches a scored assessment from .assessment/*.json#
The expect field#
operator |
When to use | Example |
|---|---|---|
gt |
Command prints a count; must be > N | grep -c returns at least 1 match |
gte |
Count must be ≥ N | At least 2 pods running |
eq |
Count must be exactly N | Exactly one ActiveGate |
not-empty |
Any non-empty output counts | DQL returns at least one row |
MkDocs nav registration#
Every lesson file must be listed in mkdocs.yaml nav or it will not appear in the lesson menu:
# mkdocs.yaml
INHERIT: mkdocs-base.yaml
site_name: "Dynatrace Enablement Lab: My Training"
repo_name: "View Code on GitHub"
repo_url: "https://github.com/dynatrace-wwse/my-training-repo"
nav:
- "Welcome": index.md
- "00. Getting Started": 00-getting-started.md
- "01. Lesson Anatomy": 01-lesson-anatomy.md
- "02. Interactive Blocks": 02-interactive-blocks.md
- "03. Example Lesson": 03-example-lesson.md
- "04. Publishing": 04-publishing-validation.md
- "Resources": resources.md
extra:
rum_snippet: "https://js-cdn.dynatrace.com/jstag/1612cf70810/<tenant-id>/<app-id>_complete.js"
Nav order = lesson order
The Dynatrace app builds the lesson menu from nav in order. Always list pages in the order you want learners to follow them.
Page lifecycle (what happens when a learner opens a lesson)#
- Dynatrace app fetches the rendered HTML from GitHub Pages
- App parses all
<!-- LAB_QUESTION -->and<!-- STEP_SETUP -->comments - If
STEP_SETUPexists, app calls Orbital to run the commands in the container - Page renders with all interactive blocks active
- Learner reads content, runs Terminal commands, clicks check buttons
- Each
shell-verificationbutton → Orbital executes command → result compared toexpect→ hint or explanation shown - Each
dql-verificationbutton → DQL runs in tenant → result compared toexpect - If
boundScenarioIdis present → assessment renders after all checks complete
Admonition quick reference#
!!! tip "Tip heading"
Content here.
!!! note "Note heading"
Content here.
!!! warning "Warning heading"
Content here.
!!! success "Success heading"
Content here.
Grid card navigation#
Use at the bottom of each page to guide the learner to the next step: