Skip to content
Xi Software Request an evaluation

Page scan

Scan a directory and return page metadata as a TT array variable.

Page scan

The scan: prefix in tt_page_var scans a directory for .md files and returns an array of page objects. Use it to build indexes, listings, and navigation from page metadata.

Syntax

---
tt_page_var:
  pages: scan:/blog/*.md sort=date desc
---

Pattern rules

  • Must start with / (docroot-relative)
  • Must end with .md
  • Standard shell glob patterns work (*.md, post-*.md)
  • Use ** for recursive scanning across all subdirectories: scan:/**/*.md scans the entire docroot
  • At most 200 files are read per scan, the first 200 in file-name order (then sorted), so the same pages are listed on every render. Set scan_limit: in lazysite.conf to change it. A capped scan logs a warning.
  • NAME_total beside the list counts the pages the pattern matched that the reader may see, before filter= and before the cap, so a page can say showing [% posts.size %] of [% posts_total %]
  • limit=N and offset=N page the list after filter= and sort=: scan:/blog/*.md sort=date desc offset=10 limit=10 is the second ten. limit= is capped by scan_limit, and offset= reaches no further than the pages the scan read, so raise scan_limit to page a longer list. NAME_total is not changed by them. A value that is not a whole number is ignored and logged.
  • Files outside the docroot are excluded (realpath check)

Page object fields

Each scanned page returns these fields:

  • url - docroot-relative URL (.md stripped, /index normalised to /)
  • title - from front matter title: or empty string
  • subtitle - from front matter subtitle: or empty string
  • date - from front matter date: or file mtime (YYYY-MM-DD format)
  • tags - array of tags from front matter (YAML list, comma-separated, or single value)
  • excerpt - first 500 characters of the raw page body (after front matter), used for search snippets
  • searchable - 1 or 0, from front matter search: or the site-wide search_default setting
  • path - full filesystem path to the .md file

Sort modifier

Append sort=FIELD DIRECTION to the pattern:

scan:/blog/*.md sort=date desc
scan:/docs/*.md sort=title asc
scan:/pages/*.md sort=filename asc

Supported fields: date, title, filename. Default: filename asc. Direction is optional and defaults to asc.

Paging modifiers

Append limit=N and offset=N to list part of the sorted result:

scan:/blog/*.md sort=date desc limit=10
scan:/blog/*.md sort=date desc offset=10 limit=10

They apply after filter= and sort=. limit= is capped by the site's scan_limit; offset= counts into the pages the scan read.

Example

---
title: Blog
tt_page_var:
  posts: scan:/blog/*.md sort=date desc
---
[% FOREACH post IN posts %]
### [% post.title %]

*[% post.date %]* - [% post.subtitle %]

[Read more]([% post.url %])
[% END %]

Notes

  • Scans can also be defined in lazysite.conf for site-wide variables
  • Tags are parsed from YAML list format, comma-separated strings, or single values into an array: [% page.tags.join(', ') %]
  • The scan is performed at render time - results reflect the current state of the filesystem
  • Filtered scan - filter results by field value
  • Search - build a search index from scan results
  • TT variables - all variable sources and types