Template - obsidian-nvim/obsidian.nvim GitHub Wiki
To insert a template in the current note, run the command :Obsidian template
. This will open a list of available templates in your templates folder with your preferred picker. Select a template and hit <CR>
to insert.
To create a new note from a template, run the command :Obsidian new_from_template
. This will prompt you for an optional path for the new note and will open a list of available templates in your templates folder with your preferred picker. Select a template and hit <CR>
to create the new note with the selected template.
Substitutions for {{id}}
, {{title}}
, {{path}}
, {{date}}
, and {{time}}
are supported out-of-the-box.
For example, with the following configuration
require("obsidian").setup({
-- other fields ...
templates = {
folder = "my-templates-folder",
date_format = "%Y-%m-%d-%a",
time_format = "%H:%M",
},
})
and the file ~/my-vault/my-templates-folder/note template.md
:
# {{title}}
Date created: {{date}}
Creating the note Configuring Neovim.md
and executing :Obsidian template
will insert the following above the cursor position.
# Configuring Neovim
Date created: 2023-03-01-Wed
Substitutions
You can also define custom template substitutions with the configuration field templates.substitutions
. For example, to automatically substitute the template variable {{yesterday}}
when inserting a template, you could add this to your config:
require("obsidian").setup({
-- other fields ...
templates = {
substitutions = {
yesterday = function()
return os.date("%Y-%m-%d", os.time() - 86400)
end,
},
},
})
Substitution functions are passed obsidian.TemplateContext
objects with details about which template is being used. For example, to return different values from different templates:
--- NOTE: For weekly templates this means "seven days ago", otherwise it means "one day ago".
yesterday = function(ctx)
if vim.endswith(ctx.template_name, "Weekly Note Template.md") then
return os.date("%Y-%m-%d", os.time() - 86400 * 7)
end
-- Fallback
return os.date("%Y-%m-%d", os.time() - 86400)
end
Context Types
---@alias obsidian.TemplateContext obsidian.InsertTemplateContext | obsidian.CloneTemplateContext
---The table passed to user substitution functions. Use `ctx.type` to distinguish between the different kinds.
---@class obsidian.InsertTemplateContext
---The table passed to user substitution functions when inserting templates into a buffer.
---
---@field type "insert_template"
---@field template_name string|obsidian.Path The name or path of the template being used.
---@field template_opts obsidian.config.TemplateOpts The template options being used.
---@field templates_dir obsidian.Path The folder containing the template file.
---@field location [number, number, number, number] `{ buf, win, row, col }` location from which the request was made.
---@field partial_note? obsidian.Note An optional note with fields to copy from.
---@class obsidian.CloneTemplateContext
---The table passed to user substitution functions when cloning template files to create new notes.
---
---@field type "clone_template"
---@field template_name string|obsidian.Path The name or path of the template being used.
---@field template_opts obsidian.config.TemplateOpts The template options being used.
---@field templates_dir obsidian.Path The folder containing the template file.
---@field destination_path obsidian.Path The path the cloned template will be written to.
---@field partial_note obsidian.Note The note being written.
Customizations
You can specify per-template behavior using the templates.customizations
configuration field. You may want to do this if you want to:
1. Control which directory a new note is placed in based on the template you used to create it
You might want all of your notes created using your meeting.md
template to go to {vault_root}/jobs/my-job/meetings/
require("obsidian").setup({
-- other fields ...
templates = {
customizations = {
meeting = {
notes_subdir = "jobs/my-job/meetings",
},
},
},
})
2. Control the ID generated for notes based on the template you used to create it
For example, rather than a default, Zettelkasten-style note for prominent people you want to study, you could opt for a simpler ID:
biography = {
-- This function currently only receives the note title as an input
note_id_func = function(title)
if title == nil then
return nil
end
local name = title:gsub(" ", "-"):gsub("[^A-Za-z0-9-]", ""):lower()
return name -- "Hulk Hogan" → "hulk-hogan"
end,
}
[!IMPORTANT] The name of the template file must match the name specified in your configuration
Template Customization book.md book personal-diaries.md ["personal-diaries"] big books.md ["big books"]
Full Type Annotation
---@class obsidian.config.CustomTemplateOpts
---
---@field notes_subdir? string
---@field note_id_func? (fun(title: string|?): string)