Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to use regex on file path instead of folder templates #974

Merged
merged 9 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 44 additions & 13 deletions docs/src/settings.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,58 @@
# Settings

You can set a `Template folder location` to tell [Templater](https://github.com/SilentVoid13/Templater) to only check this folder for templates.
## General Settings

You can set a timeout for your system commands with the `Timeout` option. A system command that takes longer than what you defined will be canceled and considered as a failure.
- `Template folder location`: Files in this folder will be available as templates.
- `Syntax Highlighting on Desktop` adds syntax highlighting for [Templater](https://github.com/SilentVoid13/Templater) commands in edit mode.
- `Syntax Highlighting on Mobile` adds syntax highlighting for [Templater](https://github.com/SilentVoid13/Templater) commands in edit mode on mobile. Use with caution: this may break live preview on mobile platforms."
- `Automatic jump to cursor` automatically triggers `tp.file.cursor` after inserting a template. You can also set a hotkey to manually trigger `tp.file.cursor`.
- `Trigger Templater on new file creation`: [Templater](https://github.com/SilentVoid13/Templater) will listen for the new file creation event, and, if it matches a rule you've set, replace every command it finds in the new file's content. This makes [Templater](https://github.com/SilentVoid13/Templater) compatible with other plugins like the Daily note core plugin, Calendar plugin, Review plugin, Note refactor plugin, etc.
- Make sure to set up rules under either Folder Templates or File Regex Template below.
- **Warning:** This can be dangerous if you create new files with unknown / unsafe content on creation. Make sure that every new file's content is safe on creation."
- `Show icon in sidebar`: Show [Templater](https://github.com/SilentVoid13/Templater) icon in sidebar ribbon, allowing you to quickly use templates anywhere.

You can set [Templater](https://github.com/SilentVoid13/Templater) to be triggered on new file creation. It will listen for the new file creation event and replace every command it finds in the new file's content.
## Template Hotkeys

This makes Templater compatible with other plugins like the Daily note core plugin, Calendar plugin, Review plugin, Note refactor plugin, ...
Template Hotkeys allows you to bind a template to a hotkey.

## Security Warning
## Folder Templates

It can be dangerous if you create new files with unknown / unsafe content on creation. Make sure that every new file's content is safe on creation.
**Note**: This setting is hidden by default. To view it first enable the `Trigger Template on new file creation` setting. And since it's mutually exclusive with File Regex Templates, enabling one will disable the other.

## Folder Templates
You can specify a template that will automatically be used on a selected folder and children using the `Folder Templates` functionality. The deepest match will be used, so the order of the rules is irrelevant.

Add a rule for "`/`" if you need a catch-all.

## File Regex Templates

**Note**: This setting is hidden by default. To view it first enable the `Trigger Template on new file creation` setting. And since it's mutually exclusive with Folder Templates, enabling one will disable the other.

You can specify regex declarations that a new file's path will be tested against. If a regex matches, the associated template will automatically be used. Rules are tested top-to-bottom, and the first match will be used.

End with a rule for "`.*`" if you need a catch-all.

Use a tool like [Regex101](https://regex101.com/) to verify your regexes.

## Startup Templates

Startup Templates are templates that will get executed once when Templater starts.

These templates won't output anything.

This can be useful to set up templates adding hooks to obsidian events for example.

## User Script Functions

All JavaScript files in this folder will be loaded as CommonJS modules, to import custom [user functions](./user-functions/overview.md).

You can specify a template that will automatically be used on a selected folder and children using the `Folder Templates` functionality.
The folder needs to be accessible from the vault.

**Note**: This setting is hidden by default. To view it first enable the `Trigger Template on new file creation` setting.
Check the [documentation](./user-functions/script-user-functions.md) for more information.

## System Commands
## User System Command Functions

You can enable system commands. This allows you to create [user functions](./user-functions/overview.md) linked to system commands.
Allows you to create [user functions](./user-functions/overview.md) linked to system commands.

### Arbitrary system commands
Check the [documentation](./user-functions/system-user-functions.md) for more information.

It can be dangerous to execute arbitrary system commands from untrusted sources. Only run system commands that you understand, from trusted sources.
**Warning:** It can be dangerous to execute arbitrary system commands from untrusted sources. Only run system commands that you understand, from trusted sources.
31 changes: 31 additions & 0 deletions src/core/Templater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,17 @@ export class Templater {
} while (folder);
}

get_new_file_template_for_file(file: TFile): string | undefined {
const match = this.plugin.settings.file_templates.find((e) => {
const eRegex = new RegExp(e.regex);
return eRegex.test(file.path);
});

if (match && match.template) {
return match.template;
}
}

static async on_file_creation(
templater: Templater,
file: TAbstractFile
Expand Down Expand Up @@ -488,6 +499,26 @@ export class Templater {
return;
}
await templater.write_template_to_file(template_file, file);
} else if (
file.stat.size == 0 &&
templater.plugin.settings.enable_file_templates
) {
const file_template_match =
templater.get_new_file_template_for_file(file);
if (!file_template_match) {
return;
}
const template_file: TFile = await errorWrapper(
async (): Promise<TFile> => {
return resolve_tfile(file_template_match);
},
`Couldn't find template ${file_template_match}`
);
// errorWrapper failed
if (template_file == null) {
return;
}
await templater.write_template_to_file(template_file, file);
} else {
if (file.stat.size <= 100000) {
//https://github.com/SilentVoid13/Templater/issues/873
Expand Down
158 changes: 153 additions & 5 deletions src/settings/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export interface FolderTemplate {
template: string;
}

export interface FileTemplate {
regex: string;
template: string;
}

export const DEFAULT_SETTINGS: Settings = {
command_timeout: 5,
templates_folder: "",
Expand All @@ -23,6 +28,8 @@ export const DEFAULT_SETTINGS: Settings = {
user_scripts_folder: "",
enable_folder_templates: true,
folder_templates: [{ folder: "", template: "" }],
enable_file_templates: false,
file_templates: [{ regex: ".*", template: "" }],
syntax_highlighting: true,
syntax_highlighting_mobile: false,
enabled_templates_hotkeys: [""],
Expand All @@ -40,6 +47,8 @@ export interface Settings {
user_scripts_folder: string;
enable_folder_templates: boolean;
folder_templates: Array<FolderTemplate>;
enable_file_templates: boolean;
file_templates: Array<FileTemplate>;
syntax_highlighting: boolean;
syntax_highlighting_mobile: boolean;
enabled_templates_hotkeys: Array<string>;
Expand All @@ -62,6 +71,7 @@ export class TemplaterSettingTab extends PluginSettingTab {
this.add_templates_hotkeys_setting();
if (this.plugin.settings.trigger_on_file_creation) {
this.add_folder_templates_setting();
this.add_file_templates_setting();
}
this.add_startup_templates_setting();
this.add_user_script_functions_setting();
Expand Down Expand Up @@ -175,9 +185,12 @@ export class TemplaterSettingTab extends PluginSettingTab {
add_trigger_on_new_file_creation_setting(): void {
const desc = document.createDocumentFragment();
desc.append(
"Templater will listen for the new file creation event, and replace every command it finds in the new file's content.",
"Templater will listen for the new file creation event, and, if it matches a rule you've set, replace every command it finds in the new file's content. ",
"This makes Templater compatible with other plugins like the Daily note core plugin, Calendar plugin, Review plugin, Note refactor plugin, etc. ",
desc.createEl("br"),
desc.createEl("br"),
"Make sure to set up rules under either Folder Templates or File Regex Template below.",
desc.createEl("br"),
"This makes Templater compatible with other plugins like the Daily note core plugin, Calendar plugin, Review plugin, Note refactor plugin, ...",
desc.createEl("br"),
desc.createEl("b", {
text: "Warning: ",
Expand Down Expand Up @@ -345,7 +358,7 @@ export class TemplaterSettingTab extends PluginSettingTab {

const descUseNewFileTemplate = document.createDocumentFragment();
descUseNewFileTemplate.append(
"When enabled Templater will make use of the folder templates defined below."
"When enabled, Templater will make use of the folder templates defined below. This option is mutually exclusive with File Regex Templates below, so enabling one will disable the other."
);

new Setting(this.containerEl)
Expand All @@ -354,9 +367,12 @@ export class TemplaterSettingTab extends PluginSettingTab {
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.enable_folder_templates)
.onChange((use_new_file_templates) => {
.onChange((use_new_folder_templates) => {
this.plugin.settings.enable_folder_templates =
use_new_file_templates;
use_new_folder_templates;
if (use_new_folder_templates) {
this.plugin.settings.enable_file_templates = false;
}
this.plugin.save_settings();
// Force refresh
this.display();
Expand Down Expand Up @@ -475,6 +491,138 @@ export class TemplaterSettingTab extends PluginSettingTab {
);
}

add_file_templates_setting(): void {
this.containerEl.createEl("h2", { text: "File Regex Templates" });

const descHeading = document.createDocumentFragment();
descHeading.append(
"File Regex Templates are triggered when a new ",
descHeading.createEl("strong", { text: "empty" }),
" file is created that matches one of them. Templater will fill the empty file with the specified template."
);

new Setting(this.containerEl).setDesc(descHeading);

const descUseNewFileTemplate = document.createDocumentFragment();
descUseNewFileTemplate.append(
"When enabled, Templater will make use of the file regex templates defined below. This option is mutually exclusive with Folder Templates above, so enabling one will disable the other."
);

new Setting(this.containerEl)
.setName("Enable File Regex Templates")
.setDesc(descUseNewFileTemplate)
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.enable_file_templates)
.onChange((use_new_file_templates) => {
this.plugin.settings.enable_file_templates =
use_new_file_templates;
if (use_new_file_templates) {
this.plugin.settings.enable_folder_templates =
false;
}
this.plugin.save_settings();
// Force refresh
this.display();
});
});

if (!this.plugin.settings.enable_file_templates) {
return;
}

new Setting(this.containerEl)
.setName("Add New")
.setDesc(
"Add new file regex. The first match from the top is used, so the order of the rules is important. Use `.*` as a final catch-all, if you need it."
)
.addButton((button: ButtonComponent) => {
button
.setTooltip("Add additional file regex")
.setButtonText("+")
.setCta()
.onClick(() => {
this.plugin.settings.file_templates.push({
regex: "",
template: "",
});
this.plugin.save_settings();
this.display();
});
});

this.plugin.settings.file_templates.forEach((file_template, index) => {
const s = new Setting(this.containerEl)
.addText((cb) => {
cb.setPlaceholder("File Regex")
.setValue(file_template.regex)
.onChange((new_regex) => {
this.plugin.settings.file_templates[index].regex =
new_regex;
this.plugin.save_settings();
});
// @ts-ignore
cb.inputEl.addClass("templater_search");
})
.addSearch((cb) => {
new FileSuggest(
cb.inputEl,
this.plugin,
FileSuggestMode.TemplateFiles
);
cb.setPlaceholder("Template")
.setValue(file_template.template)
.onChange((new_template) => {
this.plugin.settings.file_templates[
index
].template = new_template;
this.plugin.save_settings();
});
// @ts-ignore
cb.containerEl.addClass("templater_search");
})
.addExtraButton((cb) => {
cb.setIcon("up-chevron-glyph")
.setTooltip("Move up")
.onClick(() => {
arraymove(
this.plugin.settings.file_templates,
index,
index - 1
);
this.plugin.save_settings();
this.display();
});
})
.addExtraButton((cb) => {
cb.setIcon("down-chevron-glyph")
.setTooltip("Move down")
.onClick(() => {
arraymove(
this.plugin.settings.file_templates,
index,
index + 1
);
this.plugin.save_settings();
this.display();
});
})
.addExtraButton((cb) => {
cb.setIcon("cross")
.setTooltip("Delete")
.onClick(() => {
this.plugin.settings.file_templates.splice(
index,
1
);
this.plugin.save_settings();
this.display();
});
});
s.infoEl.remove();
});
}

add_startup_templates_setting(): void {
new Setting(this.containerEl).setName("Startup templates").setHeading();

Expand Down