feat: replace htmlspecialchars with blowdit_text for improved text handling across multiple templates

This commit is contained in:
interlope committed 2026-06-02 12:26:08 +02:00
1 parent 3050c618a4
commit 7ef88cbe06
6 files changed
+44 -32

No files matched your search

+11 -11
View File
@@ -95,19 +95,19 @@
?>
<!-- Open Graph -->
<meta property="og:type" content="<?php echo htmlspecialchars($ogType, ENT_QUOTES, 'UTF-8'); ?>">
<meta property="og:site_name" content="<?php echo htmlspecialchars($ogSiteName, ENT_QUOTES, 'UTF-8'); ?>">
<meta property="og:title" content="<?php echo htmlspecialchars($ogTitle, ENT_QUOTES, 'UTF-8'); ?>">
<meta property="og:description" content="<?php echo htmlspecialchars($ogDesc, 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:url" content="<?php echo htmlspecialchars($ogUrl, ENT_QUOTES, 'UTF-8'); ?>">
<meta property="og:image" content="<?php echo htmlspecialchars($ogImage, 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 htmlspecialchars($page->username(), ENT_QUOTES, 'UTF-8'); ?>">
<meta property="article:author" content="<?php echo blowdit_text($page->username()); ?>">
<?php endif ?>
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="<?php echo htmlspecialchars($ogTitle, ENT_QUOTES, 'UTF-8'); ?>">
<meta name="twitter:description" content="<?php echo htmlspecialchars($ogDesc, ENT_QUOTES, 'UTF-8'); ?>">
<meta name="twitter:title" content="<?php echo blowdit_text($ogTitle); ?>">
<meta name="twitter:description" content="<?php echo blowdit_text($ogDesc); ?>">
<meta name="twitter:image" content="<?php echo htmlspecialchars($ogImage, ENT_QUOTES, 'UTF-8'); ?>">
<?php
@@ -130,19 +130,19 @@
$jsonLd = array(
'@context' => 'https://schema.org',
'@type' => 'BlogPosting',
'headline' => $page->title(),
'description' => $ldDescription,
'headline' => blowdit_plain($page->title()),
'description' => blowdit_plain($ldDescription),
'image' => $ldImage,
'datePublished' => $ldPublished,
'dateModified' => $ldModified,
'author' => array(
'@type' => 'Person',
'name' => $page->username(),
'name' => blowdit_plain($page->username()),
'url' => Theme::siteUrl(),
),
'publisher' => array(
'@type' => 'Organization',
'name' => $site->title(),
'name' => blowdit_plain($site->title()),
'logo' => array(
'@type' => 'ImageObject',
'url' => DOMAIN_THEME . 'img/favicon.png',
@@ -163,7 +163,7 @@
?>
<!-- RSS feed auto-discovery (RSS plugin serves /rss.xml) -->
<link rel="alternate" type="application/rss+xml" title="<?php echo htmlspecialchars($site->title(), ENT_QUOTES, 'UTF-8'); ?>" href="<?php echo rtrim(Theme::siteUrl(), '/') . '/rss.xml'; ?>">
<link rel="alternate" type="application/rss+xml" title="<?php echo blowdit_text($site->title()); ?>" href="<?php echo rtrim(Theme::siteUrl(), '/') . '/rss.xml'; ?>">
<!-- Include Favicon -->
<?php echo Theme::favicon('img/favicon.png'); ?>
+9 -9
View File
@@ -7,19 +7,19 @@
?>
<?php if ($showProfile) : ?>
<header class="profile text-center">
<img class="profile-avatar" src="<?php echo $profileImage; ?>" alt="<?php echo htmlspecialchars($site->title(), ENT_QUOTES, 'UTF-8'); ?>" />
<h1 class="profile-name"><?php echo htmlspecialchars($site->title(), ENT_QUOTES, 'UTF-8'); ?></h1>
<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>
<?php if ($site->slogan()) : ?>
<p class="profile-bio"><?php echo htmlspecialchars($site->slogan(), ENT_QUOTES, 'UTF-8'); ?></p>
<p class="profile-bio"><?php echo blowdit_text($site->slogan()); ?></p>
<?php elseif ($site->description()) : ?>
<p class="profile-bio"><?php echo htmlspecialchars($site->description(), ENT_QUOTES, 'UTF-8'); ?></p>
<p class="profile-bio"><?php echo blowdit_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 htmlspecialchars($label, ENT_QUOTES, 'UTF-8') ?>">
<img class="profile-social-icon" src="<?php echo blowdit_asset('img/' . $key . '.svg') ?>" alt="<?php echo htmlspecialchars($label, ENT_QUOTES, 'UTF-8') ?>" />
<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>
<?php endforeach ?>
<!-- RSS feed (served by the RSS plugin at /rss.xml) -->
@@ -53,7 +53,7 @@
<div class="post-list-head">
<a href="<?php echo $page->permalink(); ?>">
<h2 class="post-list-title"><?php echo htmlspecialchars($page->title(), ENT_QUOTES, 'UTF-8'); ?></h2>
<h2 class="post-list-title"><?php echo blowdit_text($page->title()); ?></h2>
</a>
<div class="post-list-meta">
<span><?php echo blowdit_icon('calendar'); ?><?php echo $page->date(); ?></span>
@@ -69,11 +69,11 @@
<div class="post-taxonomy">
<?php if ($categoryKey) : ?>
<a class="taxonomy-badge" href="<?php echo $page->categoryPermalink(); ?>">
<?php echo blowdit_icon('folder'); ?><?php echo htmlspecialchars($page->category(), ENT_QUOTES, 'UTF-8'); ?>
<?php echo blowdit_icon('folder'); ?><?php echo blowdit_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 htmlspecialchars($tagName, ENT_QUOTES, 'UTF-8'); ?></a>
<a class="taxonomy-badge" href="<?php echo DOMAIN_TAGS . $tagKey; ?>"><?php echo blowdit_icon('tag'); ?><?php echo blowdit_text($tagName); ?></a>
<?php endforeach ?>
</div>
<?php endif ?>
+12
View File
@@ -34,6 +34,18 @@ if (!function_exists('blowdit_icon')) {
. 'stroke-linejoin="round" aria-hidden="true">' . $paths[$name] . '</svg>';
}
// Bludit already HTML-escapes titles/names on save (Sanitize::html), so a
// plain htmlspecialchars() in the theme double-encodes ("&" -> "&amp;amp;",
// shown as "&amp;"). blowdit_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) {
return html_entity_decode((string) $s, ENT_QUOTES, 'UTF-8');
}
function blowdit_text($s) {
return htmlspecialchars(blowdit_plain($s), ENT_QUOTES, 'UTF-8');
}
// Theme asset URL with an mtime cache-buster (so edited images/SVGs refetch).
function blowdit_asset($rel) {
$v = @filemtime(THEME_DIR . $rel);
+5 -5
View File
@@ -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 htmlspecialchars($site->title(), ENT_QUOTES, 'UTF-8') ?></span>
<span class="text-white"><?php echo blowdit_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 htmlspecialchars($staticPage->title(), ENT_QUOTES, 'UTF-8') ?></a>
<a class="nav-link<?php echo ($url->slug() == $staticPage->slug()) ? ' active' : '' ?>" href="<?php echo $staticPage->permalink() ?>"><?php echo blowdit_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 htmlspecialchars($label, ENT_QUOTES, 'UTF-8') ?>">
<img class="d-none d-md-block nav-svg-icon" src="<?php echo blowdit_asset('img/' . $key . '.svg') ?>" alt="<?php echo htmlspecialchars($label, ENT_QUOTES, 'UTF-8') ?>" />
<span class="d-inline d-md-none"><?php echo htmlspecialchars($label, ENT_QUOTES, 'UTF-8'); ?></span>
<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>
</li>
<?php endforeach; ?>
+4 -4
View File
@@ -7,13 +7,13 @@
<!-- Cover image -->
<?php if ($page->coverImage()): ?>
<div class="cover-image-wrapper">
<img class="card-img-top" alt="<?php echo htmlspecialchars($page->title(), ENT_QUOTES, 'UTF-8'); ?>" src="<?php echo $page->coverImage(); ?>" fetchpriority="high" decoding="async"/>
<img class="card-img-top" alt="<?php echo blowdit_text($page->title()); ?>" src="<?php echo $page->coverImage(); ?>" fetchpriority="high" decoding="async"/>
</div>
<?php endif ?>
<div class="card-body">
<!-- Title -->
<h1 class="title"><?php echo htmlspecialchars($page->title(), ENT_QUOTES, 'UTF-8'); ?></h1>
<h1 class="title"><?php echo blowdit_text($page->title()); ?></h1>
<?php if (!$page->isStatic() && !$url->notFound()): ?>
<!-- Creation date, reading time and author -->
@@ -43,11 +43,11 @@
<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 htmlspecialchars($page->category(), ENT_QUOTES, 'UTF-8'); ?>
<?php echo blowdit_icon('folder'); ?><?php echo blowdit_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 htmlspecialchars($tagName, ENT_QUOTES, 'UTF-8'); ?></a>
<a class="taxonomy-badge" href="<?php echo DOMAIN_TAGS . $tagKey; ?>"><?php echo blowdit_icon('tag'); ?><?php echo blowdit_text($tagName); ?></a>
<?php endforeach ?>
</div>
<?php endif ?>
+3 -3
View File
@@ -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 htmlspecialchars($page->username(), ENT_QUOTES, 'UTF-8') ?>" />
<img class="sidebar-author-avatar" src="<?php echo DOMAIN_THEME . 'img/spleenftw.jpeg' ?>" alt="<?php echo blowdit_text($page->username()) ?>" />
</a>
<div class="sidebar-author-name"><?php echo htmlspecialchars($page->username(), ENT_QUOTES, 'UTF-8') ?></div>
<div class="sidebar-author-name"><?php echo blowdit_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 htmlspecialchars($_authorBio, ENT_QUOTES, 'UTF-8') ?></p>
<p class="sidebar-author-bio"><?php echo blowdit_text($_authorBio) ?></p>
<?php endif ?>
</div>
</div>