sized to 1em so existing
* 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.
*/
if (!function_exists('blowdit_icon')) {
function blowdit_icon($name) {
static $paths = array(
// --- UI ---
'calendar' => '',
'clock' => '',
'folder' => '',
'tag' => '',
'chevron-left' => '',
'chevron-right' => '',
'house' => '',
'link' => '',
'search' => '',
'share' => '',
// --- Theme picker (mirror in blowdit.js) ---
'sun' => '',
'moon' => '',
'snow' => '',
'droplet' => '',
'cup' => '',
'half' => '',
);
if (!isset($paths[$name])) { return ''; }
return '';
}
// 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);
return DOMAIN_THEME . $rel . ($v ? '?v=' . $v : '');
}
// Map a theme key to its toggle icon name.
function blowdit_theme_icon($theme) {
$map = array(
'light' => 'sun',
'dark' => 'moon',
'nord' => 'snow',
'dracula' => 'droplet',
'catppuccin' => 'cup',
);
return isset($map[$theme]) ? $map[$theme] : 'half';
}
}