prepare("SELECT p.*, c.name AS category_name, c.slug AS category_slug FROM blog_posts p LEFT JOIN blog_categories c ON p.category_id = c.id WHERE p.slug = :slug AND p.status = 'published' LIMIT 1"); $stmt->execute([':slug' => $slug]); $post = $stmt->fetch(); if (!$post) { http_response_code(404); $pageTitle = 'Artículo no encontrado - Blog TRIMAPE'; $notFound = true; } else { $notFound = false; $pageTitle = e($post['title']) . ' - Blog TRIMAPE'; $pageDesc = $post['excerpt'] ? e($post['excerpt']) : e(truncate($post['content'], 160)); $coverImage = $post['cover_image'] ?: SITE_URL . '/assets/img/trimape-1200.webp'; // Related posts (same category, excluding current) $relatedStmt = $db->prepare("SELECT p.*, c.name AS category_name, c.slug AS category_slug FROM blog_posts p LEFT JOIN blog_categories c ON p.category_id = c.id WHERE p.status = 'published' AND p.id != :id AND p.category_id = :catid ORDER BY p.published_at DESC LIMIT 3"); $relatedStmt->execute([':id' => $post['id'], ':catid' => $post['category_id']]); $related = $relatedStmt->fetchAll(); // If not enough related from same category, fill with recent if (count($related) < 3) { $excludeIds = array_merge([$post['id']], array_column($related, 'id')); $placeholders = implode(',', array_fill(0, count($excludeIds), '?')); $fillStmt = $db->prepare("SELECT p.*, c.name AS category_name, c.slug AS category_slug FROM blog_posts p LEFT JOIN blog_categories c ON p.category_id = c.id WHERE p.status = 'published' AND p.id NOT IN ($placeholders) ORDER BY p.published_at DESC LIMIT " . (3 - count($related))); $fillStmt->execute($excludeIds); $related = array_merge($related, $fillStmt->fetchAll()); } } ?> <?= $pageTitle ?>

404

El artículo que buscas no existe o fue eliminado.

Volver al blog
<?= e($post['title']) ?>

Publicado el
← Volver al blog

Artículos relacionados

<?= e($rel['title']) ?>
TRIMAPE