Hierarchical list of files with the dataview plugin

I’m trying to get a hierarchical list of files inside a folder with the dataview plugin, such that the output would be something like the following:

- folder_A: fileA1 fileA2 fileA3 ...
    - subfolder_AA fileAA1 ...
    - subfolder_AB fileAB1 ...
- folder_B: fileB1 fileB2 fileB3 ...
    - subfolder_BA fileBA1 ...
    - subfolder_BB fileBB1 ...

and so on, where the filenames would be clickable (i.e., links). I’ve played quite a bit with the plugin but haven’t reached anything close to what I’m looking for. Is that possible? If not, what would be the closest thing achievable using dataview?

2 Likes

I somewhat managed to get this working using dataviewjs.

Edit: I have made some more improvements and fixed a bug where the folders where not in the correct hierarchy:

let title = "Files";
let dir = 'Root/Directory/In/Your/Vault';

let processed = [];

function listRecursive(folder, depth) {
	let files = [];
	
	// All pages in the scope of the current path
	let pages = dv.pages('"' + folder + '"')
	
	// Collect files in the current folder here
	let currentFiles = "";
	
	pages.forEach(page => {
		if (page.file.folder === folder) {
			// Page is in current folder
			currentFiles += page.file.link + " | ";
		}
		else {
			// Page is in subfolder
			let nestedFolder = page.file.folder;
			
			// Make sure nested folder is direct child, not any other descendant from current folder
			let isChild = folder.split('/').length + 1 == nestedFolder.split('/').length;
			
			// Make sure we dont process sub-directories multiple times
			if (!processed.includes(nestedFolder) && isChild) {
				processed.push(nestedFolder);
				
				// Result of recursive call is a list, by adding it to the current list we recursively build a tree
				files.push(listRecursive(nestedFolder, depth + 1));
			}
		}
	});
	
	if (currentFiles.endsWith(" | "))
		currentFiles = currentFiles.slice(0, -3);
	
	// Add files in current folder at the start
	if (currentFiles !== "") files.unshift(currentFiles);
	
	// Add current folder name at the start
	let path = folder.split('/');
	path = path [path.length - 1];
	
	if (depth == 0) path = path;
	
	files.unshift("<h3>" + path + "</h3>");
	
	return files;
}

let files = listRecursive(dir, 0);

dv.header(3, title);
dv.list(files);

The formatting of the output isn’t great, but it’s something. Maybe someone has better Knowledge how to properly format this. But the functionality is there.

3 Likes

wow, thank you @jonas.franz !

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.