{files}
Scans a directory and iterates its entries, with path, file, ext, item and dir for each.
Syntax
{files 'dir', base='app'} {$item} {$file} {$ext} {/files}
{files dir='dir', base='data', mask='*.txt', exclude='old*', recursive, onlyFiles, includeHidden} ... {/files}
{files 'dir', base='app', onlyDirs} ... {/files}
Parameters
-
dir -
The directory, relative to what
base=names. Also writtendir=.
Options
-
base -
What the directory is relative to:
app(the application),data(DATA/) orpad(the path as given); otherwise the file system root. It must lie inside the applications, the engine or DATA. -
mask -
Only the names that match this shell pattern -
*.pad. -
exclude - Leave out the names that match this shell pattern.
-
recursive -
Bare option: the subdirectories too - every file below,
itemholding the path. -
onlyFiles - Bare option: files only.
-
onlyDirs - Bare option: directories only.
-
includeHidden - Bare option: names starting with a dot too.
Description
{files 'dir', base='app'} scans a directory and iterates its entries, one occurrence each, with five fields: path (the full path), file (the name), ext (the extension, empty for a directory), item (the entry relative to the scanned directory, the extension taken off a file - the name a page is addressed by) and dir (the part of item before its last slash).
base= says what the directory is relative to: app the application, data DATA/, pad the path as given; otherwise it is read from the file system root. Whatever the base, the directory must lie inside the applications, the engine or DATA - anything else is an error. A directory that is not there is an error under the strict check, an empty list without it.
recursive walks every subdirectory and lists the files below; mask and exclude keep or drop names by a shell pattern, onlyFiles and onlyDirs keep one kind, and names starting with a dot are left out unless includeHidden is given. . and .. never come along.
The entries come in the order the file system keeps them, which differs between machines: add sort='item' (any handling option works) when the order matters. The tag reads a group parameter of its own as well, but the handling option of that name takes it first, so it cannot be used. {dir} is the plain version - the names only.
Examples
A folder of the application
base='app' reads the directory from the application's root; sort makes the order the file system keeps irrelevant.
<ul>
{files '_data/filesDemo', base='app', sort='item'}
<li>{$item} {if $ext}<small>({$ext})</small>{else}<small>(directory)</small>{/if}</li>
{/files}
</ul>
- archive (directory)
- notes (txt)
- prices (csv)
- readme (md)
Recursive, files only, by mask
recursive walks the subdirectories too; item keeps the path below the scanned directory, dir the part before its last slash.
<table>
<tr><th>item</th><th>file</th><th>dir</th></tr>
{files '_data/filesDemo', base='app', recursive, onlyFiles, mask='*.txt', sort='item'}
<tr><td>{$item}</td><td>{$file}</td><td>{$dir}</td></tr>
{/files}
</table>
| item | file | dir |
|---|---|---|
| archive/2025 | 2025.txt | archive |
| archive/2026 | 2026.txt | archive |
| notes | notes.txt |
Directories only, or all but some
onlyDirs keeps the directories; exclude drops the names that match its pattern.
<p>Directories: {files '_data/filesDemo', base='app', onlyDirs}{$item}{/files}</p>
<p>Not text: {files '_data/filesDemo', base='app', onlyFiles, exclude='*.txt', sort='item'}{notFirst@files}, {/notFirst@files}{$file}{/files}</p>
Directories: archive
Not text: prices.csv, readme.md
See also
- {dir} Lists the names in a directory, one occurrence each - the plain version of files.
- {exists} Renders its content when a file or directory is there, its else half when not.
- {file} Writes its rendered content to a file under DATA/ instead of to the page.
- {sitemap} Lists the pages of the application, read from the file tree, as rows with page, url and lastmod.