Metadata
Metadata providers extract structured fields from files and optionally declare a schema so Phials can show Details columns and property UI. Multiple providers can match one file; the host merges keyed values into ExtractedMetadata (later providers overwrite duplicate keys).
Types: MetadataProvider, MetadataAPI, MetadataColumnPolicy, DirectoryMetadataProfile.
Related: Plugin overview · Plugin API · Preview
Mental model
- Raw metadata — string map from the host file-metadata pipeline plus timestamps from
FileEntry. extract(file, rawMeta, api)— returnsExtractedMetadata(JSON-serializable values).- Merge — order follows matched providers sorted by
priority(higher first); collisions favor later providers in that list. schema— optionalMetadataSchemaFieldlist (key,label,type, …) for columns and formatting.columnPolicy— controls column picker and auto-visible behavior (dominance sampling, caps, exclusions).
Matching providers
Same style of extension / MIME / category index as previews, plus global providers:
- A provider with empty
extensions,mimeTypes, andcategories, and nocanHandle, is treated as global and considered for every file.
Per candidate:
- If
canHandleexists, it must return true (signature(file: FileEntry) => booleanonly — unlike previewcanHandle). - Otherwise match on extension, MIME, category, or global.
Sort by priority (higher first) before running extract.
MetadataAPI
Extends the plugin API with read helpers for file content used in extraction. Declare filesystem.read (and the Phials version you need) so readFile / readTextFile are allowed for your plugin.
Column policy (summary)
| Field | Meaning |
|---|---|
showInColumnMenu | Omit from column picker when false (entire provider); takes precedence over columnWhitelist. |
columnWhitelist | If set, only these schema keys appear in the column picker and in auto-visible picks. Omit for all schema fields. An empty array excludes the provider from column contributions. |
autoVisible | Controls automatic column insertion (never, dominance-based, …). |
defaultVisibleFields | Subset of schema keys when auto-visible runs (subject to caps). |
excludeFromDominance | Skip when computing dominant provider stats for a directory. |
requiresValueSampling | Exclude from naive auto-visible heuristics. |
Directory dominance profiles sample files in a folder to decide which metadata columns should appear by default; exact thresholds ship with the app version you target — test against real directories.
Minimal example
const myMetadata: MetadataProvider = {
type: "metadata",
id: "my.vendor.metadata",
name: "My Metadata",
priority: 20,
extensions: ["log"],
extract: async (file, rawMeta, api) => {
const text = await api.readTextFile(file.path);
const lines = text.split("\n").length;
return { logLines: lines };
},
schema: {
fields: [{ key: "logLines", label: "Lines", type: "number" }],
},
columnPolicy: {
autoVisible: "when-dominant",
defaultVisibleFields: ["logLines"],
},
};Pitfalls
canHandlevs global — Empty filters pluscanHandledoes not make a provider global.- Merged keys — use prefixed keys (
myPlugin.foo) to avoid collisions with other providers. - Raw vs extracted — guard missing
rawMetakeys; coerce types defensively. readTextFile/readFilerequirefilesystem.readin your manifest (and aminAppVersionthat supports the behavior you rely on).