Inline-Note-Creation
Inline Note Creation
When a dynamic_select field has allow_create = true, Pour extends the capture flow to include vault-side note creation. This closes the loop between data entry and data management — the user never leaves the TUI to scaffold a new option.
How It Works
- The user types a value that doesn't match any existing option in the dropdown.
- The dropdown shows
+ Create "{value}"as a visual affordance. - On form submit, Pour detects the novel value and auto-creates a bare note at
{source}/{value}.mdwith minimal frontmatter (dateonly). - The note is created before the main module output is written, so any
wikilink = truereferences resolve immediately in Obsidian. - The local cache is updated so subsequent form loads include the new option without a transport round-trip.
Relationship to the 3-Tier Fallback
This feature extends The-3-Tier-Data-Fallback with an output side. The fallback pipeline handles reading options into the TUI; inline creation handles writing new options back to the vault. Together they form a closed loop:
Vault ──[fetch]──> Cache ──> Dropdown ──[novel value]──> Auto-create ──> Vault
When all three tiers fail and the dropdown is empty, allow_create fields accept freetext input (Tier 3 behavior). The submitted value triggers note creation, seeding the cache for future sessions.
Filename Sanitization
User-typed values are sanitized before becoming filenames:
- Characters invalid in cross-platform filenames (
: ? * < > | " \ /) are replaced with- - Consecutive dashes are collapsed
- Leading/trailing dashes and whitespace are trimmed
- Windows reserved device names (
CON,NUL,COM1-COM9,LPT1-LPT9) are rejected - Empty results after sanitization are skipped
Duplicate detection is case-insensitive and checks both the raw typed value and its sanitized form against existing options.
Best-Effort Semantics
Note creation is best-effort. If the transport layer fails (network error, permission issue), the main form write still proceeds. The failure is logged to stderr but does not block the user's capture flow.
Template-Driven Creation
By default, inline creation produces a bare stub — a note with only a date field. For richer notes, add a create_template reference to the field:
[[modules.coffee.fields]]
name = "bean"
field_type = "dynamic_select"
prompt = "Bean"
source = "Coffee/Beans"
allow_create = true
wikilink = true
create_template = "bean"
post_create_command = "templater:run" # optional — fires an Obsidian command after creation
When the user types a novel value, a sub-form overlay appears with the template's fields. The user fills them in without leaving Pour, and the created note gets full structured frontmatter.
Sub-Form Overlay
The overlay is a centered modal that appears over the main form:
- Shows the template's fields (text, number, static_select)
Tab/Shift+Tabnavigates fieldsEnteron the submit button creates the noteEsccancels without creating anything- Falls back to bare stub creation if the terminal is too small
Post-Creation Command Hook
post_create_command fires an Obsidian command via the REST API after note creation. This bridges Pour's data capture with Obsidian plugins:
- Pour writes frontmatter (structured data it collected)
- Templater (or any plugin) adds body content, formatting, and dynamic expressions
- Only fires when connected via API; silently skipped on filesystem transport
Template Definition
Templates are defined at the top level of config.toml:
[templates.bean]
path = "Coffee/Beans/{{name}}.md"
[[templates.bean.fields]]
name = "roaster"
field_type = "text"
prompt = "Roaster"
[[templates.bean.fields]]
name = "origin"
field_type = "static_select"
prompt = "Origin"
options = ["Ethiopia", "Colombia", "Kenya"]
{{name}} is replaced with the user's typed value. The path also supports strftime tokens (%Y, %m, %d). See field-types > Templates for the full schema reference.
Config
# Basic — bare stub creation
[[modules.coffee.fields]]
name = "bean"
field_type = "dynamic_select"
prompt = "Bean"
source = "Coffee/Beans"
allow_create = true
wikilink = true
# Advanced — template-driven creation with Templater hook
[[modules.coffee.fields]]
name = "bean"
field_type = "dynamic_select"
prompt = "Bean"
source = "Coffee/Beans"
allow_create = true
wikilink = true
create_template = "bean"
post_create_command = "templater:run"
See field-types for the full allow_create, wikilink, create_template, and post_create_command reference.