How to redirect to note when clicking on folder in Publish

My goal was to have a note for each top-level folder on my publish site that a user would be sent to when the folder name was clicked. With this method I used below, a user can still use the arrow to expand/contract the folder normally. Also, the note is hidden from the nav to reduce clutter.

publish

How I did it:

  1. I made notes for each folder with the same name as the folder
  2. I hid the notes with css (publish.css)
.tree-item-self[data-path^='Concepts/Concepts'] {
  display: none;
}

.tree-item-self[data-path^='FAQ/FAQ'] {
  display: none;
}

.tree-item-self[data-path^='Guides/Guides'] {
  display: none;
}

.tree-item-self[data-path^='Tools/Tools'] {
  display: none;
}

.tree-item-self[data-path^='Tutorials/Tutorials'] {
  display: none;
}
  1. I added an attribute that contains the redirect link to the folder name in the nav for each folder
  2. Added an event listener to redirect to the link in the attribute
const site = "https://dataengineering.wiki";
var navContainer = siteNav.querySelector('.tree-item').querySelector('.tree-item-children');

// Each folder contains a note with the same name as the folder, add a redirect to the note when the folder is clicked.
// Expand arrow should not be affected.
let folders = ["Concepts", "FAQ", "Guides", "Tools", "Tutorials"];
for (const item of folders) {

    var element = navContainer.querySelector(`[data-path="${item}"] div.tree-item-inner`);
    element.setAttribute('data-link', `${site}/${item}/${item}`);
    element.addEventListener('click', function(e) {
        window.location.href = e.target.getAttribute('data-link');
        return false;
    });
};

I tried various methods of achieving this like removing the div and surrounding a span tag with an a tag but this was by far the simplest and most reliable.

See full code here:

1 Like

often the name index.html is auto loaded if it’s found.
i’ve noticed the same happens when i make a website from my obsidian notes.
so we can take advantage of this by creating a note named index.md in every folder.
and this will auto load when i click on the folder in the sidebar.

Do you mind sharing what steps you took? I just tried adding an index.md file in a folder and publishing it but clicking on the folder name didn’t take me to the index.md file.

ah i use mkdocs to make my wiki instead of Obsidian publish.
so default HTML rules apply. e.g. index will be default page.

Hey, thank you for share! There is a way to do the same for second level folders?

I use the Folder notes plugin and missed this feature with Obsidian Publish.

Here is my attempt at a general solution, it should work similarly to the ‘Folder notes’ plugin, that is, if the directory contains a markdown file of the same name, it will hide the markdown file and allow the user to open it through clicking on the top level item.

function folderPages() {
    var siteLeft = document.querySelector('.site-body-left-column');
    var siteNav = siteLeft.querySelector('.nav-view-outer');
    var navContainer = siteNav.querySelector('.tree-item').querySelector('.tree-item-children');
    var navItems = navContainer.querySelectorAll(`.is-clickable:not([data-path$=".md"])`);

    for(const item of navItems) {
        var dataPath = item.getAttribute('data-path');
        var [x, y] = dataPath.split('/').slice(-2);
        if(y) {
            var path = `${dataPath}/${y}`;
            var pathMd = `${path}.md`;
            if(app.site.cache.cache[pathMd]) {
                var linkContainer = item.querySelector('div.tree-item-inner');
                var children = item.parentElement.querySelector('.tree-item-children');
                var leafNode = children ? children.querySelector(`a[data-path="${pathMd}"]`) : null;
                if(leafNode) {
                    linkContainer.replaceWith(leafNode);
                } else if(!item.querySelector('a')) {
                    link = document.createElement('a');
                    link.setAttribute('data-path', pathMd);
                    link.setAttribute('href', path);
                    link.classList.add('tree-item-self');
                    link.classList.add('is-clickable');
                    link.innerText=y;
                    linkContainer.innerHTML='';
                    linkContainer.appendChild(link);
                }
            }
        }
    }
}

const observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
        if (mutation.addedNodes.length > 0) {
            folderPages();
        }
    });
});

observer.observe(document.body, {
    childList: true,
    subtree: true
});

folderPages();
1 Like