Prohlížeč zdrojového kódu
docs/specs/examples.md
Spec: Examples System
- Status: active
- Created: 2026-03-05
- Related code:
app/examples/,app/services/example_entry.rb,app/services/example_registry.rb,app/controllers/examples_controller.rb,app/views/examples/
Overview
The examples system lets visitors browse a curated set of Ruby code examples. Each example has metadata (title, description, tags) and optionally a source file displayed with syntax highlighting. Examples are grouped by tags and listed on an index page; clicking one opens a detail page. No database is involved — the filesystem is the single source of truth.
Behaviour
Storage
- Each example lives in its own subdirectory under
app/examples/<slug>/. - The subdirectory name is the example's slug (used in URLs).
- Every example directory contains an
example.yml(metadata) and anexample.mdcontent file. A.rbsource file is optional.
Metadata (example.yml)
Required fields: title.
Optional fields: source_file, description (defaults to ""), tags (defaults to []), position (defaults to 999), scenarios.
- title and description are in Czech; option values stay in English.
- position controls listing order; lower numbers appear first. Examples without a position are sorted last.
- Tags are free-form strings in Czech used for filtering.
- Each scenario must define a boilerplate_file: an explicit filename (relative to the example directory) containing the runner snippet shown in the "Vyzkoušet" section.
Index page (/examples)
- Lists all examples as cards showing title, description, and tags.
- When tags exist, a tag filter bar appears above the grid with a "Vše" (all) link and one link per tag.
- Filtering by tag shows only matching examples; the active filter is highlighted.
- If no examples match, a Czech message is shown (different wording when filtering by tag vs. no examples at all).
Detail page (/examples/:slug)
- Displays the example's title, tags, and rich content from
example.md. - If
source_fileis present, the<!-- source -->placeholder inexample.mdis replaced with the syntax-highlighted source. Using<!-- source -->in an example without asource_fileraises an error. - Examples without a
source_fileuseexample.mdas the sole content driver, with code snippets embedded directly as fenced code blocks in the Markdown. This suits complex, multi-file topics ("case studies") where there is no single file to showcase. - If the example has scenarios, each
<!-- scenario:N -->or<!-- scenarios -->placeholder is replaced with the scenario card — details covered in the scenario runner spec. Scenarios in a source-file-less example must be fully self-contained. - Unknown slugs raise a 404.
Registry
- Examples are loaded at boot into an in-memory singleton (
ExampleRegistry). ExampleRegistry.allreturns all entries sorted byposition.ExampleRegistry.find_by_slug(slug)returns an entry ornil.ExampleRegistry.filter_by_tag(tag)returns matching entries sorted byposition.ExampleRegistry.tagsreturns all unique tags, sorted alphabetically.ExampleRegistry.reload!rebuilds the singleton (used in tests and development).
Implementation Notes
app/examples/is excluded from Zeitwerk autoloading (configured inconfig/application.rb) — example.rbfiles are loaded manually byScenarioRunnerinside an anonymousModule.ExampleRegistryis a singleton class; the instance is memoized on first access viaExampleRegistry.instance.ExampleEntryis a plain Ruby object (not ActiveRecord);ScenarioandInputare inner Structs.- The registry reads all
example.ymlfiles at boot usingDir[examples_root.join("*", "example.yml")]. source_fileis optional;ExampleEntrystoresnilwhen the key is absent inexample.yml.ExampleEntry#source_codereturnsnilin that case.- Source code is read from disk on each request via
ExampleEntry#source_code. boilerplate_fileis resolved to an absolute path at parse time inbuild_scenarios;Scenario#boilerplate_codereads it on demand viaFile.read.entry_classandentry_methodare no longer part ofExampleEntryorScenario.
Tests
spec/services/example_registry_spec.rb— loading, lookup, tag filtering, sorting, reloadspec/services/example_entry_spec.rb— attribute parsing, source file path, default position
See Also
- Examples Runner — defines how scenarios within examples are executed interactively.
- Rich Example Content — Markdown-driven detail page layout replacing the fixed description/source/scenarios structure.
- Home Page — displays a preview of up to six examples from the registry on the landing page.
Change Log
- 2026-03-05: Initial retrospective spec.
- 2026-03-09: Prospective update — added boilerplate_file per scenario; removed top-level entry_class/entry_method; updated detail page source display behaviour.
- 2026-03-23: Prospective update —
source_filemade optional; examples without it useexample.mdas sole content driver (case studies);<!-- source -->silently removed when absent.