- title(), ENT_QUOTES, 'UTF-8'); ?>
+ title()); ?>
date(); ?>
@@ -69,11 +69,11 @@
diff --git a/php/icons.php b/php/icons.php
index d9c7b37..027fded 100644
--- a/php/icons.php
+++ b/php/icons.php
@@ -34,6 +34,18 @@ if (!function_exists('blowdit_icon')) {
. 'stroke-linejoin="round" aria-hidden="true">' . $paths[$name] . '';
}
+ // Bludit already HTML-escapes titles/names on save (Sanitize::html), so a
+ // plain htmlspecialchars() in the theme double-encodes ("&" -> "&",
+ // shown as "&"). 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);
diff --git a/php/navbar.php b/php/navbar.php
index 26d020c..4b6c9ad 100644
--- a/php/navbar.php
+++ b/php/navbar.php
@@ -1,7 +1,7 @@