Templater - template for creating subtopics

I found myself repeating these steps a lot:

  1. Naming my note as “Title (Domain)”
  2. Add “Title” as alias
  3. Add link to domain note, e.g. *This is a note about [[Domain]].*

So, I automated the process.

How to use this template:

  1. Name your note as “Title (Domain)”
  2. Insert this template with templater

Feel free to give suggestions.

<%*
/**
 * This template creates a subtopic note
 * When a note has format:
 *     title (domain)
 * 
 * Inserting this template, will perform the following actions:
 *     1. Creates ${title} alias (inserts into frontmatter if present)
 *     2. Inserts *This is a note about [\[${domain}]].* at top of note
 */

let match = tp.file.title.match(/^\b([\S\s]+)\b \(\b([\S\s]+)\b\)$/);

if (match === null) {
	// Invalid title format
	new tp.obsidian.Notice(
`*Template Error:*
Note title should have format:
[title] ([domain])`);

	return;
}

// Valid title, insert template

const alias = match[1];
const domain = match[2];

var frontmatter = tp.file.content.match(/^---\n[\s\S]*?---(\n|$)/);
const content = tp.file.content.replace(/^---\n[\s\S]*?---(\n|$)/, "");

if (frontmatter !== null) {
	// Insert alias within existing frontmatter

	frontmatter = frontmatter[0];

	if (frontmatter.match(/aliases *:\n( *- *[\S ]+\n)+/) !== null) {
		// Multi-line array
		const aliasFormat = frontmatter.match(/aliases *:\n( *- *[\S ]+\n)+/)[1];
		const aliasInsert = aliasFormat.replace(/^( *- *)([\s\S]+?)$/, "$1" + alias);
		frontmatter = frontmatter.replace(/(aliases *:\n)( *- *[\S ]+\n)+/, `$&${aliasInsert}\n`);
	} else if (frontmatter.match(/aliases *: +\[[\w "]+(,[\w "]+)+\]/) !== null) {
		// Single-line array
		frontmatter = frontmatter.replace(/(aliases *: +\[([\w "]+,)+)([\w "]+)\]/, `$1$3, ${alias}]`);
	} else {
		// Create alias in frontmatter
		const aliasInsert = "$&aliases:\n  - " + alias + "\n";

		frontmatter = frontmatter.replace(/^---\n/, aliasInsert);
	}
	console.log(frontmatter);
} else {
	// No frontmatter found
	// Insert in front of file
	frontmatter = `---
aliases:
- ${alias}
---`;
}

const fileContent = frontmatter + `*This is a note about [\[${domain}]].*` + "\n\n" + content;

await this.app.vault.adapter.write(tp.file.path(true), fileContent);

%>

UPDATE

  • Fix: incorrect result inserting alias into multi-line array
  • Fix: missing new line after frontmatter
  • Feature: update pre-existing domain link
<%*
/**
 * This template creates a subtopic note
 * When a note has format:
 *     title (domain)
 * 
 * Inserting this template, will perform the following actions:
 *     1. Creates ${title} alias (inserts into frontmatter if present)
 *     2. Inserts *This is a note about [[${domain}]].* at top of note
 */

let match = tp.file.title.match(/^\b([\S\s]+)\b \(\b([\S\s]+)\b\)$/);

if (match === null) {
	// Invalid title format
	new tp.obsidian.Notice(
`*Swnoflake Template Error:*
Note title should have format:
[title] ([domain])`);

	return;
}

// Valid title, insert template

const alias = match[1];
const domain = match[2];

var frontmatter = tp.file.content.match(/^---\n[\s\S]*?---(\n|$)/);
var content = tp.file.content.replace(/^---\n[\s\S]*?---(\n|$)/, "");

if (frontmatter !== null) {
	// Insert alias within existing frontmatter

	frontmatter = frontmatter[0];

	if (frontmatter.match(/aliases *:\n( *- *[\S ]+\n)+/) !== null) {
		// Aliases exists as multi-line array
		const aliasFormat = frontmatter.match(/aliases *:\n( *- *\b[\S ]+?\n)+/)[1];
		const aliasInsert = aliasFormat.replace(/^( *- *)\b([\s\S]+?)$/, "$1" + alias);
		frontmatter = frontmatter.replace(/(aliases *:\n)( *- *\b[\S ]+\n)+/, `$&${aliasInsert}\n`);
	} else if (frontmatter.match(/aliases *: +\[[\w "]+(,[\w "]+)+\]/) !== null) {
		// Aliases exists as single-line array
		frontmatter = frontmatter.replace(/(aliases *: +\[([\w "]+,)+)([\w "]+)\]/, `$1$3, ${alias}]`);
	} else {
		// No aliases exists
		// Create alias in frontmatter
		const aliasInsert = "$&aliases:\n  - " + alias + "\n";

		frontmatter = frontmatter.replace(/^---\n/, aliasInsert);
	}
} else {
	// No frontmatter found, create frontmatter
	frontmatter = `---
aliases:
- ${alias}
---
`;
}

// Update domain
if (content.match(/[*_]This is a note about \[\[([\s\S]+?)]]\.[*_]/) !== null) {
	// Replace previous domain
	content = content.replace(/[*_]This is a note about \[\[([\s\S]+?)]]\.[*_]/, `*This is a note about \[[${domain}]].*`);
} else {
	// No previous domain, add new domain
	content = `*This is a note about [[${domain}]].*` + "\n\n" + content;
}

const fileContent = frontmatter + content;

await this.app.vault.adapter.write(tp.file.path(true), fileContent);

%>
1 Like

I have same needs to create subtopic but i found myself using the following process a lot

  1. when writing in a note, let’s say topicA
  2. I often have some words in topicA that I could expend to another subtopic, so I select the words and turn it into a new note
  3. I insert template in new note and change the name of new note to “topicA- words that i selected”
1 Like