Skip to content

Commit d201262

Browse files
committed
add templater support for new button actions
1 parent 1ea58fb commit d201262

File tree

16 files changed

+184
-72
lines changed

16 files changed

+184
-72
lines changed
File renamed without changes.

exampleVault/Replace Buttons.md renamed to exampleVault/Buttons/Replace Buttons.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,3 @@ action:
101101
replacement: "i am no longer a button\n\nnice"
102102
```
103103
```
104-
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Templater Buttons
2+
Templater Buttons
3+
Templater Buttons
4+
5+
6+
```meta-bind-button
7+
label: Insert Text
8+
hidden: false
9+
class: ""
10+
tooltip: ""
11+
id: ""
12+
style: default
13+
action:
14+
type: "insertIntoNote"
15+
line: 1
16+
value: "templates/templater/Templater Template.md"
17+
templater: true
18+
```

packages/core/src/api/InternalAPI.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,15 @@ export abstract class InternalAPI<Plugin extends IPlugin> {
238238

239239
abstract createContextMenu(items: ContextMenuItemDefinition[]): IContextMenu;
240240

241+
abstract evaluateTemplaterTemplate(templateFilePath: string, targetFilePath: string): Promise<string>;
242+
243+
abstract createNoteWithTemplater(
244+
templateFilePath: string,
245+
folderPath?: string,
246+
fileName?: string,
247+
openNote?: boolean,
248+
): Promise<string | undefined>;
249+
241250
openCommandSelectModal(selectCallback: (selected: Command) => void): void {
242251
this.createSearchModal(new CommandSelectModal(this.plugin, selectCallback)).open();
243252
}

packages/core/src/config/ButtonConfig.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,13 @@ export interface ReplaceInNoteButtonAction {
7474
fromLine: number;
7575
toLine: number;
7676
replacement: string;
77+
templater?: boolean;
7778
}
7879

7980
export interface ReplaceSelfButtonAction {
8081
type: ButtonActionType.REPLACE_SELF;
8182
replacement: string;
83+
templater?: boolean;
8284
}
8385

8486
export interface RegexpReplaceInNoteButtonAction {
@@ -91,6 +93,7 @@ export interface InsertIntoNoteButtonAction {
9193
type: ButtonActionType.INSERT_INTO_NOTE;
9294
line: number;
9395
value: string;
96+
templater?: boolean;
9497
}
9598

9699
export type ButtonAction =

packages/core/src/config/ButtonConfigValidators.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,15 @@ export const V_ReplaceInNoteButtonAction = schemaForType<ReplaceInNoteButtonActi
8989
fromLine: z.number(),
9090
toLine: z.number(),
9191
replacement: z.string(),
92+
templater: z.boolean().optional(),
9293
}),
9394
);
9495

9596
export const V_ReplaceSelfButtonAction = schemaForType<ReplaceSelfButtonAction>()(
9697
z.object({
9798
type: z.literal(ButtonActionType.REPLACE_SELF),
9899
replacement: z.string(),
100+
templater: z.boolean().optional(),
99101
}),
100102
);
101103

@@ -112,6 +114,7 @@ export const V_InsertIntoNoteButtonAction = schemaForType<InsertIntoNoteButtonAc
112114
type: z.literal(ButtonActionType.INSERT_INTO_NOTE),
113115
line: z.number(),
114116
value: z.string(),
117+
templater: z.boolean().optional(),
115118
}),
116119
);
117120

packages/core/src/fields/button/ButtonActionRunner.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@ export class ButtonActionRunner {
237237
await new Promise(resolve => setTimeout(resolve, action.ms));
238238
}
239239

