+
+
+
+
+ {category}
+
+
{postTitle}
+
-
-
-
- {date}
-
-
-
- {author}
-
-
-
- {readTime}
-
-
-
+
+
+
+
+ {date}
+
+
+
+ {author}
+
+
+
+ {readTime}
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
\ No newline at end of file
diff --git a/frontend/src/pages/blog/[slug].astro b/frontend/src/pages/blog/[slug].astro
index 7e78476..a9c025f 100644
--- a/frontend/src/pages/blog/[slug].astro
+++ b/frontend/src/pages/blog/[slug].astro
@@ -3,6 +3,7 @@ import ArticleLayout from '@layouts/ArticleLayout.astro';
import { SITE_URL } from '@constants';
import PostCommentForm from '@components/blog/PostCommentForm.astro';
import RelatedPosts from '@components/blog/RelatedPosts.astro';
+import ArticleTableOfContents from '@components/blog/ArticleTableOfContents.astro';
import { getCollection, getEntry, render } from 'astro:content';
export const prerender = false;
@@ -28,6 +29,24 @@ if (!post) {
const { Content } = await render(post);
+// Извлекаем заголовки из MDX тела для оглавления
+const body = post.body || '';
+const headingRegex = /^(#{2,3})\s+(.+)$/gm;
+const tocItems: { id: string; text: string; level: number }[] = [];
+let match;
+let headingIndex = 0;
+while ((match = headingRegex.exec(body)) !== null) {
+ const level = match[1].length;
+ const text = match[2].trim();
+ // Генерируем ID из текста заголовка
+ const id = text.toLowerCase()
+ .replace(/[^\w\s-]/g, '')
+ .replace(/\s+/g, '-');
+ tocItems.push({ level, id: `heading-${headingIndex++}`, text });
+}
+
+console.log('=== TOC ITEMS ===', tocItems);
+
// Форматируем дату
const formatDate = (date: Date) => {
return date.toLocaleDateString('ru-RU', {
@@ -74,7 +93,7 @@ const allPosts = await getCollection('blog');
@@ -84,16 +103,17 @@ const allPosts = await getCollection('blog');
posts={allPosts}
currentSlug={post.id}
/>
+
+
+