From 0af8205feb79107c292f72a1854ef942785590db Mon Sep 17 00:00:00 2001 From: LeCheenaX <102142515+LeCheenaX@users.noreply.github.com> Date: Sat, 28 Dec 2024 23:38:12 +0800 Subject: [PATCH 1/3] Create Record Modified Notes to Daily Notes.md This template will detect modify behaviors and help you to record which notes that you modified today, automatically inserting these notes to any place of your daily notes. --- .../Record Modified Notes to Daily Notes.md | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md diff --git a/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md b/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md new file mode 100644 index 000000000..46f932e2d --- /dev/null +++ b/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md @@ -0,0 +1,164 @@ +## Concepts +This template will detect modify behaviors and help you to record which notes that you modified today, automatically inserting these notes to any place of your daily notes. +![image](https://github.com/user-attachments/assets/58e1ac58-acf6-498e-8832-dfe3fa0677fe) + +The template is modular that: +1. You don't have to modify your current daily notes templates at all.(But you can also customize a place for recording) +2. You can either insert the note to an existing place like the end of daily note, or modify your daily note template to add a place for inserting. +3. You can customize the query to collect the code. The query is the same as `Dataview Query`. + +## How to use this template? +1. You need to install the Templater plugin and Dataview plugin +2. In setting of Templater plugin, ensure that the folder template is enabled to auto-enforce daily note template to new created daily notes![image](https://github.com/user-attachments/assets/5edefd02-e065-46c6-b170-6f3c81eeb055) + +3. You need to specify a folder to store your templates in the setting of Templater plugin +4. Create a new `.md` file in your template folder +5. Copy the template below and paste it into your `.md` file that just created +6. Modify the `Constants`:`RECORD_NOTE_FOLDER`,`QUERY_STRING`,`START_POSITION`,`END_POSITION` +7. In the setting of Templater plugin, add this template as "start-up template"![image](https://github.com/user-attachments/assets/4448ea44-9cc3-4ae8-b86e-f21381e67868) + + +### The Record Note Folder +By default, the record folder is "Logs/Daily Notes". You should adjust it to your daily note folder. + +### The Query String +You can seamlessly move your dataview query here but deleting the line-breaks. +By default, will use the data in this dataview query: +```dataview +table WITHOUT ID +file.link as "Modified Notes", file.mtime as "Edit Time" +from !"MyTestFolder" +where file.mday = date(today) +sort file.mtime asc +limit 32 +``` + +### Start Position and End Position +This string defines where to insert the data. Not only the admonition plugin is supported, but for all other plugins. +By default, this will insert a table of data to an admonition-callout: +```ad-note +title: Modified Notes on this day +collapse: close +``` +Effect: +![image](https://github.com/user-attachments/assets/58e1ac58-acf6-498e-8832-dfe3fa0677fe) + +It's also recommended to place it under a title(Require this title exist in your daily note template): +``` +START_POSITION = "#### Dataview Query"; +END_POSITION = "#### Dataview JS"; +``` +Effect: +![image](https://github.com/user-attachments/assets/57aa7556-265d-4d5d-b739-4ea9863b1dea) + +If you want to insert to the end of your daily note, just leave `END_POSITION` blank. + +## Template +``` +<%* +// Configuration Constants +const RECORD_NOTE_FOLDER = "Logs/Daily Notes"; +const QUERY_STRING = `table WITHOUT ID file.link as "Modified Notes", file.mtime as "Edit Time" from !"MyTestFolder" where file.mday = date(today) sort file.mtime asc limit 32`; +const START_POSITION = "title: Modified Notes on this day\ncollapse: close"; +const END_POSITION = "````"; +const dv = app.plugins.plugins["dataview"].api; + +// Get today's date in ISO format +let today = moment().format("YYYY-MM-DD"); +let DailyNote = moment(today).format("YYYY-MM-DD"); +let recordNote = DailyNote; +let note = app.vault.getAbstractFileByPath(`${RECORD_NOTE_FOLDER}/${recordNote}.md`); + +// Delay function +function delay(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +new Notice("Autoupdate scripts are running! ", 3000); +console.log("Autoupdate scripts are running! "); + +// Function to create a new note +async function createNewNote() { + await tp.file.create_new("", recordNote, false, RECORD_NOTE_FOLDER); + new Notice(`Created new note ${recordNote} in folder ${RECORD_NOTE_FOLDER}.`, 5000); + console.log(`Created new note ${recordNote} in folder ${RECORD_NOTE_FOLDER}.`); + await delay(500); +} + +// Function to fetch query output +async function fetchQueryOutput() { + try { + return await dv.queryMarkdown(QUERY_STRING); + } catch (error) { + new Notice("⚠️ ERROR querying data: " + error.message, 5000); + console.log(`⚠️ ERROR: ${error}`); + throw error; // Rethrow to handle in the calling function + } +} + +// Function to process query output +function processQueryOutput(queryOutput) { + const lines = queryOutput.split('\n'); + return lines.length > 3 ? queryOutput.trimEnd() : "No note is modified today! "; +} + +// Function to read note content +async function readDailyNoteContent() { + return await app.vault.read(note); +} + +// Function to update the note +async function updateNoteContent(content, recordData) { + const regex = new RegExp(`${START_POSITION}[\\s\\S]*?(?=${END_POSITION})`); + if (regex.test(content)) { + const newContent = content.replace(regex, `${START_POSITION}\n${recordData}\n`); + await app.vault.modify(note, newContent); + new Notice("Daily note auto updated! ", 2000); + console.log("Daily note auto updated! "); + } else { + new Notice("⚠️ ERROR updating note: " + recordNote + "! Check console log.", 5000); + console.log(`⚠️ ERROR: The given pattern "${START_POSITION} ... ${END_POSITION}" is not found in ${recordNote}! `); + } +} + +// Main function to update daily notes +async function updateDailyNotes() { + try { + if (!tp.file.find_tfile(recordNote)) { + await createNewNote(); + } + + const dvqueryOutput = await fetchQueryOutput(); + const recordData = processQueryOutput(dvqueryOutput.value); + const content = await readDailyNoteContent(); + await updateNoteContent(content, recordData); + } catch (error) { + new Notice("⚠️ An unexpected error occurred: " + error.message, 5000); + console.log(`⚠️ ERROR: ${error}`); + } +} + +// Debounce function to limit the rate at which a function can fire +function debounce(func, wait) { + let timeout; + return function(...args) { + clearTimeout(timeout); + timeout = setTimeout(() => func.apply(this, args), wait); + }; +} + +// Set up event listener to run the update function on every file save with debounce +app.vault.on('modify', debounce(async (file) => { + console.log(`Detected File Change: ${file.name}`); + if (file.name === `${recordNote}.md`) { + await delay(200); + } else { + await updateDailyNotes(); + console.log(`Try updating ${recordNote}.md`); + } +}, 60000)); // 60 seconds debounce + +%> +``` + +You can also subscribe to latest update/improvement here: https://github.com/LeCheenaX/Obsidian-useful-scripts/tree/main/Templates From 956ac5ca2cda6148bffd09ec90e8e5e86517eb1c Mon Sep 17 00:00:00 2001 From: LeCheenaX <102142515+LeCheenaX@users.noreply.github.com> Date: Sun, 29 Dec 2024 16:10:28 +0800 Subject: [PATCH 2/3] Update Record Modified Notes to Daily Notes.md Apply the T-template as recommended --- .../Record Modified Notes to Daily Notes.md | 83 ++++++++++++------- 1 file changed, 51 insertions(+), 32 deletions(-) diff --git a/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md b/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md index 46f932e2d..5f381259a 100644 --- a/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md +++ b/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md @@ -1,21 +1,36 @@ -## Concepts +--- +aliases: + - Modified File Recorder +tags: + - seedling + - templater + - dataview + - template +publish: true +--- + +# Record Modified Notes to Daily Notes + This template will detect modify behaviors and help you to record which notes that you modified today, automatically inserting these notes to any place of your daily notes. ![image](https://github.com/user-attachments/assets/58e1ac58-acf6-498e-8832-dfe3fa0677fe) The template is modular that: -1. You don't have to modify your current daily notes templates at all.(But you can also customize a place for recording) -2. You can either insert the note to an existing place like the end of daily note, or modify your daily note template to add a place for inserting. -3. You can customize the query to collect the code. The query is the same as `Dataview Query`. +1. You could use your current daily notes templates without modification. +2. You could also record it after a title or insert it into a specific place by changing the `Constants`. +3. You can customize the query to collect the notes under your rules. The query is the same as `Dataview Query`in this plugin [[dataview]]. + +You can also subscribe to latest update/improvement here: https://github.com/LeCheenaX/Obsidian-useful-scripts/tree/main/Templates ## How to use this template? +Prerequisites: 1. You need to install the Templater plugin and Dataview plugin 2. In setting of Templater plugin, ensure that the folder template is enabled to auto-enforce daily note template to new created daily notes![image](https://github.com/user-attachments/assets/5edefd02-e065-46c6-b170-6f3c81eeb055) - 3. You need to specify a folder to store your templates in the setting of Templater plugin -4. Create a new `.md` file in your template folder -5. Copy the template below and paste it into your `.md` file that just created -6. Modify the `Constants`:`RECORD_NOTE_FOLDER`,`QUERY_STRING`,`START_POSITION`,`END_POSITION` -7. In the setting of Templater plugin, add this template as "start-up template"![image](https://github.com/user-attachments/assets/4448ea44-9cc3-4ae8-b86e-f21381e67868) + +Steps: +1. Copy and Paste the [[#Source Template]] below to a new created `.md` file in your template folder +2. Modify the `Constants`:`RECORD_NOTE_FOLDER`,`QUERY_STRING`,`START_POSITION`,`END_POSITION`to satisfy your own need. +3. In the setting of Templater plugin, add this template as "startup template"![image](https://github.com/user-attachments/assets/f75144e7-6f82-48dd-a098-b3b43b00538a) ### The Record Note Folder @@ -24,6 +39,7 @@ By default, the record folder is "Logs/Daily Notes". You should adjust it to you ### The Query String You can seamlessly move your dataview query here but deleting the line-breaks. By default, will use the data in this dataview query: +```` ```dataview table WITHOUT ID file.link as "Modified Notes", file.mtime as "Edit Time" @@ -32,15 +48,19 @@ where file.mday = date(today) sort file.mtime asc limit 32 ``` - +```` ### Start Position and End Position This string defines where to insert the data. Not only the admonition plugin is supported, but for all other plugins. -By default, this will insert a table of data to an admonition-callout: + +By default, this will insert a table of data to an [[obsidian-admonition|admonition-callout]]: +```` ```ad-note title: Modified Notes on this day collapse: close + ``` -Effect: +```` +Showcase: ![image](https://github.com/user-attachments/assets/58e1ac58-acf6-498e-8832-dfe3fa0677fe) It's also recommended to place it under a title(Require this title exist in your daily note template): @@ -48,13 +68,14 @@ It's also recommended to place it under a title(Require this title exist in your START_POSITION = "#### Dataview Query"; END_POSITION = "#### Dataview JS"; ``` -Effect: +Showcase: ![image](https://github.com/user-attachments/assets/57aa7556-265d-4d5d-b739-4ea9863b1dea) If you want to insert to the end of your daily note, just leave `END_POSITION` blank. -## Template -``` +## Source Template + +```markdown <%* // Configuration Constants const RECORD_NOTE_FOLDER = "Logs/Daily Notes"; @@ -67,7 +88,6 @@ const dv = app.plugins.plugins["dataview"].api; let today = moment().format("YYYY-MM-DD"); let DailyNote = moment(today).format("YYYY-MM-DD"); let recordNote = DailyNote; -let note = app.vault.getAbstractFileByPath(`${RECORD_NOTE_FOLDER}/${recordNote}.md`); // Delay function function delay(ms) { @@ -75,14 +95,14 @@ function delay(ms) { } new Notice("Autoupdate scripts are running! ", 3000); -console.log("Autoupdate scripts are running! "); +console.log("[Modified File Recorder] Autoupdate scripts are running! "); // Function to create a new note async function createNewNote() { await tp.file.create_new("", recordNote, false, RECORD_NOTE_FOLDER); new Notice(`Created new note ${recordNote} in folder ${RECORD_NOTE_FOLDER}.`, 5000); - console.log(`Created new note ${recordNote} in folder ${RECORD_NOTE_FOLDER}.`); - await delay(500); + console.log(`[Modified File Recorder] Created new note ${recordNote} in folder ${RECORD_NOTE_FOLDER}.`); + await delay(2000); } // Function to fetch query output @@ -91,7 +111,7 @@ async function fetchQueryOutput() { return await dv.queryMarkdown(QUERY_STRING); } catch (error) { new Notice("⚠️ ERROR querying data: " + error.message, 5000); - console.log(`⚠️ ERROR: ${error}`); + console.log(`[Modified File Recorder] ⚠️ ERROR: ${error}`); throw error; // Rethrow to handle in the calling function } } @@ -103,21 +123,21 @@ function processQueryOutput(queryOutput) { } // Function to read note content -async function readDailyNoteContent() { +async function readDailyNoteContent(note) { return await app.vault.read(note); } // Function to update the note -async function updateNoteContent(content, recordData) { +async function updateNoteContent(content, recordData, note) { const regex = new RegExp(`${START_POSITION}[\\s\\S]*?(?=${END_POSITION})`); if (regex.test(content)) { const newContent = content.replace(regex, `${START_POSITION}\n${recordData}\n`); await app.vault.modify(note, newContent); new Notice("Daily note auto updated! ", 2000); - console.log("Daily note auto updated! "); + console.log("[Modified File Recorder] Daily note auto updated! "); } else { new Notice("⚠️ ERROR updating note: " + recordNote + "! Check console log.", 5000); - console.log(`⚠️ ERROR: The given pattern "${START_POSITION} ... ${END_POSITION}" is not found in ${recordNote}! `); + console.log(`[Modified File Recorder] ⚠️ ERROR: The given pattern "${START_POSITION} ... ${END_POSITION}" is not found in ${recordNote}! `); } } @@ -127,14 +147,15 @@ async function updateDailyNotes() { if (!tp.file.find_tfile(recordNote)) { await createNewNote(); } - + + let note = app.vault.getAbstractFileByPath(`${RECORD_NOTE_FOLDER}/${recordNote}.md`); const dvqueryOutput = await fetchQueryOutput(); const recordData = processQueryOutput(dvqueryOutput.value); - const content = await readDailyNoteContent(); - await updateNoteContent(content, recordData); + const content = await readDailyNoteContent(note); + await updateNoteContent(content, recordData, note); } catch (error) { new Notice("⚠️ An unexpected error occurred: " + error.message, 5000); - console.log(`⚠️ ERROR: ${error}`); + console.log(`[Modified File Recorder] ⚠️ An unexpected error occurred: ${error}`); } } @@ -149,16 +170,14 @@ function debounce(func, wait) { // Set up event listener to run the update function on every file save with debounce app.vault.on('modify', debounce(async (file) => { - console.log(`Detected File Change: ${file.name}`); + console.log(`[Modified File Recorder] Detected File Change: ${file.name}`); if (file.name === `${recordNote}.md`) { await delay(200); } else { + console.log(`[Modified File Recorder] Try updating ${recordNote}.md`); await updateDailyNotes(); - console.log(`Try updating ${recordNote}.md`); } }, 60000)); // 60 seconds debounce %> ``` - -You can also subscribe to latest update/improvement here: https://github.com/LeCheenaX/Obsidian-useful-scripts/tree/main/Templates From b2afb3e020a965ffb9e7e3ed5827aa900ce856a3 Mon Sep 17 00:00:00 2001 From: LeCheenaX <102142515+LeCheenaX@users.noreply.github.com> Date: Sun, 29 Dec 2024 16:40:38 +0800 Subject: [PATCH 3/3] Update Record Modified Notes to Daily Notes.md Support custom daily note format. Improvements in logging behaviors. --- .../Record Modified Notes to Daily Notes.md | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md b/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md index 5f381259a..a1285ad30 100644 --- a/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md +++ b/03 - Showcases & Templates/Templates/Plugin-specific templates/Templater templates/Record Modified Notes to Daily Notes.md @@ -29,7 +29,7 @@ Prerequisites: Steps: 1. Copy and Paste the [[#Source Template]] below to a new created `.md` file in your template folder -2. Modify the `Constants`:`RECORD_NOTE_FOLDER`,`QUERY_STRING`,`START_POSITION`,`END_POSITION`to satisfy your own need. +2. Modify the `Constants`:`RECORD_NOTE_FOLDER`,`QUERY_STRING`,`START_POSITION`,`END_POSITION`, `DAILY_NOTE_FORMAT` to satisfy your own need. 3. In the setting of Templater plugin, add this template as "startup template"![image](https://github.com/user-attachments/assets/f75144e7-6f82-48dd-a098-b3b43b00538a) @@ -73,6 +73,18 @@ Showcase: If you want to insert to the end of your daily note, just leave `END_POSITION` blank. +### Daily Note Format +Ensure the format is corresponding to all cases below: +1. Your current daily notes +2. Plugins that may modify daily note (if you have, such as Periodic Note plugin) +3. Templates that may modify daily note (if you have, such as `folder template`/`startup template` in templater plugin) + +By default, the format will be "YYYY-MM-DD", which will target on daily note with file name: `2024-12-23.md` for example. + +Misplacing the daily note format may cause issues such as templater could not fetch the target note. + +Also be of caution if you have a template file that will auto-rename the file name of your daily note. + ## Source Template ```markdown @@ -81,13 +93,15 @@ If you want to insert to the end of your daily note, just leave `END_POSITION` b const RECORD_NOTE_FOLDER = "Logs/Daily Notes"; const QUERY_STRING = `table WITHOUT ID file.link as "Modified Notes", file.mtime as "Edit Time" from !"MyTestFolder" where file.mday = date(today) sort file.mtime asc limit 32`; const START_POSITION = "title: Modified Notes on this day\ncollapse: close"; -const END_POSITION = "````"; -const dv = app.plugins.plugins["dataview"].api; +const END_POSITION = "````"; +const DAILY_NOTE_FORMAT = "YYYY-MM-DD"; + // Get today's date in ISO format let today = moment().format("YYYY-MM-DD"); -let DailyNote = moment(today).format("YYYY-MM-DD"); +let DailyNote = moment(today).format(DAILY_NOTE_FORMAT); let recordNote = DailyNote; +const dv = app.plugins.plugins["dataview"].api; // Delay function function delay(ms) {