up:: ๐งช Code Diary
type:: #log/code
language:: JavaScript
program:: Obsidian, Plugin - Templater
topics:: Coding
Generate MOC from files in a folder using Templater
Language:: JavaScript
Program:: Obsidian
Summary
Ask user to select folder to generate MOC for all files in this folder, all files in subfolders will be included
Code
Is it possible to get a bulleted list of all the files included in a specific folder in this format ?
[[name of file 1]]
[[name of file 2]]
<%*
// ask user to select folder to generate MOC for all files in this folder
// all files in subfolders will be included
const folders = this.app.vault.getAllLoadedFiles().filter(i => i.children).map(folder => folder.path);
const folderChoicePath = await tp.system.suggester(folders, folders);
if (folderChoicePath != null) {
new Notice(`Folder selected: ${folderChoicePath}`, 5000);
const files = app.vault.getMarkdownFiles();
const filesInFolder = new Array();
console.log("folderChoicePath: " + `${folderChoicePath}`)
files.forEach((file) => {
//console.log("file.path: " + `${file.path}`)
if (file.path.includes(folderChoicePath)) {
filesInFolder.push(file.basename)
};
})
const filesList = new Array();
filesInFolder.forEach((file) => {
//console.log(file)
filesList.push('\n - [[' + file + ']]')
});
const folderChoice = folderChoicePath.split("/").slice(-1)
const fileName = folderChoice + " MOC"
//files sorted case insensitive
const content = "## " + folderChoice + " MOC " + "\n" + filesList.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).join('')
// create new file with a list of files in folder
const tFolder = app.vault.getAbstractFileByPath(folderChoicePath)
// if file exist, do not create file
if (await app.vault.exists(`${folderChoicePath}/${fileName}.md`)) {
new Notice(`Unable to create. File already exists: ${folderChoicePath}/${fileName}.md`, 5000)
} else {
await tp.file.create_new(content, fileName, true, tFolder)
new Notice(`Created new MOC: ${folderChoicePath}/${fileName}.md`, 5000);
}
} else {
new Notice(`No folder selected`, 5000);
}
_%>
Hi, thank you for your response. Is there a way to get the list in the active file without creating a new file, and to replace something in the code so that it always checks the same folder.
// Check the folder specified below and build a list of all markdown files
// all files in subfolders will be included
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// MacOS example, Modify folderChoicePath
folderChoicePath = "resources/health/"
// If you are on Windows, try: "resources\health\"
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
if (folderChoicePath != null) {
new Notice(`Folder: ${folderChoicePath}`, 5000);
let filesInFolder = new Array();
console.log("folderChoicePath: " + `${folderChoicePath}`)
filesInFolder = app.vault.getMarkdownFiles().filter(file => file.path.includes(folderChoicePath)).map(tFile=>tFile.basename)
const filesList = new Array();
filesInFolder.forEach((file) => {
filesList.push('\n - [[' + file + ']]')
});
const folderChoice = folderChoicePath.split("/").slice(-2).join("")
const fileName = folderChoice + " MOC"
//files sorted case insensitive
const heading = "## " + folderChoice.charAt(0).toUpperCase() + folderChoice.slice(1)+ " MOC"
const content = heading + "\n" + filesList.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).join('')
// insert the list of files in the active file
tR+=content
new Notice(`Created new MOC`, 5000);
} else {
new Notice(`No folder selected`, 5000);
}
_%>
Thank you, this helped me immensely. I modified this slightly to generate a table rather than a list. The table has 3 columns.
- the file link
- a description column (to be filled in)
- links to generated headers for more detailed descriptions of the files.
The level 2 headers using the file name are automatically generated after the table.
Here is my modifications for anyone needing this...
<%*
// Check the folder specified below and build a list of all markdown files
// all files in subfolders will be included
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// MacOS example
folderChoicePath = "Templates/"
// If you are on Windows, try: "resources\health\"
// Note: "/" works fine under Windows 10
// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
if (folderChoicePath != null) {
new Notice(`Folder: ${folderChoicePath}`, 5000);
let filesInFolder = new Array();
let headings = new Array();
console.log("folderChoicePath: " + `${folderChoicePath}`)
filesInFolder = app.vault.getMarkdownFiles().filter(file => file.path.includes(folderChoicePath)).map(tFile=>tFile.basename)
const filesList = new Array();
filesList.push('\n| Template | Description | Detailed Notes |\n| -------- | ----------- | -------------- |')
filesInFolder.forEach((file) => {
filesList.push('\n| - |')
headings.push('\n## ' + file + '\n')
});
const folderChoice = folderChoicePath.split("/").slice(-2).join("")
const fileName = folderChoice + " MOC"
//files sorted case insensitive
const heading = "## " + folderChoice.charAt(0).toUpperCase() + folderChoice.slice(1)+ " MOC"
let content = heading + "\n" + filesList.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).join('')
content = content + "\n" + headings.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase())).join('')
// insert the list of files in the active file
tR+=content
new Notice(`Created new MOC`, 5000);
} else {
new Notice(`No folder selected`, 5000);
}
_%>
Explanation
Result
up:: ๐งช Code Diary