Folder Pages (Grav-Style)
In the folder model, the directory is the page. The folder name becomes
the URL, and an index file inside it carries the content. Anything else in the
folder – images, PDFs, _-prefixed modules, nested child directories – is
scoped to that page. This is the Grav CMS convention, and it is the natural
choice when content and its assets travel together.
Layout
content/
01.home/
default.md # page at /home
hero.jpg # page-local media for /home
_hero/
default.md # page module
02.blog/
default.md # /blog listing
01.hello-world/
default.md # /blog/hello-world
cover.jpg # page-local media
03.docs/
default.md # /docs
01.getting-started/
default.md # /docs/getting-started
Every page is a folder; every folder is reachable at the URL formed from its name. Nesting folders nests URLs, so the filesystem tree and the navigation tree are the same shape.
URLs from folder names
The folder name becomes the last URL segment, with any numeric ordering prefix
stripped: 02.blog/ serves /blog, and 02.blog/01.hello-world/ serves
/blog/hello-world. The index file’s own name (default.md) never appears in
the URL – it only marks which file holds the folder’s content.
Numeric prefixes control order
A leading NN. on a directory name (01., 02., 123.) sets its position in
navigation. The prefix is stripped from the URL but recorded as the page’s
menu.order, so you get filesystem-driven ordering without writing any
frontmatter. Rename 05.guides/ to 02.guides/ and it moves up the menu –
no edits to the content itself.
Folders without a prefix sort after prefixed ones, alphabetically by URL.
Index files
The content lives in one of three recognized filenames inside the folder:
| Filename | Convention |
|---|---|
default.md | Accent CMS / Grav convention |
README.md | Repository / documentation convention |
index.md | Web / static-site convention |
Filename matching is case-insensitive. If more than one index file is present
in the same folder, priority is default.md, then README.md, then
index.md – the others are ignored. Most sites pick one convention and use
it everywhere; mixing is supported but rarely worth the ambiguity.
Page-local media
Any non-markdown file beside the index is automatically registered as a
MediaAsset attached to that page. Drop hero.jpg next to 01.home/default.md
and it belongs to /home. In templates, resolve its URL with the media()
function, passing the owning page’s URL:
<img src="{{ media('hero.jpg', page.url) }}" alt="Hero">
Because media is scoped to the folder, two different pages can each have their
own cover.jpg with no collision – the asset is namespaced by the page it
lives beside. See the Media in Templates
guide for processing options
(resize, crop, format conversion).
Page modules
Subdirectories prefixed with an underscore (_hero/, _features/, _cta/)
are composable content blocks, not standalone pages. They never get their
own URL; instead they render independently and are exposed to the parent page’s
template as page.modules. This is how you assemble a landing page from
reusable, separately edited sections:
content/01.home/
default.md
_hero/default.md
_features/default.md
_cta/default.md
See the Modular Pages guide for how to loop over and render modules in a template.
Template selection
A folder page’s template name is the index filename stem. Since nearly
every folder uses default.md, a single default.html.jinja template renders
the whole site. Override per page with a template: field in the index
frontmatter:
--- title: Home template: landing ---
Creating a folder page
mkdir -p content/01.about cat > content/01.about/default.md << 'EOF' --- title: About Us menu: visible: true order: 1 --- Welcome to our about page. EOF
This produces a page at /about with an explicit title and sort position.
Add media to it
Drop the file in beside the index – nothing else required:
content/01.about/
default.md # the page
team-photo.jpg # page-local media, accessible via media('team-photo.jpg', page.url)
Add modules to it
Add _-prefixed subdirectories:
content/01.about/
default.md
_team/default.md # rendered into the page as a module
_values/default.md
When to choose folder pages
- Your pages carry images, PDFs, or other assets that should stay beside the content and move with it.
- You want to build landing pages from composable modules (
_hero/,_features/,_cta/). - You are migrating from Grav CMS.
- You want filesystem-driven sort ordering with no frontmatter.
When your content is mostly text with few assets, the File Pages model is lighter. The two can also be mixed freely in one site.