### 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, "[]" + "("+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, "[]" + "("+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, "[]" + "("+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, "[]" + "("+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();
%>
```