Release v1.5.1
This commit is contained in:
@@ -1,61 +1,171 @@
|
||||
<?php
|
||||
$pageTitle = $title ?? 'News';
|
||||
$posts = $posts ?? [];
|
||||
$page = $page ?? null;
|
||||
$posts = is_array($posts ?? null) ? $posts : [];
|
||||
$page = is_array($page ?? null) ? $page : null;
|
||||
$pageContentHtml = trim((string)($page['content_html'] ?? ''));
|
||||
|
||||
$formatDate = static function (?string $value): string {
|
||||
if ($value === null || trim($value) === '') {
|
||||
return '';
|
||||
}
|
||||
try {
|
||||
return (new DateTime($value))->format('d M Y');
|
||||
} catch (Throwable $e) {
|
||||
return $value;
|
||||
}
|
||||
};
|
||||
|
||||
$renderTags = static function (string $tags): array {
|
||||
return array_values(array_filter(array_map('trim', explode(',', $tags))));
|
||||
};
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<section class="card">
|
||||
<div class="badge">News</div>
|
||||
<?php if ($page && !empty($page['content_html'])): ?>
|
||||
<div style="margin-top:12px; color:var(--muted); line-height:1.7;">
|
||||
<?= (string)$page['content_html'] ?>
|
||||
<section class="card news-list-shell-minimal">
|
||||
<?php if ($pageContentHtml !== ''): ?>
|
||||
<div class="blog-page-content-box">
|
||||
<?= $pageContentHtml ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<h1 style="margin-top:12px; font-size:30px;">Latest Updates</h1>
|
||||
<p style="color:var(--muted); margin-top:8px;">News, updates, and announcements.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div style="margin-top:18px; display:grid; gap:12px;">
|
||||
<?php if (!$posts): ?>
|
||||
<div style="color:var(--muted);">No posts yet.</div>
|
||||
<?php else: ?>
|
||||
<?php if ($posts): ?>
|
||||
<div class="news-list-grid-minimal">
|
||||
<?php foreach ($posts as $post): ?>
|
||||
<article style="padding:14px 16px; border-radius:16px; border:1px solid rgba(255,255,255,0.12); background: rgba(0,0,0,0.25);">
|
||||
<div style="font-size:11px; text-transform:uppercase; letter-spacing:0.28em; color:var(--muted);">Post</div>
|
||||
<h2 style="margin:8px 0 6px; font-size:22px;"><?= htmlspecialchars((string)($post['title'] ?? ''), ENT_QUOTES, 'UTF-8') ?></h2>
|
||||
<a class="news-card-minimal" href="/news/<?= htmlspecialchars((string)$post['slug'], ENT_QUOTES, 'UTF-8') ?>">
|
||||
<?php if (!empty($post['featured_image_url'])): ?>
|
||||
<img src="<?= htmlspecialchars((string)$post['featured_image_url'], ENT_QUOTES, 'UTF-8') ?>" alt="" style="width:100%; border-radius:12px; margin:10px 0;">
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($post['published_at'])): ?>
|
||||
<div style="font-size:12px; color:var(--muted); margin-bottom:8px;"><?= htmlspecialchars((string)$post['published_at'], ENT_QUOTES, 'UTF-8') ?></div>
|
||||
<?php endif; ?>
|
||||
<div style="font-size:12px; color:var(--muted); margin-bottom:8px;">
|
||||
<?php if (!empty($post['author_name'])): ?>
|
||||
<?= htmlspecialchars((string)$post['author_name'], ENT_QUOTES, 'UTF-8') ?>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($post['category'])): ?>
|
||||
<?php if (!empty($post['author_name'])): ?> · <?php endif; ?>
|
||||
<?= htmlspecialchars((string)$post['category'], ENT_QUOTES, 'UTF-8') ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<p style="color:var(--muted); line-height:1.6;">
|
||||
<?= htmlspecialchars((string)($post['excerpt'] ?? ''), ENT_QUOTES, 'UTF-8') ?>
|
||||
</p>
|
||||
<?php if (!empty($post['tags'])): ?>
|
||||
<div style="margin-top:8px; display:flex; flex-wrap:wrap; gap:6px;">
|
||||
<?php foreach (array_filter(array_map('trim', explode(',', (string)$post['tags'] ?? ''))) as $tag): ?>
|
||||
<span style="font-size:11px; color:#c8ccd8; border:1px solid rgba(255,255,255,0.15); padding:4px 8px; border-radius:999px;">
|
||||
<?= htmlspecialchars((string)$tag, ENT_QUOTES, 'UTF-8') ?>
|
||||
</span>
|
||||
<?php endforeach; ?>
|
||||
<div class="news-card-media-minimal">
|
||||
<img src="<?= htmlspecialchars((string)$post['featured_image_url'], ENT_QUOTES, 'UTF-8') ?>" alt="">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<a href="/news/<?= htmlspecialchars((string)($post['slug'] ?? ''), ENT_QUOTES, 'UTF-8') ?>" style="display:inline-flex; margin-top:10px; font-size:12px; text-transform:uppercase; letter-spacing:0.2em; color:#9ad4ff;">Read more</a>
|
||||
</article>
|
||||
<div class="news-card-copy-minimal">
|
||||
<div class="news-card-meta-minimal">
|
||||
<?php $published = $formatDate((string)($post['published_at'] ?? '')); ?>
|
||||
<?php if ($published !== ''): ?><span><?= htmlspecialchars($published, ENT_QUOTES, 'UTF-8') ?></span><?php endif; ?>
|
||||
<?php if (!empty($post['author_name'])): ?><span><?= htmlspecialchars((string)$post['author_name'], ENT_QUOTES, 'UTF-8') ?></span><?php endif; ?>
|
||||
</div>
|
||||
<h2><?= htmlspecialchars((string)$post['title'], ENT_QUOTES, 'UTF-8') ?></h2>
|
||||
<?php if (!empty($post['excerpt'])): ?>
|
||||
<p><?= htmlspecialchars((string)$post['excerpt'], ENT_QUOTES, 'UTF-8') ?></p>
|
||||
<?php endif; ?>
|
||||
<?php $tags = $renderTags((string)($post['tags'] ?? '')); ?>
|
||||
<?php if ($tags): ?>
|
||||
<div class="news-card-tags-minimal">
|
||||
<?php foreach (array_slice($tags, 0, 3) as $tag): ?>
|
||||
<span><?= htmlspecialchars($tag, ENT_QUOTES, 'UTF-8') ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php elseif ($pageContentHtml === ''): ?>
|
||||
<div class="news-empty-minimal">No published posts yet.</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.news-list-shell-minimal { display: grid; gap: 18px; }
|
||||
.blog-page-content-box {
|
||||
border-radius: 22px;
|
||||
border: 1px solid rgba(255,255,255,.1);
|
||||
background: rgba(12,15,21,.84);
|
||||
padding: 28px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.blog-page-content-box img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
.news-list-grid-minimal {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
.news-card-minimal {
|
||||
display: grid;
|
||||
grid-template-columns: 180px minmax(0, 1fr);
|
||||
gap: 0;
|
||||
min-height: 180px;
|
||||
border-radius: 22px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255,255,255,.1);
|
||||
background: rgba(12,15,21,.84);
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
|
||||
}
|
||||
.news-card-minimal:hover {
|
||||
transform: translateY(-2px);
|
||||
border-color: rgba(34,242,165,.34);
|
||||
box-shadow: 0 18px 32px rgba(0,0,0,.2);
|
||||
}
|
||||
.news-card-media-minimal { background: rgba(255,255,255,.03); }
|
||||
.news-card-media-minimal img {
|
||||
width: 100%; height: 100%; object-fit: cover; display: block;
|
||||
}
|
||||
.news-card-copy-minimal {
|
||||
display: grid;
|
||||
align-content: start;
|
||||
gap: 12px;
|
||||
padding: 20px;
|
||||
}
|
||||
.news-card-meta-minimal {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
color: rgba(255,255,255,.58);
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
letter-spacing: .16em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.news-card-copy-minimal h2 {
|
||||
margin: 0;
|
||||
font-size: 34px;
|
||||
line-height: .96;
|
||||
}
|
||||
.news-card-copy-minimal p {
|
||||
margin: 0;
|
||||
color: #c4cede;
|
||||
line-height: 1.65;
|
||||
font-size: 15px;
|
||||
}
|
||||
.news-card-tags-minimal {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.news-card-tags-minimal span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 6px 10px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(255,255,255,.12);
|
||||
background: rgba(255,255,255,.04);
|
||||
color: #dce5f6;
|
||||
font-size: 11px;
|
||||
}
|
||||
.news-empty-minimal {
|
||||
border-radius: 18px;
|
||||
border: 1px dashed rgba(255,255,255,.16);
|
||||
padding: 24px;
|
||||
color: #afb8ca;
|
||||
background: rgba(255,255,255,.02);
|
||||
}
|
||||
@media (max-width: 980px) {
|
||||
.news-list-grid-minimal { grid-template-columns: 1fr; }
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
.blog-page-content-box { padding: 20px; }
|
||||
.news-card-minimal {
|
||||
grid-template-columns: 1fr;
|
||||
min-height: 0;
|
||||
}
|
||||
.news-card-media-minimal { min-height: 220px; }
|
||||
.news-card-copy-minimal h2 { font-size: 28px; }
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
require __DIR__ . '/../../../views/site/layout.php';
|
||||
require __DIR__ . '/../../../../views/site/layout.php';
|
||||
@@ -1,47 +1,257 @@
|
||||
<?php
|
||||
$pageTitle = $title ?? 'Post';
|
||||
$contentHtml = $content_html ?? '';
|
||||
$publishedAt = $published_at ?? '';
|
||||
$featuredImage = $featured_image_url ?? '';
|
||||
$authorName = $author_name ?? '';
|
||||
$category = $category ?? '';
|
||||
$tags = $tags ?? '';
|
||||
ob_start();
|
||||
?>
|
||||
<section class="card">
|
||||
<div class="badge">News</div>
|
||||
<h1 style="margin-top:12px; font-size:30px;"><?= htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8') ?></h1>
|
||||
<?php if ($publishedAt !== '' || $authorName !== '' || $category !== ''): ?>
|
||||
<div style="font-size:12px; color:var(--muted); margin-top:6px;">
|
||||
<?php if ($publishedAt !== ''): ?>
|
||||
<?= htmlspecialchars($publishedAt, ENT_QUOTES, 'UTF-8') ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($authorName !== ''): ?>
|
||||
<?php if ($publishedAt !== ''): ?> · <?php endif; ?>
|
||||
<?= htmlspecialchars($authorName, ENT_QUOTES, 'UTF-8') ?>
|
||||
<?php endif; ?>
|
||||
<?php if ($category !== ''): ?>
|
||||
<?php if ($publishedAt !== '' || $authorName !== ''): ?> · <?php endif; ?>
|
||||
<?= htmlspecialchars($category, ENT_QUOTES, 'UTF-8') ?>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
$pageTitle = $title ?? 'Post';
|
||||
$contentHtml = (string)($content_html ?? '');
|
||||
$publishedAt = (string)($published_at ?? '');
|
||||
$authorName = (string)($author_name ?? '');
|
||||
$category = (string)($category ?? '');
|
||||
$tags = (string)($tags ?? '');
|
||||
$tagList = array_filter(array_map('trim', explode(',', $tags)));
|
||||
$publishedDisplay = '';
|
||||
if ($publishedAt !== '') {
|
||||
try {
|
||||
$publishedDisplay = (new DateTime($publishedAt))->format('d M Y');
|
||||
} catch (Throwable $e) {
|
||||
$publishedDisplay = $publishedAt;
|
||||
}
|
||||
}
|
||||
ob_start();
|
||||
?>
|
||||
<section class="card article-shell-fluid">
|
||||
<div class="article-fluid-grid">
|
||||
<aside class="article-fluid-meta">
|
||||
<div class="badge">News</div>
|
||||
<h1 class="article-fluid-title"><?= htmlspecialchars($pageTitle, ENT_QUOTES, 'UTF-8') ?></h1>
|
||||
<div class="article-fluid-meta-list">
|
||||
<?php if ($publishedDisplay !== ''): ?>
|
||||
<div class="article-fluid-meta-item">
|
||||
<span>Date</span>
|
||||
<strong><?= htmlspecialchars($publishedDisplay, ENT_QUOTES, 'UTF-8') ?></strong>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($authorName !== ''): ?>
|
||||
<div class="article-fluid-meta-item">
|
||||
<span>Author</span>
|
||||
<strong><?= htmlspecialchars($authorName, ENT_QUOTES, 'UTF-8') ?></strong>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($category !== ''): ?>
|
||||
<div class="article-fluid-meta-item">
|
||||
<span>Category</span>
|
||||
<strong><?= htmlspecialchars($category, ENT_QUOTES, 'UTF-8') ?></strong>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($tagList): ?>
|
||||
<div class="article-fluid-tags">
|
||||
<?php foreach ($tagList as $tag): ?>
|
||||
<span><?= htmlspecialchars((string)$tag, ENT_QUOTES, 'UTF-8') ?></span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<a href="/news" class="article-fluid-back">Back to news</a>
|
||||
</aside>
|
||||
|
||||
<div class="article-fluid-content-shell">
|
||||
<div class="article-fluid-post-box">
|
||||
<?= $contentHtml ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($featuredImage !== ''): ?>
|
||||
<img src="<?= htmlspecialchars($featuredImage, ENT_QUOTES, 'UTF-8') ?>" alt="" style="width:100%; border-radius:16px; margin-top:16px;">
|
||||
<?php endif; ?>
|
||||
<div style="margin-top:14px; color:var(--muted); line-height:1.8;">
|
||||
<?= $contentHtml ?>
|
||||
</div>
|
||||
<?php if ($tags !== ''): ?>
|
||||
<div style="margin-top:16px; display:flex; flex-wrap:wrap; gap:6px;">
|
||||
<?php foreach (array_filter(array_map('trim', explode(',', (string)$tags))) as $tag): ?>
|
||||
<span style="font-size:11px; color:#c8ccd8; border:1px solid rgba(255,255,255,0.15); padding:4px 8px; border-radius:999px;">
|
||||
<?= htmlspecialchars((string)$tag, ENT_QUOTES, 'UTF-8') ?>
|
||||
</span>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</section>
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
require __DIR__ . '/../../../views/site/layout.php';
|
||||
|
||||
<style>
|
||||
.article-shell-fluid {
|
||||
padding: 0;
|
||||
}
|
||||
.article-fluid-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 280px minmax(0, 1fr);
|
||||
gap: 0;
|
||||
align-items: start;
|
||||
min-height: 100%;
|
||||
}
|
||||
.article-fluid-meta {
|
||||
display: grid;
|
||||
gap: 18px;
|
||||
align-content: start;
|
||||
min-height: 100%;
|
||||
padding: 32px 24px;
|
||||
}
|
||||
.article-fluid-title {
|
||||
margin: 0;
|
||||
color: #f5f7ff;
|
||||
font-size: clamp(34px, 3vw, 56px);
|
||||
line-height: .94;
|
||||
word-break: break-word;
|
||||
}
|
||||
.article-fluid-meta-list {
|
||||
display: grid;
|
||||
gap: 14px;
|
||||
}
|
||||
.article-fluid-meta-item span {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
color: rgba(255,255,255,.56);
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 10px;
|
||||
letter-spacing: .18em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.article-fluid-meta-item strong {
|
||||
color: #e8eefc;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.article-fluid-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
.article-fluid-tags span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 7px 10px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(255,255,255,.12);
|
||||
background: rgba(255,255,255,.04);
|
||||
color: #dce5f6;
|
||||
font-size: 11px;
|
||||
}
|
||||
.article-fluid-back {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 42px;
|
||||
padding: 0 14px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(255,255,255,.14);
|
||||
background: rgba(255,255,255,.04);
|
||||
color: #eef4ff;
|
||||
text-decoration: none;
|
||||
font-family: 'IBM Plex Mono', monospace;
|
||||
font-size: 11px;
|
||||
letter-spacing: .16em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.article-fluid-back:hover {
|
||||
border-color: rgba(34,242,165,.36);
|
||||
color: #9ff8d8;
|
||||
}
|
||||
.article-fluid-content-shell {
|
||||
min-width: 0;
|
||||
min-height: 100%;
|
||||
margin: 0;
|
||||
padding: 40px 44px;
|
||||
border-radius: 0 28px 28px 0;
|
||||
background: #f4f1ec;
|
||||
box-shadow: none;
|
||||
}
|
||||
.article-fluid-post-box {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
color: #26272d;
|
||||
}
|
||||
.article-fluid-post-box,
|
||||
.article-fluid-post-box p,
|
||||
.article-fluid-post-box li,
|
||||
.article-fluid-post-box blockquote,
|
||||
.article-fluid-post-box figcaption,
|
||||
.article-fluid-post-box td,
|
||||
.article-fluid-post-box th {
|
||||
color: #3a3d45;
|
||||
}
|
||||
.article-fluid-post-box h1,
|
||||
.article-fluid-post-box h2,
|
||||
.article-fluid-post-box h3,
|
||||
.article-fluid-post-box h4,
|
||||
.article-fluid-post-box h5,
|
||||
.article-fluid-post-box h6,
|
||||
.article-fluid-post-box strong {
|
||||
color: #202228;
|
||||
}
|
||||
.article-fluid-post-box,
|
||||
.article-fluid-post-box > *,
|
||||
.article-fluid-post-box > * > *,
|
||||
.article-fluid-post-box > * > * > * {
|
||||
max-width: none !important;
|
||||
}
|
||||
.article-fluid-post-box > * {
|
||||
width: 100% !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.article-fluid-post-box > div,
|
||||
.article-fluid-post-box > section,
|
||||
.article-fluid-post-box > article,
|
||||
.article-fluid-post-box > main,
|
||||
.article-fluid-post-box > figure {
|
||||
width: 100% !important;
|
||||
max-width: none !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.article-fluid-post-box * {
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.article-fluid-post-box [style*="max-width"],
|
||||
.article-fluid-post-box [style*="width"],
|
||||
.article-fluid-post-box [style*="margin: auto"],
|
||||
.article-fluid-post-box [style*="margin-left:auto"],
|
||||
.article-fluid-post-box [style*="margin-right:auto"] {
|
||||
max-width: none !important;
|
||||
width: 100% !important;
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.article-fluid-post-box > div,
|
||||
.article-fluid-post-box > section,
|
||||
.article-fluid-post-box > article,
|
||||
.article-fluid-post-box > main,
|
||||
.article-fluid-post-box > figure,
|
||||
.article-fluid-post-box > div > div:first-child {
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
border: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
.article-fluid-post-box img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
}
|
||||
.article-fluid-post-box iframe,
|
||||
.article-fluid-post-box video,
|
||||
.article-fluid-post-box table,
|
||||
.article-fluid-post-box pre {
|
||||
max-width: 100%;
|
||||
}
|
||||
@media (max-width: 980px) {
|
||||
.article-fluid-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
.article-fluid-meta {
|
||||
padding: 24px 24px 8px;
|
||||
}
|
||||
.article-fluid-content-shell {
|
||||
margin: 0;
|
||||
border-radius: 0 0 28px 28px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
.article-shell-fluid {
|
||||
padding: 0;
|
||||
}
|
||||
.article-fluid-content-shell {
|
||||
padding: 28px 24px;
|
||||
}
|
||||
.article-fluid-post-box {
|
||||
padding: 0;
|
||||
}
|
||||
.article-fluid-title {
|
||||
font-size: 42px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
$content = ob_get_clean();
|
||||
require __DIR__ . '/../../../../views/site/layout.php';
|
||||
|
||||
Reference in New Issue
Block a user