↩️ Назад

Категории

tag.php — страница тегов (материалы по метке)

24.04.2026 | коды из категории: php

Вроде уже выкладывал как теги делать, еще раз продублирую для пхп блога файлик

🔐 ЗАЩИТА:
- Фильтрация slug через preg_replace()
- Проверка длины slug (2-50 символов)
- htmlspecialchars() для всего вывода
- PDO подготовленные запросы
- 404 при отсутствии тега
- Белый список популярных тегов для индексации

⚙️ ФУНКЦИИ:
- Поиск тега по slug (из URI или GET)
- Вывод статей и код-постов с этим тегом
- Сортировка по дате (новые сверху)
- Автоматическая индексация SEO для популярных тегов
- Адаптивная сетка материалов

📦 ПОДДЕРЖИВАЕМЫЕ URL:
- /tag.php/esp32
- /tag.php?slug=php

<?php
session_start(); // Добавлено для возможной админ-панели

require __DIR__ . '/includes/db.php';
include __DIR__ . '/includes/header.php';

// Получаем slug тега из разных источников
$uri = $_SERVER['REQUEST_URI'];
$tagSlug = '';

// Вариант 1: /tag.php/slug
if (preg_match('#/tag\.php/([^/\?]+)#i', $uri, $matches)) {
    $tagSlug = trim($matches[1]);
}
// Вариант 2: ?slug=value
elseif (isset($_GET['slug'])) {
    $tagSlug = trim($_GET['slug']);
}

// Проверка: slug не должен быть пустым
if (empty($tagSlug)) {
    http_response_code(400);
    die("⚠️ Укажите тег в URL, например: /tag.php/esp32");
}

// Безопасная фильтрация slug (только буквы, цифры, дефисы)
$tagSlug = preg_replace('/[^a-zA-Z0-9\-_]/', '', $tagSlug);

if (strlen($tagSlug) < 2 || strlen($tagSlug) > 50) {
    http_response_code(400);
    die("⚠️ Некорректный формат тега");
}

// Получаем тег из БД
$stmt = $pdo->prepare("SELECT id, name, slug FROM tags WHERE slug = ?");
$stmt->execute([$tagSlug]);
$tag = $stmt->fetch();

if (!$tag) {
    http_response_code(404);
    include '404.php';
    exit;
}

// Получаем статьи с этим тегом
$articles = $pdo->prepare("
    SELECT a.id, a.title, a.preview_text, a.image, a.created_at, 'article' AS post_type
    FROM articles a
    JOIN article_tags at ON a.id = at.article_id
    WHERE at.tag_id = ?
    ORDER BY a.created_at DESC
");
$articles->execute([$tag['id']]);
$articleResults = $articles->fetchAll();

// Получаем код-посты с этим тегом
$codePosts = $pdo->prepare("
    SELECT cp.id, cp.title, cp.intro AS preview_text, cp.image, cp.created_at, 'code' AS post_type
    FROM code_posts cp
    JOIN code_post_tags cpt ON cp.id = cpt.code_post_id
    WHERE cpt.tag_id = ?
    ORDER BY cp.created_at DESC
");
$codePosts->execute([$tag['id']]);
$codePostResults = $codePosts->fetchAll();

// Объединяем и сортируем по дате
$allPosts = array_merge($articleResults, $codePostResults);
usort($allPosts, function($a, $b) {
    return strtotime($b['created_at']) - strtotime($a['created_at']);
});

// SEO: индексировать только популярные теги или при наличии контента
$posts_count = count($allPosts);
$popular_tags = ['esp32', 'zigbee', 'smart-home', 'arduino', 'raspberry', 'linux', 'php'];
$should_index = in_array($tag['slug'], $popular_tags) || $posts_count >= 3;

// Мета-теги
$meta_title = htmlspecialchars($tag['name'], ENT_QUOTES, 'UTF-8');
$meta_description = "Публикации с тегом «{$tag['name']}» в блоге IoTProf. Статьи и код-посты по теме.";

?>
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <?php if ($should_index): ?>
        <meta name="robots" content="index, follow">
    <?php else: ?>
        <meta name="robots" content="noindex, follow">
    <?php endif; ?>
    
    <title>IoTProf Blog — Публикации с тегом «<?= htmlspecialchars($tag['name'], ENT_QUOTES, 'UTF-8') ?>»</title>
    <meta name="description" content="<?= htmlspecialchars($meta_description, ENT_QUOTES, 'UTF-8') ?>">
    
    <link rel="stylesheet" href="/css/style.css">
    <link rel="stylesheet" href="/css/callback.css">
</head>
<body>

<div class="container">
    <?php include 'includes/category_block.php'; ?>
    
    <h2>📜 Материалы с тегом «<?= htmlspecialchars($tag['name'], ENT_QUOTES, 'UTF-8') ?>»</h2>
    
    <?php if ($posts_count === 0): ?>
        <p>😕 Нет материалов с этим тегом.</p>
    <?php else: ?>
        <section class="posts-section">
            <div class="posts-grid">
                <?php foreach ($allPosts as $post): ?>
                    <?php
                    $isCode = ($post['post_type'] === 'code');
                    $post_id = (int)$post['id'];
                    $link = $isCode ? "/code_post.php?id={$post_id}" : "/article.php?id={$post_id}";
                    $date = date('d.m.Y', strtotime($post['created_at']));
                    $category = $isCode ? '💻 Код' : '📖 Статья';
                    ?>
                    <article class="post-card article-card">
                        <div class="post-content">
                            <?php if (!empty($post['image'])): ?>
                                <img src="/uploads/<?= htmlspecialchars($post['image'], ENT_QUOTES, 'UTF-8') ?>"
                                     alt="<?= htmlspecialchars($post['title'], ENT_QUOTES, 'UTF-8') ?>"
                                     class="post-thumb">
                            <?php endif; ?>
                            
                            <span class="date_cat_article"><?= htmlspecialchars($category, ENT_QUOTES, 'UTF-8') ?> | <?= htmlspecialchars($date, ENT_QUOTES, 'UTF-8') ?></span>
                            
                            <h3><a href="<?= htmlspecialchars($link, ENT_QUOTES, 'UTF-8') ?>"><?= htmlspecialchars($post['title'], ENT_QUOTES, 'UTF-8') ?></a></h3>
                            
                            <p><?= nl2br(htmlspecialchars($post['preview_text'], ENT_QUOTES, 'UTF-8')) ?></p>
                        </div>
                    </article>
                <?php endforeach; ?>
            </div>
        </section>
        
        <!-- Простая пагинация (опционально) -->
        <?php if ($posts_count > 10): ?>
            <div class="pagination">
                <span>Всего материалов: <?= $posts_count ?></span>
            </div>
        <?php endif; ?>
    <?php endif; ?>
</div>

<?php include 'includes/callpack.php'; ?>
<?php include 'includes/footer.php'; ?>
</body>
</html>
Теги: #php #tag #метки



Категории:

Категории

Комментарии

Пока нет комментариев. Будьте первым!

Оставить комментарий

← Назад к списку

Посетителей сегодня: 0
о блоге | карта блога

© Digital Specialist | Не являемся сотрудниками Google, Яндекса и NASA