Merge branch 'main' of https://github.com/Spleenftw/blowdit
This commit is contained in:
commit
1839946934
23 files changed
+211
-206
No files matched your search
+5
-5
@@ -30,15 +30,15 @@
|
||||
$bdSp = new Page($bdSk);
|
||||
if ($bdSp->isStatic()) { continue; } // posts only
|
||||
$bdSearchIndex[] = array(
|
||||
't' => blowdit_plain($bdSp->title()),
|
||||
't' => blowfish_plain($bdSp->title()),
|
||||
'u' => $bdSp->permalink(),
|
||||
'd' => blowdit_plain($bdSp->description()),
|
||||
'c' => blowdit_plain($bdSp->category()),
|
||||
'g' => array_values(array_map('blowdit_plain', $bdSp->tags(true))),
|
||||
'd' => blowfish_plain($bdSp->description()),
|
||||
'c' => blowfish_plain($bdSp->category()),
|
||||
'g' => array_values(array_map('blowfish_plain', $bdSp->tags(true))),
|
||||
);
|
||||
}
|
||||
}
|
||||
echo '<script type="application/json" id="blowdit-search-index">'
|
||||
echo '<script type="application/json" id="blowfish-search-index">'
|
||||
. json_encode($bdSearchIndex, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
|
||||
. '</script>';
|
||||
} catch (\Throwable $e) {}
|
||||
|
||||
+44
-44
@@ -5,23 +5,23 @@
|
||||
<!-- Tint the mobile browser chrome to match the navbar (--chrome-bg per theme).
|
||||
Set server-side from the theme cookie so it's correct on the first paint. -->
|
||||
<?php
|
||||
$blowditChromeColors = array(
|
||||
$blowfishChromeColors = array(
|
||||
'light' => '#1f1f1f',
|
||||
'dark' => '#1f1f1f',
|
||||
'nord' => '#3b4252',
|
||||
'dracula' => '#343746',
|
||||
'catppuccin' => '#313244',
|
||||
);
|
||||
$blowditChrome = isset($blowditChromeColors[$blowditTheme]) ? $blowditChromeColors[$blowditTheme] : '#1f1f1f';
|
||||
$blowfishChrome = isset($blowfishChromeColors[$blowfishTheme]) ? $blowfishChromeColors[$blowfishTheme] : '#1f1f1f';
|
||||
?>
|
||||
<meta name="theme-color" content="<?php echo $blowditChrome; ?>">
|
||||
<meta name="theme-color" content="<?php echo $blowfishChrome; ?>">
|
||||
|
||||
<?php if (!empty($blowditIsArticle) && $page->coverImage()): ?>
|
||||
<?php if (!empty($blowfishIsArticle) && $page->coverImage()): ?>
|
||||
<!-- Preload the article cover image (typically the LCP element) -->
|
||||
<link rel="preload" as="image" href="<?php echo htmlspecialchars($page->coverImage(true), ENT_QUOTES, 'UTF-8'); ?>" fetchpriority="high">
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (!empty($blowditIsArticle)): ?>
|
||||
<?php if (!empty($blowfishIsArticle)): ?>
|
||||
<!-- Warm up connections to article third-parties (comments + tweet embeds) -->
|
||||
<link rel="preconnect" href="https://utteranc.es" crossorigin>
|
||||
<link rel="dns-prefetch" href="https://platform.twitter.com">
|
||||
@@ -32,7 +32,7 @@
|
||||
Sets data-theme AND paints the html background/color-scheme inline, so the
|
||||
very first frame (before style.css loads) already uses the theme colour. -->
|
||||
<script data-cfasync="false">
|
||||
window.BLOWDIT_THEME_BG = {
|
||||
window.BLOWFISH_THEME_BG = {
|
||||
light: '#ffffff',
|
||||
dark: '#171717',
|
||||
nord: '#2e3440',
|
||||
@@ -41,8 +41,8 @@
|
||||
};
|
||||
(function () {
|
||||
try {
|
||||
var bg = window.BLOWDIT_THEME_BG;
|
||||
var stored = localStorage.getItem('blowdit-theme');
|
||||
var bg = window.BLOWFISH_THEME_BG;
|
||||
var stored = localStorage.getItem('blowfish-theme');
|
||||
if (!bg[stored]) {
|
||||
stored = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
}
|
||||
@@ -51,7 +51,7 @@
|
||||
root.style.colorScheme = (stored === 'light') ? 'light' : 'dark';
|
||||
root.style.backgroundColor = bg[stored];
|
||||
// Persist to a cookie so PHP can pre-colour the next page server-side.
|
||||
document.cookie = 'blowdit-theme=' + stored + '; path=/; max-age=31536000; SameSite=Lax';
|
||||
document.cookie = 'blowfish-theme=' + stored + '; path=/; max-age=31536000; SameSite=Lax';
|
||||
} catch (e) {}
|
||||
})();
|
||||
</script>
|
||||
@@ -64,13 +64,13 @@
|
||||
|
||||
<?php
|
||||
// ---- Social sharing metadata (Open Graph + Twitter Card) ----
|
||||
// $blowditIsArticle is pre-computed in index.php before this file is included.
|
||||
$ogIsArticle = !empty($blowditIsArticle);
|
||||
// $blowfishIsArticle is pre-computed in index.php before this file is included.
|
||||
$ogIsArticle = !empty($blowfishIsArticle);
|
||||
|
||||
// ISO 8601 publish date — formatted explicitly so it's valid regardless of
|
||||
// the admin's configured date format. Falls back to dateRaw() if Date is unavailable.
|
||||
if (!function_exists('blowdit_iso_date')) {
|
||||
function blowdit_iso_date($page, $field) {
|
||||
if (!function_exists('blowfish_iso_date')) {
|
||||
function blowfish_iso_date($page, $field) {
|
||||
$raw = $page->getValue($field);
|
||||
if (!$raw) { return ''; }
|
||||
if (class_exists('Date')) {
|
||||
@@ -86,7 +86,7 @@
|
||||
$ogDesc = $page->description();
|
||||
$ogUrl = $page->permalink(true);
|
||||
$ogImage = $page->coverImage(true);
|
||||
$ogPublishedIso = blowdit_iso_date($page, 'date');
|
||||
$ogPublishedIso = blowfish_iso_date($page, 'date');
|
||||
} else {
|
||||
$ogTitle = $site->title();
|
||||
$ogDesc = '';
|
||||
@@ -105,52 +105,52 @@
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:type" content="<?php echo htmlspecialchars($ogType, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<meta property="og:site_name" content="<?php echo blowdit_text($ogSiteName); ?>">
|
||||
<meta property="og:title" content="<?php echo blowdit_text($ogTitle); ?>">
|
||||
<meta property="og:description" content="<?php echo blowdit_text($ogDesc); ?>">
|
||||
<meta property="og:site_name" content="<?php echo blowfish_text($ogSiteName); ?>">
|
||||
<meta property="og:title" content="<?php echo blowfish_text($ogTitle); ?>">
|
||||
<meta property="og:description" content="<?php echo blowfish_text($ogDesc); ?>">
|
||||
<meta property="og:url" content="<?php echo htmlspecialchars($ogUrl, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<meta property="og:image" content="<?php echo htmlspecialchars($ogImage, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<meta property="og:image:alt" content="<?php echo blowdit_text($ogTitle); ?>">
|
||||
<meta property="og:image:alt" content="<?php echo blowfish_text($ogTitle); ?>">
|
||||
<meta property="og:locale" content="<?php echo htmlspecialchars(str_replace('-', '_', Theme::lang()), ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php if ($ogIsArticle): ?>
|
||||
<meta property="article:published_time" content="<?php echo htmlspecialchars($ogPublishedIso, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<meta property="article:author" content="<?php echo blowdit_text($page->username()); ?>">
|
||||
<meta property="article:author" content="<?php echo blowfish_text($page->username()); ?>">
|
||||
<?php endif ?>
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<?php if (!empty($blowditTwitterHandle)): ?>
|
||||
<meta name="twitter:site" content="<?php echo htmlspecialchars($blowditTwitterHandle, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<meta name="twitter:creator" content="<?php echo htmlspecialchars($blowditTwitterHandle, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php if (!empty($blowfishTwitterHandle)): ?>
|
||||
<meta name="twitter:site" content="<?php echo htmlspecialchars($blowfishTwitterHandle, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<meta name="twitter:creator" content="<?php echo htmlspecialchars($blowfishTwitterHandle, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<?php endif ?>
|
||||
<meta name="twitter:title" content="<?php echo blowdit_text($ogTitle); ?>">
|
||||
<meta name="twitter:description" content="<?php echo blowdit_text($ogDesc); ?>">
|
||||
<meta name="twitter:title" content="<?php echo blowfish_text($ogTitle); ?>">
|
||||
<meta name="twitter:description" content="<?php echo blowfish_text($ogDesc); ?>">
|
||||
<meta name="twitter:image" content="<?php echo htmlspecialchars($ogImage, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<meta name="twitter:image:alt" content="<?php echo blowdit_text($ogTitle); ?>">
|
||||
<meta name="twitter:image:alt" content="<?php echo blowfish_text($ogTitle); ?>">
|
||||
|
||||
<?php
|
||||
// ---- JSON-LD structured data ----
|
||||
$blowditEmitLd = function ($doc) {
|
||||
$blowfishEmitLd = function ($doc) {
|
||||
echo '<script type="application/ld+json">'
|
||||
. json_encode($doc, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
|
||||
. '</script>' . "\n";
|
||||
};
|
||||
|
||||
// Social profile URLs, used as schema.org "sameAs".
|
||||
$blowditSameAs = array();
|
||||
$blowfishSameAs = array();
|
||||
foreach (Theme::socialNetworks() as $snKey => $snLabel) {
|
||||
$snUrl = $site->{$snKey}();
|
||||
if (!empty($snUrl)) { $blowditSameAs[] = $snUrl; }
|
||||
if (!empty($snUrl)) { $blowfishSameAs[] = $snUrl; }
|
||||
}
|
||||
|
||||
// WebSite (every page) — declares the site + a sitelinks search box.
|
||||
$siteLd = array(
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'WebSite',
|
||||
'name' => blowdit_plain($site->title()),
|
||||
'name' => blowfish_plain($site->title()),
|
||||
'url' => Theme::siteUrl(),
|
||||
);
|
||||
$siteDesc = $site->description() ?: $site->slogan();
|
||||
if ($siteDesc) { $siteLd['description'] = blowdit_plain($siteDesc); }
|
||||
if ($siteDesc) { $siteLd['description'] = blowfish_plain($siteDesc); }
|
||||
$siteLd['potentialAction'] = array(
|
||||
'@type' => 'SearchAction',
|
||||
'target' => array(
|
||||
@@ -159,7 +159,7 @@
|
||||
),
|
||||
'query-input' => 'required name=search_term_string',
|
||||
);
|
||||
$blowditEmitLd($siteLd);
|
||||
$blowfishEmitLd($siteLd);
|
||||
|
||||
// BlogPosting + BreadcrumbList — articles only.
|
||||
if ($ogIsArticle) {
|
||||
@@ -168,7 +168,7 @@
|
||||
$ldPublished = $ogPublishedIso;
|
||||
|
||||
// dateModified: fall back to published date when not tracked.
|
||||
$ldModified = blowdit_iso_date($page, 'dateModified');
|
||||
$ldModified = blowfish_iso_date($page, 'dateModified');
|
||||
if (!$ldModified) { $ldModified = $ldPublished; }
|
||||
|
||||
// timeRequired as an ISO 8601 duration (e.g. "PT8M") parsed from readingTime().
|
||||
@@ -179,23 +179,23 @@
|
||||
|
||||
$author = array(
|
||||
'@type' => 'Person',
|
||||
'name' => blowdit_plain($page->username()),
|
||||
'name' => blowfish_plain($page->username()),
|
||||
'url' => Theme::siteUrl(),
|
||||
);
|
||||
if (!empty($blowditSameAs)) { $author['sameAs'] = $blowditSameAs; }
|
||||
if (!empty($blowfishSameAs)) { $author['sameAs'] = $blowfishSameAs; }
|
||||
|
||||
$jsonLd = array(
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'BlogPosting',
|
||||
'headline' => blowdit_plain($page->title()),
|
||||
'description' => blowdit_plain($ldDescription),
|
||||
'headline' => blowfish_plain($page->title()),
|
||||
'description' => blowfish_plain($ldDescription),
|
||||
'image' => $ldImage,
|
||||
'datePublished' => $ldPublished,
|
||||
'dateModified' => $ldModified,
|
||||
'author' => $author,
|
||||
'publisher' => array(
|
||||
'@type' => 'Organization',
|
||||
'name' => blowdit_plain($site->title()),
|
||||
'name' => blowfish_plain($site->title()),
|
||||
'logo' => array(
|
||||
'@type' => 'ImageObject',
|
||||
'url' => DOMAIN_THEME . 'img/favicon.png',
|
||||
@@ -208,25 +208,25 @@
|
||||
'wordCount' => str_word_count(strip_tags($page->content())),
|
||||
);
|
||||
if ($ldTimeRequired) { $jsonLd['timeRequired'] = $ldTimeRequired; }
|
||||
$blowditEmitLd($jsonLd);
|
||||
$blowfishEmitLd($jsonLd);
|
||||
|
||||
// Breadcrumb: Home > [Category] > Article
|
||||
$crumbs = array(array(
|
||||
'@type' => 'ListItem', 'position' => 1,
|
||||
'name' => blowdit_plain($site->title()), 'item' => Theme::siteUrl(),
|
||||
'name' => blowfish_plain($site->title()), 'item' => Theme::siteUrl(),
|
||||
));
|
||||
$pos = 2;
|
||||
if ($page->categoryKey()) {
|
||||
$crumbs[] = array(
|
||||
'@type' => 'ListItem', 'position' => $pos++,
|
||||
'name' => blowdit_plain($page->category()), 'item' => $page->categoryPermalink(),
|
||||
'name' => blowfish_plain($page->category()), 'item' => $page->categoryPermalink(),
|
||||
);
|
||||
}
|
||||
$crumbs[] = array(
|
||||
'@type' => 'ListItem', 'position' => $pos,
|
||||
'name' => blowdit_plain($page->title()), 'item' => $page->permalink(true),
|
||||
'name' => blowfish_plain($page->title()), 'item' => $page->permalink(true),
|
||||
);
|
||||
$blowditEmitLd(array(
|
||||
$blowfishEmitLd(array(
|
||||
'@context' => 'https://schema.org',
|
||||
'@type' => 'BreadcrumbList',
|
||||
'itemListElement' => $crumbs,
|
||||
@@ -235,7 +235,7 @@
|
||||
?>
|
||||
|
||||
<!-- RSS feed auto-discovery (RSS plugin serves /rss.xml) -->
|
||||
<link rel="alternate" type="application/rss+xml" title="<?php echo blowdit_text($site->title()); ?>" href="<?php echo rtrim(Theme::siteUrl(), '/') . '/rss.xml'; ?>">
|
||||
<link rel="alternate" type="application/rss+xml" title="<?php echo blowfish_text($site->title()); ?>" href="<?php echo rtrim(Theme::siteUrl(), '/') . '/rss.xml'; ?>">
|
||||
|
||||
<!-- Include Favicon -->
|
||||
<?php echo Theme::favicon('img/favicon.png'); ?>
|
||||
@@ -252,7 +252,7 @@
|
||||
<?php echo Theme::cssBootstrap(); ?>
|
||||
|
||||
<!-- Bootstrap Icons webfont removed: the few icons used are inline SVGs
|
||||
(see php/icons.php + blowdit.js), saving ~120 KB font + ~80 KB CSS. -->
|
||||
(see php/icons.php + blowfish.js), saving ~120 KB font + ~80 KB CSS. -->
|
||||
|
||||
<!-- Include CSS Styles from this theme (cache-busted by file mtime) -->
|
||||
<?php
|
||||
|
||||
+17
-17
@@ -7,29 +7,29 @@
|
||||
?>
|
||||
<?php if ($showProfile) : ?>
|
||||
<header class="profile text-center">
|
||||
<img class="profile-avatar" src="<?php echo $profileImage; ?>" alt="<?php echo blowdit_text($site->title()); ?>" />
|
||||
<h1 class="profile-name"><?php echo blowdit_text($site->title()); ?></h1>
|
||||
<img class="profile-avatar" src="<?php echo $profileImage; ?>" alt="<?php echo blowfish_text($site->title()); ?>" />
|
||||
<h1 class="profile-name"><?php echo blowfish_text($site->title()); ?></h1>
|
||||
<?php if ($site->slogan()) : ?>
|
||||
<p class="profile-bio"><?php echo blowdit_text($site->slogan()); ?></p>
|
||||
<p class="profile-bio"><?php echo blowfish_text($site->slogan()); ?></p>
|
||||
<?php elseif ($site->description()) : ?>
|
||||
<p class="profile-bio"><?php echo blowdit_text($site->description()); ?></p>
|
||||
<p class="profile-bio"><?php echo blowfish_text($site->description()); ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<?php $networks = Theme::socialNetworks(); ?>
|
||||
<div class="profile-social">
|
||||
<?php foreach ($networks as $key => $label) : ?>
|
||||
<a href="<?php echo $site->{$key}(); ?>" target="_blank" rel="noopener" title="<?php echo blowdit_text($label) ?>">
|
||||
<img class="profile-social-icon" src="<?php echo blowdit_asset('img/' . $key . '.svg') ?>" alt="<?php echo blowdit_text($label) ?>" />
|
||||
<a href="<?php echo $site->{$key}(); ?>" target="_blank" rel="noopener" title="<?php echo blowfish_text($label) ?>">
|
||||
<img class="profile-social-icon" src="<?php echo blowfish_asset('img/' . $key . '.svg') ?>" alt="<?php echo blowfish_text($label) ?>" />
|
||||
</a>
|
||||
<?php endforeach ?>
|
||||
<!-- RSS feed (served by the RSS plugin at /rss.xml) -->
|
||||
<a href="<?php echo rtrim(Theme::siteUrl(), '/') . '/rss.xml'; ?>" target="_blank" rel="noopener" title="<?php echo $L->get('RSS'); ?>">
|
||||
<img class="profile-social-icon" src="<?php echo blowdit_asset('img/rss.svg') ?>" alt="<?php echo $L->get('RSS'); ?>" />
|
||||
<img class="profile-social-icon" src="<?php echo blowfish_asset('img/rss.svg') ?>" alt="<?php echo $L->get('RSS'); ?>" />
|
||||
</a>
|
||||
<!-- Email (mailto) -->
|
||||
<?php if (!empty($blowditEmail)) : ?>
|
||||
<a href="mailto:<?php echo htmlspecialchars($blowditEmail, ENT_QUOTES, 'UTF-8'); ?>" title="<?php echo $L->get('Email'); ?>">
|
||||
<img class="profile-social-icon" src="<?php echo blowdit_asset('img/mail.svg') ?>" alt="<?php echo $L->get('Email'); ?>" />
|
||||
<?php if (!empty($blowfishEmail)) : ?>
|
||||
<a href="mailto:<?php echo htmlspecialchars($blowfishEmail, ENT_QUOTES, 'UTF-8'); ?>" title="<?php echo $L->get('Email'); ?>">
|
||||
<img class="profile-social-icon" src="<?php echo blowfish_asset('img/mail.svg') ?>" alt="<?php echo $L->get('Email'); ?>" />
|
||||
</a>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
@@ -59,12 +59,12 @@
|
||||
|
||||
<div class="post-list-head">
|
||||
<a href="<?php echo $page->permalink(); ?>">
|
||||
<h2 class="post-list-title"><?php echo blowdit_text($page->title()); ?></h2>
|
||||
<h2 class="post-list-title"><?php echo blowfish_text($page->title()); ?></h2>
|
||||
</a>
|
||||
<div class="post-list-meta">
|
||||
<span><?php echo blowdit_icon('calendar'); ?><?php echo $page->date(); ?></span>
|
||||
<span><?php echo blowfish_icon('calendar'); ?><?php echo $page->date(); ?></span>
|
||||
<?php if (!$page->isStatic()) : ?>
|
||||
<span><?php echo blowdit_icon('clock'); ?><?php echo $page->readingTime(); ?></span>
|
||||
<span><?php echo blowfish_icon('clock'); ?><?php echo $page->readingTime(); ?></span>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,11 +75,11 @@
|
||||
<div class="post-taxonomy">
|
||||
<?php if ($categoryKey) : ?>
|
||||
<a class="taxonomy-badge" href="<?php echo $page->categoryPermalink(); ?>">
|
||||
<?php echo blowdit_icon('folder'); ?><?php echo blowdit_text($page->category()); ?>
|
||||
<?php echo blowfish_icon('folder'); ?><?php echo blowfish_text($page->category()); ?>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
<?php foreach ($tagsList as $tagKey => $tagName) : ?>
|
||||
<a class="taxonomy-badge" href="<?php echo DOMAIN_TAGS . $tagKey; ?>"><?php echo blowdit_icon('tag'); ?><?php echo blowdit_text($tagName); ?></a>
|
||||
<a class="taxonomy-badge" href="<?php echo DOMAIN_TAGS . $tagKey; ?>"><?php echo blowfish_icon('tag'); ?><?php echo blowfish_text($tagName); ?></a>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
@@ -120,7 +120,7 @@
|
||||
<?php if (Paginator::showPrev()) : ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link is-arrow" href="<?php echo Paginator::previousPageUrl() ?>" aria-label="<?php echo $L->get('Previous'); ?>">
|
||||
<?php echo blowdit_icon('chevron-left'); ?>
|
||||
<?php echo blowfish_icon('chevron-left'); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
@@ -140,7 +140,7 @@
|
||||
<?php if (Paginator::showNext()) : ?>
|
||||
<li class="page-item">
|
||||
<a class="page-link is-arrow" href="<?php echo Paginator::nextPageUrl() ?>" aria-label="<?php echo $L->get('Next'); ?>">
|
||||
<?php echo blowdit_icon('chevron-right'); ?>
|
||||
<?php echo blowfish_icon('chevron-right'); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
|
||||
+11
-11
@@ -7,10 +7,10 @@
|
||||
* font-size rules (.navbar .nav-link .bd-icon, .metadata .bd-icon, …) scale it.
|
||||
*
|
||||
* Theme-picker icons (sun/moon/snow/droplet/cup/half) are duplicated in
|
||||
* blowdit.js so the toggle can swap them client-side; keep the two in sync.
|
||||
* blowfish.js so the toggle can swap them client-side; keep the two in sync.
|
||||
*/
|
||||
if (!function_exists('blowdit_icon')) {
|
||||
function blowdit_icon($name) {
|
||||
if (!function_exists('blowfish_icon')) {
|
||||
function blowfish_icon($name) {
|
||||
static $paths = array(
|
||||
// --- UI ---
|
||||
'calendar' => '<rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/>',
|
||||
@@ -23,7 +23,7 @@ if (!function_exists('blowdit_icon')) {
|
||||
'link' => '<path d="M9 17H7A5 5 0 0 1 7 7h2"/><path d="M15 7h2a5 5 0 0 1 0 10h-2"/><path d="M8 12h8"/>',
|
||||
'search' => '<circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/>',
|
||||
'share' => '<circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="M8.6 13.5l6.8 4M15.4 6.5l-6.8 4"/>',
|
||||
// --- Theme picker (mirror in blowdit.js) ---
|
||||
// --- Theme picker (mirror in blowfish.js) ---
|
||||
'sun' => '<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/>',
|
||||
'moon' => '<path d="M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8z"/>',
|
||||
'snow' => '<path d="M12 2v20M2 12h20M5 5l14 14M19 5 5 19"/>',
|
||||
@@ -39,24 +39,24 @@ if (!function_exists('blowdit_icon')) {
|
||||
|
||||
// Bludit already HTML-escapes titles/names on save (Sanitize::html), so a
|
||||
// plain htmlspecialchars() in the theme double-encodes ("&" -> "&amp;",
|
||||
// shown as "&"). blowdit_text() decodes any existing entities first, then
|
||||
// shown as "&"). blowfish_text() decodes any existing entities first, then
|
||||
// encodes exactly once — correct whether the value is pre-encoded or raw, and
|
||||
// always output-safe. blowdit_plain() returns decoded text (for JSON-LD etc.).
|
||||
function blowdit_plain($s) {
|
||||
// always output-safe. blowfish_plain() returns decoded text (for JSON-LD etc.).
|
||||
function blowfish_plain($s) {
|
||||
return html_entity_decode((string) $s, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
function blowdit_text($s) {
|
||||
return htmlspecialchars(blowdit_plain($s), ENT_QUOTES, 'UTF-8');
|
||||
function blowfish_text($s) {
|
||||
return htmlspecialchars(blowfish_plain($s), ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
// Theme asset URL with an mtime cache-buster (so edited images/SVGs refetch).
|
||||
function blowdit_asset($rel) {
|
||||
function blowfish_asset($rel) {
|
||||
$v = @filemtime(THEME_DIR . $rel);
|
||||
return DOMAIN_THEME . $rel . ($v ? '?v=' . $v : '');
|
||||
}
|
||||
|
||||
// Map a theme key to its toggle icon name.
|
||||
function blowdit_theme_icon($theme) {
|
||||
function blowfish_theme_icon($theme) {
|
||||
$map = array(
|
||||
'light' => 'sun',
|
||||
'dark' => 'moon',
|
||||
|
||||
+12
-12
@@ -1,7 +1,7 @@
|
||||
<nav class="navbar navbar-expand-md navbar-dark fixed-top navbar-modern">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="<?php echo Theme::siteUrl() ?>">
|
||||
<span class="text-white"><?php echo blowdit_text($site->title()) ?></span>
|
||||
<span class="text-white"><?php echo blowfish_text($site->title()) ?></span>
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
@@ -19,7 +19,7 @@
|
||||
<!-- Static pages -->
|
||||
<?php foreach ($staticContent as $staticPage) : ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link<?php echo ($url->slug() == $staticPage->slug()) ? ' active' : '' ?>" href="<?php echo $staticPage->permalink() ?>"><?php echo blowdit_text($staticPage->title()) ?></a>
|
||||
<a class="nav-link<?php echo ($url->slug() == $staticPage->slug()) ? ' active' : '' ?>" href="<?php echo $staticPage->permalink() ?>"><?php echo blowfish_text($staticPage->title()) ?></a>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
<!-- Social Networks (SVG icons live in img/<network>.svg) -->
|
||||
<?php foreach (Theme::socialNetworks() as $key => $label) : ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<?php echo $site->{$key}(); ?>" target="_blank" rel="noopener" title="<?php echo blowdit_text($label) ?>">
|
||||
<img class="d-none d-md-block nav-svg-icon" src="<?php echo blowdit_asset('img/' . $key . '.svg') ?>" alt="<?php echo blowdit_text($label) ?>" />
|
||||
<span class="d-inline d-md-none"><?php echo blowdit_text($label); ?></span>
|
||||
<a class="nav-link" href="<?php echo $site->{$key}(); ?>" target="_blank" rel="noopener" title="<?php echo blowfish_text($label) ?>">
|
||||
<img class="d-none d-md-block nav-svg-icon" src="<?php echo blowfish_asset('img/' . $key . '.svg') ?>" alt="<?php echo blowfish_text($label) ?>" />
|
||||
<span class="d-inline d-md-none"><?php echo blowfish_text($label); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
@@ -43,16 +43,16 @@
|
||||
<!-- RSS feed (served by the RSS plugin at /rss.xml) -->
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="<?php echo rtrim(Theme::siteUrl(), '/') . '/rss.xml'; ?>" target="_blank" rel="noopener" title="<?php echo $L->get('RSS'); ?>">
|
||||
<img class="d-none d-md-block nav-svg-icon" src="<?php echo blowdit_asset('img/rss.svg') ?>" alt="<?php echo $L->get('RSS'); ?>" />
|
||||
<img class="d-none d-md-block nav-svg-icon" src="<?php echo blowfish_asset('img/rss.svg') ?>" alt="<?php echo $L->get('RSS'); ?>" />
|
||||
<span class="d-inline d-md-none"><?php echo $L->get('RSS'); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<!-- Email (mailto) -->
|
||||
<?php if (!empty($blowditEmail)) : ?>
|
||||
<?php if (!empty($blowfishEmail)) : ?>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="mailto:<?php echo htmlspecialchars($blowditEmail, ENT_QUOTES, 'UTF-8'); ?>" title="<?php echo $L->get('Email'); ?>">
|
||||
<img class="d-none d-md-block nav-svg-icon" src="<?php echo blowdit_asset('img/mail.svg') ?>" alt="<?php echo $L->get('Email'); ?>" />
|
||||
<a class="nav-link" href="mailto:<?php echo htmlspecialchars($blowfishEmail, ENT_QUOTES, 'UTF-8'); ?>" title="<?php echo $L->get('Email'); ?>">
|
||||
<img class="d-none d-md-block nav-svg-icon" src="<?php echo blowfish_asset('img/mail.svg') ?>" alt="<?php echo $L->get('Email'); ?>" />
|
||||
<span class="d-inline d-md-none"><?php echo $L->get('Email'); ?></span>
|
||||
</a>
|
||||
</li>
|
||||
@@ -60,17 +60,17 @@
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Search (opens the overlay; also bound to the "/" key). Shown by
|
||||
blowdit.js only when no on-page search box is visible. -->
|
||||
blowfish.js only when no on-page search box is visible. -->
|
||||
<li class="nav-item nav-search ml-md-2 mt-2 mt-md-0">
|
||||
<button type="button" class="theme-toggle js-search-open" aria-label="<?php echo $L->get('Search'); ?>" title="<?php echo $L->get('Search'); ?> (/)">
|
||||
<?php echo blowdit_icon('search'); ?>
|
||||
<?php echo blowfish_icon('search'); ?>
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<!-- Theme picker -->
|
||||
<li class="nav-item ml-md-2 mt-2 mt-md-0 theme-picker-wrap">
|
||||
<button type="button" id="theme-toggle" class="theme-toggle" aria-label="<?php echo $L->get('Toggle theme') ?>" title="<?php echo $L->get('Toggle theme') ?>" aria-haspopup="true" aria-expanded="false">
|
||||
<?php echo blowdit_icon(blowdit_theme_icon($blowditTheme)); ?>
|
||||
<?php echo blowfish_icon(blowfish_theme_icon($blowfishTheme)); ?>
|
||||
</button>
|
||||
<div id="theme-picker" class="theme-picker" role="menu">
|
||||
<button class="swatch" data-pick="light" title="Light" style="--sb:#ffffff;--sa:#1f1f1f"><span class="swatch-dot"></span><span class="swatch-label">Light</span></button>
|
||||
|
||||
+16
-16
@@ -9,7 +9,7 @@
|
||||
<?php if (!empty($sidebarSearchHtml)) : ?>
|
||||
<div class="error-search"><?php echo $sidebarSearchHtml; ?></div>
|
||||
<?php endif ?>
|
||||
<a class="btn-primary-gradient error-home" href="<?php echo Theme::siteUrl(); ?>"><?php echo blowdit_icon('house'); ?> <?php echo $L->get('Back to home'); ?></a>
|
||||
<a class="btn-primary-gradient error-home" href="<?php echo Theme::siteUrl(); ?>"><?php echo blowfish_icon('house'); ?> <?php echo $L->get('Back to home'); ?></a>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<!-- Cover image -->
|
||||
<?php if ($page->coverImage()): ?>
|
||||
<div class="cover-image-wrapper">
|
||||
<img class="card-img-top" alt="<?php echo blowdit_text($page->title()); ?>" src="<?php echo $page->coverImage(); ?>" fetchpriority="high" decoding="async"/>
|
||||
<img class="card-img-top" alt="<?php echo blowfish_text($page->title()); ?>" src="<?php echo $page->coverImage(); ?>" fetchpriority="high" decoding="async"/>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
@@ -36,21 +36,21 @@
|
||||
<a href="<?php echo Theme::siteUrl(); ?>"><?php echo $L->get('Home'); ?></a>
|
||||
<?php if ($page->categoryKey()) : ?>
|
||||
<span class="breadcrumb-sep" aria-hidden="true">›</span>
|
||||
<a href="<?php echo $page->categoryPermalink(); ?>"><?php echo blowdit_text($page->category()); ?></a>
|
||||
<a href="<?php echo $page->categoryPermalink(); ?>"><?php echo blowfish_text($page->category()); ?></a>
|
||||
<?php endif ?>
|
||||
<span class="breadcrumb-sep" aria-hidden="true">›</span>
|
||||
<span class="breadcrumb-current" aria-current="page"><?php echo blowdit_text($page->title()); ?></span>
|
||||
<span class="breadcrumb-current" aria-current="page"><?php echo blowfish_text($page->title()); ?></span>
|
||||
</nav>
|
||||
<?php endif ?>
|
||||
|
||||
<!-- Title -->
|
||||
<h1 class="title"><?php echo blowdit_text($page->title()); ?></h1>
|
||||
<h1 class="title"><?php echo blowfish_text($page->title()); ?></h1>
|
||||
|
||||
<?php if (!$page->isStatic() && !$url->notFound()): ?>
|
||||
<!-- Creation date and reading time -->
|
||||
<div class="metadata mb-4">
|
||||
<span><?php echo blowdit_icon('calendar'); ?><?php echo $page->date(); ?></span>
|
||||
<span><?php echo blowdit_icon('clock'); ?><?php echo $L->get('Reading time') . ': ' . $page->readingTime() ?></span>
|
||||
<span><?php echo blowfish_icon('calendar'); ?><?php echo $page->date(); ?></span>
|
||||
<span><?php echo blowfish_icon('clock'); ?><?php echo $L->get('Reading time') . ': ' . $page->readingTime() ?></span>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
@@ -79,16 +79,16 @@
|
||||
}
|
||||
} catch (\Throwable $e) { $bdSeriesPosts = array(); }
|
||||
}
|
||||
$bdSeriesLabel = trim(preg_replace('/^series\s*[:\-_]?\s*/i', '', blowdit_plain($bdSeriesName)));
|
||||
$bdSeriesLabel = trim(preg_replace('/^series\s*[:\-_]?\s*/i', '', blowfish_plain($bdSeriesName)));
|
||||
?>
|
||||
<?php if (count($bdSeriesPosts) > 1) : ?>
|
||||
<aside class="series-box">
|
||||
<div class="series-box-title"><?php echo blowdit_icon('folder'); ?><span><?php echo $L->get('Part of a series'); ?><?php echo $bdSeriesLabel !== '' ? ': ' . htmlspecialchars($bdSeriesLabel, ENT_QUOTES, 'UTF-8') : ''; ?></span></div>
|
||||
<div class="series-box-title"><?php echo blowfish_icon('folder'); ?><span><?php echo $L->get('Part of a series'); ?><?php echo $bdSeriesLabel !== '' ? ': ' . htmlspecialchars($bdSeriesLabel, ENT_QUOTES, 'UTF-8') : ''; ?></span></div>
|
||||
<ol class="series-list">
|
||||
<?php foreach ($bdSeriesPosts as $bdSp) : $bdIsCur = ($bdSp->key() === $page->key()); ?>
|
||||
<li class="series-item<?php echo $bdIsCur ? ' is-current' : ''; ?>">
|
||||
<?php if ($bdIsCur) : ?><span><?php echo blowdit_text($bdSp->title()); ?></span>
|
||||
<?php else : ?><a href="<?php echo $bdSp->permalink(); ?>"><?php echo blowdit_text($bdSp->title()); ?></a><?php endif ?>
|
||||
<?php if ($bdIsCur) : ?><span><?php echo blowfish_text($bdSp->title()); ?></span>
|
||||
<?php else : ?><a href="<?php echo $bdSp->permalink(); ?>"><?php echo blowfish_text($bdSp->title()); ?></a><?php endif ?>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ol>
|
||||
@@ -116,24 +116,24 @@
|
||||
<div class="post-taxonomy mt-4">
|
||||
<?php if ($categoryKey) : ?>
|
||||
<a class="taxonomy-badge" href="<?php echo $page->categoryPermalink(); ?>">
|
||||
<?php echo blowdit_icon('folder'); ?><?php echo blowdit_text($page->category()); ?>
|
||||
<?php echo blowfish_icon('folder'); ?><?php echo blowfish_text($page->category()); ?>
|
||||
</a>
|
||||
<?php endif ?>
|
||||
<?php foreach ($tagsList as $tagKey => $tagName) : ?>
|
||||
<a class="taxonomy-badge" href="<?php echo DOMAIN_TAGS . $tagKey; ?>"><?php echo blowdit_icon('tag'); ?><?php echo blowdit_text($tagName); ?></a>
|
||||
<a class="taxonomy-badge" href="<?php echo DOMAIN_TAGS . $tagKey; ?>"><?php echo blowfish_icon('tag'); ?><?php echo blowfish_text($tagName); ?></a>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<!-- Share -->
|
||||
<?php if (!$page->isStatic() && !$url->notFound()) : ?>
|
||||
<?php $bdShareUrl = $page->permalink(true); $bdShareTitle = blowdit_plain($page->title()); ?>
|
||||
<?php $bdShareUrl = $page->permalink(true); $bdShareTitle = blowfish_plain($page->title()); ?>
|
||||
<div class="post-share mt-4">
|
||||
<span class="post-share-label"><?php echo $L->get('Share'); ?></span>
|
||||
<a class="post-share-btn" href="https://twitter.com/intent/tweet?url=<?php echo rawurlencode($bdShareUrl); ?>&text=<?php echo rawurlencode($bdShareTitle); ?>" target="_blank" rel="noopener" aria-label="<?php echo $L->get('Share on X (Twitter)'); ?>">X (Twitter)</a>
|
||||
<a class="post-share-btn" href="https://www.reddit.com/submit?url=<?php echo rawurlencode($bdShareUrl); ?>&title=<?php echo rawurlencode($bdShareTitle); ?>" target="_blank" rel="noopener" aria-label="<?php echo $L->get('Share on Reddit'); ?>">Reddit</a>
|
||||
<a class="post-share-btn" href="https://www.linkedin.com/sharing/share-offsite/?url=<?php echo rawurlencode($bdShareUrl); ?>" target="_blank" rel="noopener" aria-label="<?php echo $L->get('Share on LinkedIn'); ?>">LinkedIn</a>
|
||||
<button type="button" class="post-share-btn js-copy-link" data-url="<?php echo htmlspecialchars($bdShareUrl, ENT_QUOTES, 'UTF-8'); ?>" aria-label="<?php echo $L->get('Copy link'); ?>"><?php echo blowdit_icon('link'); ?><span class="post-share-copy-label"><?php echo $L->get('Copy link'); ?></span></button>
|
||||
<button type="button" class="post-share-btn js-copy-link" data-url="<?php echo htmlspecialchars($bdShareUrl, ENT_QUOTES, 'UTF-8'); ?>" aria-label="<?php echo $L->get('Copy link'); ?>"><?php echo blowfish_icon('link'); ?><span class="post-share-copy-label"><?php echo $L->get('Copy link'); ?></span></button>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
<?php if ($bdRp->coverImage()) : ?>
|
||||
<span class="related-cover" style="background-image:url('<?php echo htmlspecialchars($bdRp->coverImage(), ENT_QUOTES, 'UTF-8'); ?>')"></span>
|
||||
<?php endif ?>
|
||||
<span class="related-card-title"><?php echo blowdit_text($bdRp->title()); ?></span>
|
||||
<span class="related-card-title"><?php echo blowfish_text($bdRp->title()); ?></span>
|
||||
</a>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
||||
+3
-3
@@ -10,16 +10,16 @@
|
||||
<span class="sidebar-author-label">Author</span>
|
||||
<div class="sidebar-author-identity">
|
||||
<a href="<?php echo Theme::siteUrl() ?>">
|
||||
<img class="sidebar-author-avatar" src="<?php echo DOMAIN_THEME . 'img/spleenftw.jpeg' ?>" alt="<?php echo blowdit_text($page->username()) ?>" />
|
||||
<img class="sidebar-author-avatar" src="<?php echo DOMAIN_THEME . 'img/spleenftw.jpeg' ?>" alt="<?php echo blowfish_text($page->username()) ?>" />
|
||||
</a>
|
||||
<div class="sidebar-author-name"><?php echo blowdit_text($page->username()) ?></div>
|
||||
<div class="sidebar-author-name"><?php echo blowfish_text($page->username()) ?></div>
|
||||
<?php
|
||||
// Bio: set in Bludit Admin → Settings → General → Description
|
||||
// Falls back to Slogan if Description is empty.
|
||||
$_authorBio = $site->description() ?: $site->slogan();
|
||||
?>
|
||||
<?php if ($_authorBio) : ?>
|
||||
<p class="sidebar-author-bio"><?php echo blowdit_text($_authorBio) ?></p>
|
||||
<p class="sidebar-author-bio"><?php echo blowfish_text($_authorBio) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user