From 5938b8c9c9123ad5e22eb705cb10a787012e1a01 Mon Sep 17 00:00:00 2001 From: Shelby Tucker Date: Mon, 2 Jun 2025 21:14:47 -0400 Subject: [PATCH 1/2] support zettelkasten filenames --- docker-compose-build.yml | 1 + docker-compose-dev.yml | 1 + docker-compose.yml | 1 + perlite/helper.php | 98 ++++++++++++++++++++++++++++------------ 4 files changed, 73 insertions(+), 28 deletions(-) diff --git a/docker-compose-build.yml b/docker-compose-build.yml index ef89ac68..48a7ebd9 100644 --- a/docker-compose-build.yml +++ b/docker-compose-build.yml @@ -5,6 +5,7 @@ services: environment: - NOTES_PATH=Demo - HIDE_FOLDERS=docs,private,trash + - ZETTELKASTEN_FILENAMES_ENABLED=false - HIDDEN_FILE_ACCESS=false - LINE_BREAKS=true - ABSOLUTE_PATHS=false diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml index 491c285a..97b6f3cb 100644 --- a/docker-compose-dev.yml +++ b/docker-compose-dev.yml @@ -6,6 +6,7 @@ services: environment: - NOTES_PATH=Demo - HIDE_FOLDERS=docs,private,trash + - ZETTELKASTEN_FILENAMES_ENABLED=false - HIDDEN_FILE_ACCESS=false - LINE_BREAKS=true - ABSOLUTE_PATHS=false diff --git a/docker-compose.yml b/docker-compose.yml index 4a968e29..c54a67a7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,6 +6,7 @@ services: environment: - NOTES_PATH=Demo - HIDE_FOLDERS=docs,private,trash + - ZETTELKASTEN_FILENAMES_ENABLED=false - HIDDEN_FILE_ACCESS=false - LINE_BREAKS=true - ABSOLUTE_PATHS=false diff --git a/perlite/helper.php b/perlite/helper.php index 170091d1..a9c921c9 100644 --- a/perlite/helper.php +++ b/perlite/helper.php @@ -65,6 +65,11 @@ if (!isset($siteTwitter)) $siteTwitter = getenv('SITE_TWITTER'); +// Use frontmatter 'title' or top level h1 instead of filename +if (!isset($useZettelkastenFilenames)) { + $useZettelkastenFilenames = empty(getenv('ZETTELKASTEN_FILENAMES_ENABLED')) ? false : filter_var(getenv('ZETTELKASTEN_FILENAMES_ENABLED'), FILTER_VALIDATE_BOOLEAN); +} + // Temp PATH for graph linking temp files if (empty($tempPath)) $tempPath = empty(getenv('TEMP_PATH')) ? sys_get_temp_dir() : getenv('TEMP_PATH'); @@ -190,6 +195,7 @@ function menu($dir, $folder = '') global $hiddenFileAccess; global $avFiles; + global $useZettelkastenFilenames; $html = ''; // get all files from current dir $files = glob($dir . '/*'); @@ -232,34 +238,39 @@ function menu($dir, $folder = '') } } - // iterate the files - foreach ($files as $file) { - if (isMDFile($file)) { - - $path = getFileInfos($file)[0]; - $mdFile = getFileInfos($file)[1]; - - $path = '/' . $path; - // push the the path to the array - array_push($avFiles, $path); - - // URL Encode the Path for the JS call - $pathClean = rawurlencode($path); - $pathID = str_replace(' ', '_', $path); - $pathID = preg_replace('/[^A-Za-z0-9\-]/', '_', $path); - - - $html .= ' - - '; - } - } - - return $html; + // Iterate the files + foreach ($files as $file) { + if (isMDFile($file)) { + $pathInfo = getFileInfos($file); + $relativePathForURL = $pathInfo[0]; + $baseFilenameWithoutExtension = $pathInfo[1]; + + $displayTitle = ""; + + if ($useZettelkastenFilenames) { + $displayTitle = getDisplayTitle($file); + } else { + $displayTitle = $baseFilenameWithoutExtension; + } + + $urlClickPath = '/' . $relativePathForURL; + array_push($avFiles, $urlClickPath); + $pathCleanForJS = rawurlencode($urlClickPath); + + // Create a unique ID for the HTML element + $elementId = 'fileid-' . preg_replace('/[^A-Za-z0-9\-_]/', '_', $urlClickPath); + $elementId = str_replace('/', '_', $elementId); // Replace slashes for cleaner ID + + $html .= ' + + '; + } + } + return $html; } function doSearch($dir, $searchfor) @@ -448,6 +459,37 @@ function isCached($jsonMetadaFile, $metadaTempFileSum) return false; } +function getDisplayTitle($filePath) { + $content = @file_get_contents($filePath); + if ($content === false) { + // Fallback to filename if file can't be read + return getFileInfos($filePath)[1]; + } + + // 1. Try to get title from frontmatter + if (preg_match('/^---\s*\n(.*?)\n---\s*\n/s', $content, $frontmatterMatches)) { + $frontmatterRaw = $frontmatterMatches[1]; + if (preg_match('/^title:\s*(.*?)\s*$/im', $frontmatterRaw, $titleMatches)) { + $title = trim($titleMatches[1]); + $title = trim($title, "'\""); + if (!empty($title)) { + return $title; + } + } + } + + // 2. Try to get the first H1 heading + if (preg_match('/^#\s+(.*?)\s*$/m', $content, $h1Matches)) { + $h1Title = trim($h1Matches[1]); + if (!empty($h1Title)) { + return $h1Title; + } + } + + // 3. Fallback to filename (obtained via getFileInfos) + return getFileInfos($filePath)[1]; +} + function getfullGraph($rootDir) { From 0d4c2ff5e8c0b145ca97e2665f0fee8981ef90c9 Mon Sep 17 00:00:00 2001 From: sec77 <31564517+secure-77@users.noreply.github.com> Date: Wed, 5 Nov 2025 22:57:32 +0100 Subject: [PATCH 2/2] added support to open the nav tree and mark the entry as active --- perlite/.js/perlite.js | 13 +++++-------- perlite/settings.php | 1 + 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/perlite/.js/perlite.js b/perlite/.js/perlite.js index 226c8b23..6d5d2feb 100644 --- a/perlite/.js/perlite.js +++ b/perlite/.js/perlite.js @@ -1052,10 +1052,11 @@ function openNavMenu(target, openAll = false) { // open nav menu to target var navId = decodeURIComponent(target); - linkname = navId.match(/([^\/]*)\/*$/)[1] - + // search and open tree reverse navId = navId.replace(/[^a-zA-Z0-9\-]/g, '_'); + + navId = 'fileid-' + navId; var next = $('#' + navId).parent().closest('.collapse'); do { @@ -1067,13 +1068,9 @@ function openNavMenu(target, openAll = false) { } while (next.length != 0); + // mark active + $('#' + navId).addClass('perlite-link-active is-active'); - // set focus to link - var searchText = linkname; - - $("div").filter(function () { - return $(this).text() === searchText; - }).parent().addClass('perlite-link-active is-active'); }; diff --git a/perlite/settings.php b/perlite/settings.php index b1c83012..27416c49 100644 --- a/perlite/settings.php +++ b/perlite/settings.php @@ -22,6 +22,7 @@ $siteHomepage = ""; // empty for $siteURL $siteGithub = "https://github.com/secure-77"; // empty for no Github $siteTwitter = "@secure_sec77"; +$useZettelkastenFilenames = false; $tempPath = ""; // blanc so it gets it automatically