Skip to content

Instantly share code, notes, and snippets.

@dsebastien
Last active June 25, 2024 12:56
Show Gist options
  • Save dsebastien/e530cb294321642d5130d7df5f6d88d1 to your computer and use it in GitHub Desktop.
Save dsebastien/e530cb294321642d5130d7df5f6d88d1 to your computer and use it in GitHub Desktop.
Obsidian Publish Templater Template

<%*

const dv = app.plugins.plugins["dataview"].api;

// ------------------------------------------------------------------ // Update notes front matter if needed // ------------------------------------------------------------------ let publishedFiles = null;

// Load the list of currently published files try { const publishedFilesWrapper = await app.internalPlugins.plugins.publish.instance.apiList(); if(publishedFilesWrapper !== null && publishedFilesWrapper.files) { publishedFiles = publishedFilesWrapper.files; } } catch(e) { console.log("Error while fetching published files list", e); return; }

const publishedFilesByPathMap = new Map(publishedFiles.map((publishedFile) => [publishedFile.path, publishedFile]));

// Load all the Markdown files of the vault const allVaultFiles = app.vault.getMarkdownFiles(); const allVaultFilesByPathMap = new Map(allVaultFiles.map((vaultFile) => { const vaultFileCache = app.metadataCache.getFileCache(vaultFile); return [vaultFile.path, { vaultFile, vaultFileCache, }]; }));

// Retrieve the Dataview serializer plugin (if available); // Reference: https://github.com/dsebastien/obsidian-dataview-serializer const dataviewSerializerPlugin = app.plugins.plugins["dataview-serializer"];

// For each file in the vault... for (const vaultFile of allVaultFiles) { if(vaultFile.deleted) { // Skip deleted files continue; }

let isAPublishedFile = false;

// Identify if it is a published file
if(publishedFilesByPathMap.has(vaultFile.path)) {
	isAPublishedFile = true;
}

// Get file details, including the front matter
const vaultFileDetails = allVaultFilesByPathMap.get(vaultFile.path);
const vaultFileFrontMatter = vaultFileDetails?.vaultFileCache?.frontmatter;

// Check if the note is currently marked as public
let markedAsPublic = false;

if(vaultFileFrontMatter && vaultFileFrontMatter.public_note) { 
  // Note is currently marked as public
  markedAsPublic = true
}

// Process the file using the Dataview serializer plugin
if(isAPublishedFile &&  dataviewSerializerPlugin) {
  await app.plugins.plugins["dataview-serializer"].processFile(vaultFile);
}

// Check if we need to update the frontmatter
if((isAPublishedFile && !markedAsPublic) || (!isAPublishedFile && markedAsPublic)){
    console.log("Updating the front matter of ", vaultFile.path);
	try {
	    let needToUpdateCreationAndModificationMetadata = false;
		// reference: https://github.com/obsidianmd/obsidian-api/blob/master/obsidian.d.ts#L1434
		const frontMatterUpdateResult = await app.fileManager.processFrontMatter(vaultFile, (frontMatter) => {
		  // NOTE: The frontMatter object is never null, so we can safely set the property on it
		  
		  if(isAPublishedFile && !markedAsPublic) {
			console.log("Adding the missing 'public_note' property");
			frontMatter.public_note = true;
			needToUpdateCreationAndModificationMetadata = true;
		  }

		  if(!isAPublishedFile && markedAsPublic) {
			console.log("Removing the 'public_note' property");
			delete frontMatter.public_note;
			needToUpdateCreationAndModificationMetadata = true;
		  }

		  // FIXME remove once plugin available to handle that
		  // once there, invoke from here (will just need to touch the file)
		  if(needToUpdateCreationAndModificationMetadata) {
			console.log("Updating creation/modification time properties");
			// ISO Dates
			if(!frontMatter.created) {
				frontMatter.created = moment(vaultFile.stat.ctime).format();
			}
			frontMatter.updated = moment(new Date()).format();
		  }
		});
	} catch(e) {
		console.warn(`Failed to update the front matter of [${vaultFile.path}]`, e);
	}
}

}

// ------------------------------------------------------------------ // Generate/update changelog and recently updated notes // ------------------------------------------------------------------ const recentlyAddedFilePath = "50 Resources/56 Obsidian Publish/Recently added"; const recentlyModifiedFilePath = "50 Resources/56 Obsidian Publish/Recently modified";

// Add as many filenames and queries as you'd like! const fileAndQuery = new Map([ [ recentlyAddedFilePath, LIST WITHOUT ID dateformat(file.cday, "yyyy-MM-dd") + ": " + file.link FROM "30 Areas" AND -#Ignore WHERE public_note = true SORT file.ctime desc LIMIT 1000, ], [ recentlyModifiedFilePath, LIST WITHOUT ID dateformat(file.mday, "yyyy-MM-dd") + " " + dateformat(file.mtime,"hh:mm") + ": " + file.link FROM "30 Areas" AND -#Ignore WHERE public_note = true SORT file.mtime desc LIMIT 25, ], ]);

await fileAndQuery.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename); new Notice(Created ${filename}.); } const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); let fileContent = %% Automatically generated by the Publish template %% \n; if(recentlyAddedFilePath === filename) { fileContent+=\n# Changelog; } fileContent+=\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); } });

// ------------------------------------------------------------------ // Open the Obsidian Publish GUI panel // ------------------------------------------------------------------ const openPublishPanel = app.commands.commands["publish:view-changes"].callback; openPublishPanel(); %>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment