' . esc_html__('File not found or access denied.', 'hi-theme-toolkit') . '
';
return;
}
echo '';
if ($is_index_request) {
// Table of contents is built on each request, never written to disk
echo wp_kses( self::generate_index($base_dir), self::index_allowed_html() );
} else {
// Doc pages are stored as HTML (content + page table of contents)
echo wp_kses_post( file_get_contents($file_path) );
}
echo '
';
// Add the bottom navigation links
$index_url = menu_page_url('toolkit-docs', false);
if ($requested_file !== 'index.html') {
echo '' . esc_html__('Back to table of contents', 'hi-theme-toolkit') . '
';
}
}
/**
* HTML allowed in the generated table of contents (sections, toggle icons, links).
*
* @return array
*/
private static function index_allowed_html() {
return [
'div' => ['id' => true, 'class' => true, 'data-section-id' => true],
'h1' => [],
'h2' => [],
'a' => ['href' => true],
'svg' => ['height' => true, 'width' => true, 'xmlns' => true, 'viewbox' => true],
'path' => ['d' => true],
];
}
/**
* Build the docs table of contents HTML.
*
* @param string $dir Docs base directory.
* @return string
*/
private static function generate_index($dir) {
$directoryIterator = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($directoryIterator, \RecursiveIteratorIterator::SELF_FIRST);
$iterator->setMaxDepth(1); // Adjust depth as needed
$entries = [];
foreach ($iterator as $file) {
if ($file->getFilename() === 'index.html') {
continue;
}
$entries[] = $file->getPathname();
}
// Sort the entries
sort($entries, SORT_NATURAL | SORT_FLAG_CASE);
$toc = "Table des matières
";
$currentDir = '';
$sectionNumber = 0;
foreach ($entries as $filePath) {
$relativePath = substr($filePath, strlen($dir));
// Check if we are in a new directory
$dirPath = dirname($relativePath);
if ($dirPath !== '.' && $dirPath !== $currentDir) {
// Close the previous section if not the first
if ($currentDir !== '') {
$toc .= "\n"; // Close the previous section div
}
// Update current directory
$currentDir = $dirPath;
// Format directory name
$dirName = str_replace(['/', '-', '_'], ' ', $dirPath);
$dirName = ucwords(strtolower($dirName));
// Remove the first number if it exists
$dirName = preg_replace('/^\d+\s*/', '', $dirName);
$sectionNumber++;
// Add the section with a toggle link
$escaped_dir_name = esc_html( $dirName );
$escaped_section_num = (int) $sectionNumber;
$toc .= "\n";
$toc .= "\n";
}
// Only process files, not directories
if (is_file($filePath)) {
$filenameWithoutExtension = pathinfo($filePath, PATHINFO_FILENAME);
$formattedName = str_replace(['-', '_'], ' ', $filenameWithoutExtension);
$formattedName = ucfirst(strtolower($formattedName));
$url = menu_page_url('toolkit-docs', false) . '&file=' . urlencode($relativePath);
$toc .= "
" . esc_html( $formattedName ) . "\n";
}
}
// Close the last section div if there was at least one file
if (!empty($entries)) {
$toc .= "
\n"; // Close the last section div
}
// Close table of contents div
$toc .= "\n";
return $toc;
}
}