add tags
This commit is contained in:
109
src/pages/[category]/[...slug].astro
Normal file
109
src/pages/[category]/[...slug].astro
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
|
||||
import { getProfileArticleById } from '@api/posts.js';
|
||||
|
||||
import MainLayout from '@layouts/MainLayout.astro';
|
||||
|
||||
export const prerender = false; // динамический роутинг
|
||||
const { category, slug } = Astro.params;
|
||||
|
||||
// ищем ID поста
|
||||
function findPostId(slug) {
|
||||
|
||||
const lastItem = Array.isArray(slug) ? slug[slug.length - 1] : slug;
|
||||
|
||||
// Находим последний дефис
|
||||
const dashIndex = lastItem.lastIndexOf('-');
|
||||
if (dashIndex === -1) return null;
|
||||
|
||||
// Берем всё после дефиса
|
||||
const idStr = lastItem.substring(dashIndex + 1);
|
||||
|
||||
// Преобразуем в число
|
||||
const id = Number(idStr);
|
||||
return Number.isInteger(id) ? id : null;
|
||||
}
|
||||
|
||||
const postId = findPostId(slug);
|
||||
|
||||
let article;
|
||||
|
||||
try {
|
||||
article = await getProfileArticleById(postId);
|
||||
} catch (error) {
|
||||
return Astro.redirect('/404');
|
||||
}
|
||||
|
||||
if (!article) {
|
||||
return Astro.redirect('/404');
|
||||
}
|
||||
|
||||
// Валидация: проверяем категорию
|
||||
const articleCategory = article.categories?.nodes?.[0]?.slug;
|
||||
|
||||
|
||||
// Если категория не совпадает, делаем редирект
|
||||
if (articleCategory && category !== articleCategory) {
|
||||
debugLog(`Редирект: категория не совпадает (${category} != ${articleCategory})`);
|
||||
|
||||
// Строим правильный URL
|
||||
const correctUri = article.uri
|
||||
.replace(/^\//, '')
|
||||
.replace(/\/$/, '');
|
||||
|
||||
return Astro.redirect(`/${correctUri}/`, 301);
|
||||
}
|
||||
|
||||
// Валидация: проверяем полный путь
|
||||
const currentPath = `${category}/${Array.isArray(slug) ? slug.join('/') : slug}`;
|
||||
const correctPath = article.uri
|
||||
.replace(/^\//, '')
|
||||
.replace(/\/$/, '');
|
||||
|
||||
if (currentPath !== correctPath) {
|
||||
debugLog(`Редирект: путь не совпадает (${currentPath} != ${correctPath})`);
|
||||
return Astro.redirect(`/${correctPath}/`, 301);
|
||||
}
|
||||
|
||||
---
|
||||
|
||||
|
||||
<MainLayout
|
||||
title={article.title}
|
||||
description="Информационное агентство Деловой журнал Профиль"
|
||||
>
|
||||
|
||||
<h1 class="article-title">{article.title}</h1>
|
||||
|
||||
{article.tags?.nodes?.length > 0 && (
|
||||
<div class="tags-list">
|
||||
<strong>Метки:</strong>
|
||||
{article.tags.nodes.map(tag => (
|
||||
<a href={tag.uri} class="tag" key={tag.id}>{tag.name}</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{article.featuredImage?.node?.sourceUrl && (
|
||||
<figure class="featured-image">
|
||||
<img
|
||||
src={article.featuredImage.node.sourceUrl}
|
||||
alt={article.featuredImage.node.altText || article.title}
|
||||
loading="eager"
|
||||
class="article-image"
|
||||
/>
|
||||
{article.featuredImage.node.caption && (
|
||||
<figcaption class="image-caption" set:html={article.featuredImage.node.caption} />
|
||||
)}
|
||||
</figure>
|
||||
)}
|
||||
|
||||
<div class="article-content" set:html={article.content} />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</MainLayout>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user