### Version 1.3 ```js <%* const dv = app.plugins.plugins["dataview"].api; const openPublishPanel = app.commands.commands["publish:view-changes"].callback; const created_generated_files = new Date("2025/05/01").toJSON().slice(0, 10); const currentScriptRunDate = new Date().toJSON().slice(0, 10); // Add as many filenames and queries as you'd like! const postsAndNotes = new Map([ [ "Recent Posts", 'TABLE without ID dateformat(created, "yyyy.LL.dd") AS Date, file.link AS Post, language as Lang, description as Description, "[![](" + cover + ")]" + "("+replace(file.path," ", "%20")+")" AS Cover, map(tags, (x) => "#"+x) AS Hashtags FROM "BLOG" WHERE publish AND !contains(permalink, "--hidden") AND permalink != "blog" AND permalink != "all-posts" SORT created desc LIMIT 10', ], [ "All Posts", 'TABLE without ID dateformat(created, "yyyy.LL.dd") AS Date, file.link AS Post, language as Lang, map(tags, (x) => "#"+x) AS Hashtags FROM "BLOG" WHERE publish AND !contains(permalink, "--hidden") AND permalink != "blog" AND permalink != "all-posts" SORT created desc', ], ]); const storyIdeas = new Map([ [ "all-story-ideas-it--hidden", 'TABLE without ID idea_n AS "N°", title_it AS Titolo, idea_it AS Idea, dateformat(created, "yyyy.LL.dd") AS Data FROM "_PROGETTI/SCRITTURA/IDEE/STORY IDEAS" SORT idea_n DESC' ], [ "all-story-ideas-en--hidden", 'TABLE without ID idea_n AS "N°", title_en AS Title, idea_en AS Idea, dateformat(created, "yyyy.LL.dd") AS Data FROM "_PROGETTI/SCRITTURA/IDEE/STORY IDEAS" SORT idea_n DESC' ] ]) //const folder = "BLOG/RESOURCES"; const resourcesFolder = "BLOG/RESOURCES"; // Cartella per i file generati dalle query await postsAndNotes.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename, false, resourcesFolder); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const permalink = `${filename.toLowerCase().replaceAll(" ","-")+(filename == "Recent Posts" ? "--hidden" : "")}` const queryOutput = await dv.queryMarkdown(query); const fileContent = `---\npublish: true\npermalink: "${permalink}"\ncreated: ${created_generated_files}\nupdated: ${currentScriptRunDate}\ncssclasses: ${permalink}\n---\n%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); await storyIdeas.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename, false, resourcesFolder); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); const fileContent = `---\npublish: false\npermalink: "${filename}"\n---\n%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); // --- SEZIONE PER AGGIORNARE LA DATA 'updated' DEI POST IN SPECIFICHE CARTELLE --- // MODIFICA QUESTO ELENCO per includere tutte le cartelle che vuoi processare. // Esempio: ["BLOG", "SNIPPETS", "PERCORSI/DI/APPRENDIMENTO/TEMA SPECIFICO"] const foldersToProcess = [ //"BLOG", "LEARNING/DRAWING", "LEARNING/SCRIVENER 3", "LEARNING/SNIPPETS", "BLOG", "SCRITTURA/IDEE/STORY IDEAS" //"LEARNING/SCRIVENER 3" // Esempio con sottocartella // Aggiungi altre cartelle o percorsi qui ]; // La cartella 'resourcesFolder' (BLOG/RESOURCES) viene esclusa di default // per evitare di processare i file generati automaticamente da questo script. const excludedFolders = [resourcesFolder, "BLOG/LEGACY", "BLOG/attachments"]; let filesToUpdate = []; const allMarkdownFiles = app.vault.getMarkdownFiles(); for (const folderPath of foldersToProcess) { const filesInFolder = allMarkdownFiles.filter(file =>{ // Verifica che il file sia nella cartella corrente (o sue sottocartelle) const isInCurrentFolder = file.path.startsWith(folderPath + (folderPath.endsWith("/") ? "" : "/")); if (!isInCurrentFolder) return false; // Verifica che il file non sia in una delle cartelle escluse for (const excludedPath of excludedFolders) { if (file.path.startsWith(excludedPath + (excludedPath.endsWith("/") ? "" : "/"))) { return false; // Escludi se il file è in una cartella esclusa } } return true; // Includi il file se passa tutti i controlli }); filesToUpdate.push(...filesInFolder); } // Rimuove i duplicati nel caso in cui le cartelle specificate si sovrappongano // (es. se "LEARNING" e "LEARNING/SCRIVENER 3" fossero entrambe in foldersToProcess) const uniqueFilePaths = Array.from(new Set(filesToUpdate.map(f => f.path))); const uniqueFilesToUpdate = uniqueFilePaths.map(path => filesToUpdate.find(f => f.path === path)); if (uniqueFilesToUpdate.length > 0) { new Notice(`🔍 Found ${uniqueFilesToUpdate.length} files in specified folders to check for 'updated' date.`); } else { new Notice(`ℹ️ No files found in specified folders to update.`); } for (const postFile of uniqueFilesToUpdate) { try { await app.fileManager.processFrontMatter(postFile, (frontmatter) => { let fmModified = false; // Flag per tracciare se il frontmatter è stato modificato // 1. Gestione della proprietà 'updated' const fileLastModifiedDate = new Date(postFile.stat.mtime).toJSON().slice(0, 10); // Formato YYYY-MM-DD const fileBirthDate = new Date(postFile.stat.ctime).toJSON().slice(0, 10); if (frontmatter.updated === undefined) { frontmatter.updated = fileLastModifiedDate; new Notice(`Added "updated: ${fileLastModifiedDate}" to ${postFile.basename}.`); fmModified = true; } else if (frontmatter.updated !== fileLastModifiedDate) { frontmatter.updated = fileLastModifiedDate; new Notice(`Changed "updated" to ${fileLastModifiedDate} in ${postFile.basename}.`); fmModified = true; } // 2. Gestione della proprietà 'created' if (frontmatter.created === undefined) { frontmatter.created = fileBirthDate; new Notice(`Added "created: ${fileBirthDate}" to ${postFile.basename}.`); fmModified = true; } // 3. Gestione della proprietà 'publish' if (frontmatter.publish === undefined) { frontmatter.publish = false; // Imposta 'publish' a false se non definito new Notice(`Added "publish: false" to ${postFile.basename}.`); fmModified = true; } // Potresti aggiungere una notifica singola se qualcosa è stato modificato, // ma le notifiche individuali sopra sono più specifiche. // if (fmModified) { // new Notice(`Frontmatter updated for ${postFile.basename}.`); // } }); } catch (error) { new Notice(`⚠️ ERROR updating frontmatter for ${postFile.basename}. Check console.`, 0); console.error(`Error processing frontmatter for ${postFile.path}:`, error); } } // --- FINE SEZIONE --- // --- NUOVA SEZIONE: AGGIORNAMENTO SPECIFICO 'updated' PER UN ELENCO DI FILE --- // MODIFICA QUESTO ELENCO per includere i percorsi dei file specifici // da aggiornare con la data odierna. const specificFilePathsToForceUpdate = [ "BLOG/Blog.md", // Esempio // "PERCORSO_COMPLETO/ALTRO_FILE.md", // Aggiungi altri file qui // "NOTE_IMPORTANTİ/NotaSpeciale.md" ]; if (specificFilePathsToForceUpdate.length > 0) { new Notice(`⚙️ Starting force update of 'updated' date for ${specificFilePathsToForceUpdate.length} specific file(s).`); } for (const filePath of specificFilePathsToForceUpdate) { const specificFile = app.vault.getAbstractFileByPath(filePath); if (specificFile && specificFile instanceof tp.obsidian.TFile) { try { await app.fileManager.processFrontMatter(specificFile, (fm) => { if (fm.updated !== currentScriptRunDate) { fm.updated = currentScriptRunDate; new Notice(`Updated "updated" date in ${specificFile.basename} to ${currentScriptRunDate}.`); } else { new Notice(`"updated" date in ${specificFile.basename} is already ${currentScriptRunDate}. No change needed.`); } // OPZIONALE: Gestisci 'created' e 'publish' per questi file specifici se necessario. // Esempio per 'created': // if (fm.created === undefined) { // const birthDate = new Date(specificFile.stat.ctime).toJSON().slice(0,10); // fm.created = birthDate; // new Notice(`Added "created: ${birthDate}" to ${specificFile.basename}.`); // } // Esempio per 'publish' (adatta true/false secondo necessità): // if (fm.publish === undefined) { // fm.publish = true; // o false // new Notice(`Added "publish" status to ${specificFile.basename}.`); // } }); } catch (error) { new Notice(`⚠️ ERROR updating frontmatter for ${specificFile.basename} (${filePath}). Check console.`, 0); console.error(`Error processing frontmatter for ${filePath}:`, error); } } else { new Notice(`⚠️ File ${filePath} not found or is not a TFile. Cannot force update "updated" date.`, 0); } } // --- FINE AGGIORNAMENTO SPECIFICO PER ELENCO --- openPublishPanel(); %> ``` ### Version 1.2 ```js <%* const dv = app.plugins.plugins["dataview"].api; const openPublishPanel = app.commands.commands["publish:view-changes"].callback; const created_generated_files = new Date("2025/05/01").toJSON().slice(0, 10); const currentScriptRunDate = new Date().toJSON().slice(0, 10); // Add as many filenames and queries as you'd like! const postsAndNotes = new Map([ [ "Recent Posts", 'TABLE without ID dateformat(created, "yyyy.LL.dd") AS Date, file.link AS Post, language as Lang, description as Description, "[![](" + cover + ")]" + "("+replace(file.path," ", "%20")+")" AS Cover, map(tags, (x) => "#"+x) AS Hashtags FROM "BLOG" WHERE publish AND !contains(permalink, "--hidden") AND permalink != "blog" AND permalink != "all-posts" SORT created desc LIMIT 10', ], [ "All Posts", 'TABLE without ID dateformat(created, "yyyy.LL.dd") AS Date, file.link AS Post, language as Lang, map(tags, (x) => "#"+x) AS Hashtags FROM "BLOG" WHERE publish AND !contains(permalink, "--hidden") AND permalink != "blog" AND permalink != "all-posts" SORT created desc', ], ]); const storyIdeas = new Map([ [ "all-story-ideas-it--hidden", 'TABLE without ID idea_n AS "N°", title_it AS Titolo, idea_it AS Idea, dateformat(created, "yyyy.LL.dd") AS Data FROM "_PROGETTI/SCRITTURA/IDEE/STORY IDEAS" SORT idea_n DESC' ], [ "all-story-ideas-en--hidden", 'TABLE without ID idea_n AS "N°", title_en AS Title, idea_en AS Idea, dateformat(created, "yyyy.LL.dd") AS Data FROM "_PROGETTI/SCRITTURA/IDEE/STORY IDEAS" SORT idea_n DESC' ] ]) //const folder = "BLOG/RESOURCES"; const resourcesFolder = "BLOG/RESOURCES"; // Cartella per i file generati dalle query await postsAndNotes.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename, false, resourcesFolder); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const permalink = `${filename.toLowerCase().replaceAll(" ","-")+(filename == "Recent Posts" ? "--hidden" : "")}` const queryOutput = await dv.queryMarkdown(query); const fileContent = `---\npublish: true\npermalink: "${permalink}"\ncreated: ${created_generated_files}\nupdated: ${currentScriptRunDate}\ncssclasses: ${permalink}\n---\n%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); await storyIdeas.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename, false, resourcesFolder); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); const fileContent = `---\npublish: false\npermalink: "${filename}"\n---\n%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); // --- SEZIONE PER AGGIORNARE LA DATA 'updated' DEI POST IN SPECIFICHE CARTELLE --- // MODIFICA QUESTO ELENCO per includere tutte le cartelle che vuoi processare. // Esempio: ["BLOG", "SNIPPETS", "PERCORSI/DI/APPRENDIMENTO/TEMA SPECIFICO"] const foldersToProcess = [ //"BLOG", "LEARNING/DRAWING", "LEARNING/SCRIVENER 3", "LEARNING/SNIPPETS", "BLOG", "SCRITTURA/IDEE/STORY IDEAS" //"LEARNING/SCRIVENER 3" // Esempio con sottocartella // Aggiungi altre cartelle o percorsi qui ]; // La cartella 'resourcesFolder' (BLOG/RESOURCES) viene esclusa di default // per evitare di processare i file generati automaticamente da questo script. const excludedFolders = [resourcesFolder, "BLOG/LEGACY", "BLOG/attachments"]; let filesToUpdate = []; const allMarkdownFiles = app.vault.getMarkdownFiles(); for (const folderPath of foldersToProcess) { const filesInFolder = allMarkdownFiles.filter(file =>{ // Verifica che il file sia nella cartella corrente (o sue sottocartelle) const isInCurrentFolder = file.path.startsWith(folderPath + (folderPath.endsWith("/") ? "" : "/")); if (!isInCurrentFolder) return false; // Verifica che il file non sia in una delle cartelle escluse for (const excludedPath of excludedFolders) { if (file.path.startsWith(excludedPath + (excludedPath.endsWith("/") ? "" : "/"))) { return false; // Escludi se il file è in una cartella esclusa } } return true; // Includi il file se passa tutti i controlli }); filesToUpdate.push(...filesInFolder); } // Rimuove i duplicati nel caso in cui le cartelle specificate si sovrappongano // (es. se "LEARNING" e "LEARNING/SCRIVENER 3" fossero entrambe in foldersToProcess) const uniqueFilePaths = Array.from(new Set(filesToUpdate.map(f => f.path))); const uniqueFilesToUpdate = uniqueFilePaths.map(path => filesToUpdate.find(f => f.path === path)); if (uniqueFilesToUpdate.length > 0) { new Notice(`🔍 Found ${uniqueFilesToUpdate.length} files in specified folders to check for 'updated' date.`); } else { new Notice(`ℹ️ No files found in specified folders to update.`); } for (const postFile of uniqueFilesToUpdate) { try { await app.fileManager.processFrontMatter(postFile, (frontmatter) => { let fmModified = false; // Flag per tracciare se il frontmatter è stato modificato // 1. Gestione della proprietà 'updated' const fileLastModifiedDate = new Date(postFile.stat.mtime).toJSON().slice(0, 10); // Formato YYYY-MM-DD const fileBirthDate = new Date(postFile.stat.ctime).toJSON().slice(0, 10); if (frontmatter.updated === undefined) { frontmatter.updated = fileLastModifiedDate; new Notice(`Added "updated: ${fileLastModifiedDate}" to ${postFile.basename}.`); fmModified = true; } else if (frontmatter.updated !== fileLastModifiedDate) { frontmatter.updated = fileLastModifiedDate; new Notice(`Changed "updated" to ${fileLastModifiedDate} in ${postFile.basename}.`); fmModified = true; } // 2. Gestione della proprietà 'created' if (frontmatter.created === undefined) { frontmatter.created = fileBirthDate; new Notice(`Added "created: ${fileBirthDate}" to ${postFile.basename}.`); fmModified = true; } // 3. Gestione della proprietà 'publish' if (frontmatter.publish === undefined) { frontmatter.publish = false; // Imposta 'publish' a false se non definito new Notice(`Added "publish: false" to ${postFile.basename}.`); fmModified = true; } // Potresti aggiungere una notifica singola se qualcosa è stato modificato, // ma le notifiche individuali sopra sono più specifiche. // if (fmModified) { // new Notice(`Frontmatter updated for ${postFile.basename}.`); // } }); } catch (error) { new Notice(`⚠️ ERROR updating frontmatter for ${postFile.basename}. Check console.`, 0); console.error(`Error processing frontmatter for ${postFile.path}:`, error); } } // --- FINE SEZIONE --- openPublishPanel(); %> ``` ### Version 1.1 ```js <%* const dv = app.plugins.plugins["dataview"].api; const openPublishPanel = app.commands.commands["publish:view-changes"].callback; const created = new Date("2025/05/01").toJSON().slice(0, 10); const updated = new Date().toJSON().slice(0, 10); // Add as many filenames and queries as you'd like! const postsAndNotes = new Map([ [ "Recent Posts", 'TABLE without ID dateformat(created, "yyyy.LL.dd") AS Date, file.link AS Post, language as Lang, description as Description, "[![](" + cover + ")]" + "("+replace(file.path," ", "%20")+")" AS Cover, map(tags, (x) => "#"+x) AS Hashtags FROM "BLOG" WHERE publish AND !contains(permalink, "--hidden") SORT created desc LIMIT 10', ], [ "All Posts", 'TABLE without ID dateformat(created, "yyyy.LL.dd") AS Date, file.link AS Post, language as Lang, map(tags, (x) => "#"+x) AS Hashtags FROM "BLOG" WHERE publish AND !contains(permalink, "--hidden") SORT created desc', ], ]); const storyIdeas = new Map([ [ "all-story-ideas-it--hidden", 'TABLE without ID idea_n AS "N°", title_it AS Titolo, idea_it AS Idea, dateformat(created, "yyyy.LL.dd") AS Data FROM "_PROGETTI/SCRITTURA/IDEE/STORY IDEAS" SORT idea_n DESC' ], [ "all-story-ideas-en--hidden", 'TABLE without ID idea_n AS "N°", title_en AS Title, idea_en AS Idea, dateformat(created, "yyyy.LL.dd") AS Data FROM "_PROGETTI/SCRITTURA/IDEE/STORY IDEAS" SORT idea_n DESC' ] ]) const folder = "BLOG/RESOURCES"; await postsAndNotes.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename, false, folder); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const permalink = `${filename.toLowerCase().replaceAll(" ","-")+"--hidden"}` const queryOutput = await dv.queryMarkdown(query); const fileContent = `---\npublish: true\npermalink: "${permalink}"\ncreated: ${created}\nupdated: ${updated}\ncssclasses: ${permalink}\n---\n%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); await storyIdeas.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename, false, folder); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); const fileContent = `---\npublish: false\npermalink: "${filename}"\n---\n%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); openPublishPanel(); %> ``` ### Version 1.0 ```js <%* const dv = app.plugins.plugins["dataview"].api; const openPublishPanel = app.commands.commands["publish:view-changes"].callback; // Add as many filenames and queries as you'd like! const postsAndNotes = new Map([ [ "recent-new-post--hidden", 'TABLE without ID dateformat(created, "yyyy.LL.dd") AS Date, file.link AS Post, language as Lang, description as Description, "[![](" + cover + ")]" + "("+replace(file.path," ", "%20")+")" AS Cover, map(tags, (x) => "#"+x) AS Hashtags FROM "BLOG" WHERE publish AND !contains(permalink, "--hidden") SORT created desc LIMIT 10', ], [ "all-post--hidden", 'TABLE without ID dateformat(created, "yyyy.LL.dd") AS Date, file.link AS Post, language as Lang, map(tags, (x) => "#"+x) AS Hashtags FROM "BLOG" WHERE publish AND !contains(permalink, "--hidden") SORT created desc', ], ]); const storyIdeas = new Map([ [ "all-story-ideas-it--hidden", 'TABLE without ID idea_n AS "N°", title_it AS Titolo, idea_it AS Idea, dateformat(created, "yyyy.LL.dd") AS Data FROM "_PROGETTI/SCRITTURA/IDEE/STORY IDEAS" SORT idea_n DESC' ], [ "all-story-ideas-en--hidden", 'TABLE without ID idea_n AS "N°", title_en AS Title, idea_en AS Idea, dateformat(created, "yyyy.LL.dd") AS Data FROM "_PROGETTI/SCRITTURA/IDEE/STORY IDEAS" SORT idea_n DESC' ] ]) const folder = "BLOG/RESOURCES"; await postsAndNotes.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename, false, folder); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); const fileContent = `---\npublish: true\npermalink: "${filename}"\n---\n%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); await storyIdeas.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename, false, folder); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); const fileContent = `---\npublish: false\npermalink: "${filename}"\n---\n%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); openPublishPanel(); %> ```