Skip to content

Commit fd8c40c

Browse files
BeatLinkBeatLinknishantwrp
authored
feat: allow using notebook for storing templates (#63)
* Implement Feature Request #62 * Fix tests * Add details to readme * refactor: update documentation and variable names Co-authored-by: BeatLink <beatlink+git@simplelogin.co> Co-authored-by: Nishant Mittal <mittalnishant14@outlook.com>
1 parent 53c3bca commit fd8c40c

6 files changed

Lines changed: 45 additions & 5 deletions

File tree

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ This plugin allows you to create templates in Joplin and use them to create new
2424
- [Advanced Usage](#advanced-usage)
2525
- [Special variables](#special-variables)
2626
- [Default Templates](#default-templates)
27+
- [Using Notebooks or Tags for Templates](#using-notebooks-or-tags-for-templates)
2728
- [Changelog](#changelog)
2829
- [Supporting](#supporting)
2930
- [Contributing](#contributing)
@@ -174,6 +175,11 @@ This note contains the meeting minutes of the weekly meet held on {{ datetime }}
174175
## Default Templates
175176
You can define the templates you use the most as default templates. Currently you can have two default templates. One for `notes` and one for `to-dos`. You can also assign keyboard shortcuts to these defaults, so that you can quickly create a new note/to-do with the respective default template.
176177

178+
## Using Notebooks to store templates
179+
Now, the plugin also supports using notebooks to store templates instead of tags. You can start using notebooks to store your templates by going to the plugin settings and selecting `Notebook` instead of `Tag`.
180+
181+
Now, any note or todo placed in a notebook titled "Templates" will be considered a template.
182+
177183
## Changelog
178184
See [CHANGELOG.md](https://github.com/joplin/plugin-templates/blob/master/CHANGELOG.md).
179185

src/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,20 @@ joplin.plugins.register({
4040
label: "Apply tags while inserting template",
4141
description: "Apply tags using 'template_tags' variable while inserting template to notes/to-dos.",
4242
section: "templatesPlugin"
43-
}
43+
},
44+
"templatesSource":{
45+
public: true,
46+
type: SettingItemType.String,
47+
isEnum: true,
48+
value: "tag",
49+
options: {
50+
"tag": "Tag",
51+
"notebook": "Notebook"
52+
},
53+
label: "Are templates set with tags or stored in a notebook?",
54+
description: "If set to 'Tag', any note/to-do with a 'template' tag is considered a template. If set to 'Notebook', any note/todo stored in a notebook titled 'Templates' is considered a template.",
55+
section: "templatesPlugin"
56+
},
4457
});
4558

4659

src/utils/folders.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import joplin from "api";
2+
import { fetchAllItems } from "./dataApi";
3+
import { Note } from "./templates";
24

35
export const getSelectedFolder = async (): Promise<string> => {
46
const folder = await joplin.workspace.selectedFolder();
@@ -10,6 +12,10 @@ export const createFolder = async (title: string): Promise<string> => {
1012
return folder.id;
1113
}
1214

15+
export const getAllNotesInFolder = async (title: string): Promise<Note[]> => {
16+
return await fetchAllItems(["search"], { query: `notebook:${title}`, fields: ["id", "title", "body"]})
17+
}
18+
1319
export const doesFolderExist = async (folderId: string): Promise<boolean> => {
1420
try {
1521
await joplin.data.get([ "folders", folderId ], { fields: ["title"] });

src/utils/templates.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import joplin from "api";
2+
import { getAllNotesInFolder } from "./folders";
23
import { getAllNotesWithTag, getAllTagsWithTitle } from "./tags";
34

45
export interface Note {
@@ -25,10 +26,17 @@ const removeDuplicateTemplates = (templates: Note[]) => {
2526

2627
const getAllTemplates = async () => {
2728
let templates: Note[] = [];
28-
const templateTags = await getAllTagsWithTitle("template");
2929

30-
for (const tag of templateTags) {
31-
templates = templates.concat(await getAllNotesWithTag(tag.id));
30+
const templatesSource = await joplin.settings.value("templatesSource");
31+
32+
if (templatesSource == "tag"){
33+
const templateTags = await getAllTagsWithTitle("template");
34+
35+
for (const tag of templateTags) {
36+
templates = templates.concat(await getAllNotesWithTag(tag.id));
37+
}
38+
} else {
39+
templates = templates.concat(await getAllNotesInFolder("Templates"));
3240
}
3341

3442
templates = removeDuplicateTemplates(templates);

tests/mock-joplin-api.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ export default {
1414
},
1515
settings: {
1616
// eslint-disable-next-line @typescript-eslint/no-unused-vars
17-
globalValue: async (setting: string): Promise<string> => { return ""; }
17+
globalValue: async (setting: string): Promise<string> => { return ""; },
18+
value: async (setting: string): Promise<string> => { return ""; }
1819
},
1920
require: (): unknown => { return ""; }
2021
};

tests/utils/templates.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ describe("Get user template selection", () => {
2929
}
3030
});
3131

32+
jest.spyOn(joplin.settings, "value").mockImplementation(async (setting: string) => {
33+
if (setting === "templatesSource") {
34+
return "tag";
35+
}
36+
});
37+
3238
const expectTemplatesSelector = (templates: DropdownOption[], selectedValue: DropdownOption) => {
3339
jest.spyOn(joplin.commands, "execute").mockImplementation(async (cmd: string, props: Record<string, unknown>) => {
3440
expect(cmd).toEqual("showPrompt");

0 commit comments

Comments
 (0)