' . 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 .= "

{$escaped_dir_name}

\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; } }