240-
async runTemplaterCreateNoteAction(_action: TemplaterCreateNoteButtonAction): Promise<void> {
241-
throw new Error('Not supported');
240+
async runTemplaterCreateNoteAction(action: TemplaterCreateNoteButtonAction): Promise<void> {
241+
await this.plugin.internal.createNoteWithTemplater(action.templateFile, action.folderPath, action.fileName);
242242
}
243243

244244
async runUpdateMetadataAction(action: UpdateMetadataButtonAction, filePath: string): Promise<void> {
@@ -259,13 +259,17 @@ export class ButtonActionRunner {
259259
}
260260

261261
async runReplaceInNoteAction(action: ReplaceInNoteButtonAction, filePath: string): Promise<void> {
262+
const replacement = action.templater
263+
? await this.plugin.internal.evaluateTemplaterTemplate(action.replacement, filePath)
264+
: action.replacement;
265+
262266
const content = await this.plugin.internal.readFilePath(filePath);
263267

264268
let splitContent = content.split('\n');
265269

266270
splitContent = [
267271
...splitContent.slice(0, action.fromLine - 1),
268-
action.replacement,
272+
replacement,
269273
...splitContent.slice(action.toLine),
270274
];
271275

@@ -286,13 +290,17 @@ export class ButtonActionRunner {
286290
throw new Error('Position of the button in the note is unknown');
287291
}
288292

293+
const replacement = action.templater
294+
? await this.plugin.internal.evaluateTemplaterTemplate(action.replacement, filePath)
295+
: action.replacement;
296+
289297
const content = await this.plugin.internal.readFilePath(filePath);
290298

291299
let splitContent = content.split('\n');
292300

293301
splitContent = [
294302
...splitContent.slice(0, position.lineStart),
295-
action.replacement,
303+
replacement,
296304
...splitContent.slice(position.lineEnd + 1),
297305
];
298306

@@ -316,11 +324,11 @@ export class ButtonActionRunner {
316324

317325
let splitContent = content.split('\n');
318326

319-
splitContent = [
320-
...splitContent.slice(0, action.line - 1),
321-
action.value,
322-
...splitContent.slice(action.line - 1),
323-
];
327+
const replacement = action.templater
328+
? await this.plugin.internal.evaluateTemplaterTemplate(action.value, filePath)
329+
: action.value;
330+
331+
splitContent = [...splitContent.slice(0, action.line - 1), replacement, ...splitContent.slice(action.line - 1)];
324332

325333
await this.plugin.internal.writeFilePath(filePath, splitContent.join('\n'));
326334
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Plugin, TFile, TFolder } from 'obsidian';
2+
import { Templater_RunMode } from 'packages/obsidian/src/ObsUtils';
3+
4+
export type TemplaterPlugin = Plugin & {
5+
templater: Templater;
6+
};
7+
8+
export interface Templater {
9+
create_running_config(
10+
template_file: TFile | undefined,
11+
target_file: TFile,
12+
run_mode: Templater_RunMode,
13+
): Templater_RunningConfig;
14+
15+
read_and_parse_template(config: Templater_RunningConfig): Promise<string>;
16+
17+
create_new_note_from_template(
18+
template: TFile | string,
19+
folder?: TFolder,
20+
filename?: string,
21+
open_new_note?: boolean,
22+
): Promise<TFile | undefined>;
23+
}
24+
25+
export interface Templater_RunningConfig {
26+
template_file: TFile | undefined;
27+
target_file: TFile;
28+
run_mode: Templater_RunMode;
29+
active_file?: TFile | null;
30+
}

packages/obsidian/src/ObsUtils.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { type API as JsEngineAPI } from 'jsEngine/api/API';
22
import type MetaBindPlugin from 'packages/obsidian/src/main';
33
import { type DataviewApi } from 'obsidian-dataview';
4+
import { type Templater, type TemplaterPlugin } from 'packages/obsidian/extraTypes/Templater';
45

56
export function getDataViewPluginAPI(plugin: MetaBindPlugin): DataviewApi {
67
/* eslint-disable */
@@ -13,3 +14,18 @@ export function getJsEnginePluginAPI(plugin: MetaBindPlugin): JsEngineAPI {
1314
const jsEnginePlugin = plugin.dependencyManager.checkDependency('js-engine');
1415
return (jsEnginePlugin as any).api as JsEngineAPI;
1516
}
17+
18+
export enum Templater_RunMode {
19+
CreateNewFromTemplate,
20+
AppendActiveFile,
21+
OverwriteFile,
22+
OverwriteActiveFile,
23+
DynamicProcessor,
24+
StartupTemplate,
25+
}
26+
27+
export function getTemplaterPluginAPI(plugin: MetaBindPlugin): Templater {
28+
/* eslint-disable */
29+
const templaterPlugin = plugin.dependencyManager.checkDependency('templater-obsidian');
30+
return (templaterPlugin as TemplaterPlugin).templater;
31+
}

packages/obsidian/src/ObsidianAPI.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { type UnvalidatedViewFieldDeclaration } from 'packages/core/src/parsers/
99
import { getUUID } from 'packages/core/src/utils/Utils';
1010
import { validateArgs } from 'packages/core/src/utils/ZodUtils';
1111
import { ErrorLevel, MetaBindInternalError } from 'packages/core/src/utils/errors/MetaBindErrors';
12-
import { ObsidianButtonActionRunner } from 'packages/obsidian/src/ObsidianButtonActionRunner';
1312
import { MarkdownRenderChildWidget } from 'packages/obsidian/src/cm6/Cm6_Widgets';
1413
import { FieldMDRC } from 'packages/obsidian/src/FieldMDRC';
1514
import { type FieldBase } from 'packages/core/src/fields/FieldBase';
@@ -24,9 +23,7 @@ export interface ComponentLike {
2423
*/
2524
export class ObsidianAPI extends API<MetaBindPlugin> {
2625
constructor(plugin: MetaBindPlugin) {
27-
super(plugin, {
28-
buttonActionRunner: new ObsidianButtonActionRunner(plugin),
29-
});
26+
super(plugin);
3027
}
3128

3229
public wrapInMDRC(field: FieldBase, containerEl: HTMLElement, component: ComponentLike): FieldMDRC {

0 commit comments

Comments
 (0)