From 34c1c18f1b661d95586b4072803287aa01acd6e2 Mon Sep 17 00:00:00 2001 From: spleenftw Date: Thu, 4 Jun 2026 11:10:41 +0200 Subject: [PATCH 1/2] Renamed blowdit to bludit-blowfish / blowfish --- README.md | 105 +++++++++++++++++---------------- css/style.css | 4 +- index.php | 50 ++++++++-------- js/{blowdit.js => blowfish.js} | 24 ++++---- languages/de_CH.json | 4 +- languages/de_DE.json | 4 +- languages/en.json | 4 +- languages/es.json | 4 +- languages/fa_IR.json | 4 +- languages/it.json | 4 +- languages/ja_JP.json | 4 +- languages/nl_NL.json | 4 +- languages/ru_RU.json | 4 +- languages/tr_TR.json | 4 +- manifest.webmanifest | 4 +- metadata.json | 2 +- php/footer.php | 12 ++-- php/head.php | 90 ++++++++++++++-------------- php/home.php | 36 +++++------ php/icons.php | 24 ++++---- php/navbar.php | 26 ++++---- php/page.php | 34 +++++------ php/sidebar.php | 8 +-- 23 files changed, 232 insertions(+), 227 deletions(-) rename js/{blowdit.js => blowfish.js} (98%) diff --git a/README.md b/README.md index 78107d5..12ef7a1 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,93 @@ -# Blowdit +# Blowfish A clean, minimal theme for [Bludit](https://www.bludit.com) inspired by the [Blowfish](https://blowfish.page/) Hugo theme. -![Bludit](https://img.shields.io/badge/Bludit-3.9+-informational) ![License](https://img.shields.io/badge/license-MIT-green) ![Version](https://img.shields.io/badge/version-1.6.0-blue) +![Bludit](https://img.shields.io/badge/Bludit-3.22+-informational) ![License](https://img.shields.io/badge/license-MIT-green) ![Version](https://img.shields.io/badge/version-1.6.0-blue) ## Features -- 🎨 **Five-theme swatch picker** — click the theme button to open a dropdown with coloured swatches for Light, Dark, Nord, Dracula and Catppuccin. Choice persists via `localStorage` + cookie (no flash on next load); falls back to OS preference. -- 🧱 **Monochrome base design** — restrained grayscale palette with crisp Inter typography. -- 👤 **Profile hero** — circular avatar, site title, slogan and social links on the homepage front page. -- 📖 **Sticky Table of Contents** — articles that contain headings (`h2`/`h3`/`h4`) get a left sidebar ToC that sticks while scrolling and highlights the active section. Layout automatically switches to 3-column with a wider container. -- 📚 **Smart right sidebar** — shows only About / Categories / Hit Counter on the homepage (navigation is redundant there); shows the full plugin set on article pages. -- 🔀 **Randomized navigation** — the Navigation/Pages plugin list is shuffled on each load. -- ⏱️ **Reading time & dates** shown on the post list and single posts. -- 🔗 **Social icons** in the navbar and hero (SVG files in `img/`). -- 🏷️ **Tags & categories** rendered as pill badges. -- 🖼️ **Image lightbox** — clicking any article image opens it full-screen. A dark overlay with a magnifier icon appears on hover to hint at the interaction. Closes on click or Esc. -- 🎠 **Image carousel** — use a ` ```carousel ` fenced block, one image per line (markdown image syntax or plain URL). -- 📑 **Tabbed code blocks** — use a ` ```tabs ` fenced block with `[Tab Name]` or `@tab Name` headers to show content from multiple servers/environments side by side. -- 📜 **Code block scrollbar** — always-visible horizontal scrollbar on `
` blocks with a custom slim style that respects the active theme.
-- 📱 Fully responsive; no flash of the wrong theme on load.
+- **Five-theme swatch picker** — Light, Dark, Nord, Dracula, Catppuccin. Choice persists via `localStorage` + cookie (no flash on next load); falls back to OS preference.
+- **Monochrome base design** — restrained grayscale palette with crisp Inter typography (self-hosted, no Google Fonts).
+- **Profile hero** — circular avatar, site title, slogan and social links on the homepage.
+- **Sticky Table of Contents** — articles with `h2`/`h3`/`h4` headings get a left sidebar ToC that sticks while scrolling and highlights the active section. Layout switches to 3-column with a wider container. A floating button opens a drawer on mobile.
+- **Smart right sidebar** — shows only About / Categories / Hit Counter on the homepage; full plugin set on article pages.
+- **Client-side search overlay** — `/` key or navbar button; searches titles, descriptions and tags client-side.
+- **Keyboard shortcuts** — `/` (search), `g h` (go home), `t` (back to top), `Esc` (close overlay).
+- **Randomized navigation** — the Navigation/Pages plugin list is shuffled on every load.
+- **Reading time & dates** shown on the post list and single posts.
+- **Social icons** in the navbar and hero (SVG files in `img/`).
+- **Tags & categories** rendered as pill badges.
+- **Image lightbox** — clicking any article image opens it full-screen with a dark overlay and zoom hint.
+- **Image carousel** — ` ```carousel ` fenced block, one image per line (markdown syntax or bare URL with optional `| caption`).
+- **Tabbed code blocks** — ` ```tabs ` fenced block with `[Tab Name]` or `@tab Name` headers.
+- **Code block header bar** — language label + copy-to-clipboard button on every code block.
+- **Callout/admonition boxes** — `> [!NOTE]`, `> [!TIP]`, `> [!WARNING]`, `> [!DANGER]`, `> [!IMPORTANT]`.
+- **Series navigation** — posts tagged `series-*` display an ordered series box.
+- **SEO** — Open Graph, Twitter Card, JSON-LD (WebSite, Article, BreadcrumbList, sameAs), canonical URL, theme-color meta, cover-image preload.
+- **Accessibility** — skip link, ARIA labels, `:focus-visible`, heading anchor links, print stylesheet.
+- **PWA** — web app manifest included.
+- Fully responsive; no jQuery, no Bootstrap JS, no webfont requests.
 
 ## Installation
 
-1. Download or clone this repository into your Bludit `bl-themes` directory:
+1. Clone or copy this repository into your Bludit `bl-themes/` directory:
 
    ```
-   /usr/share/nginx/html/bl-themes/
+   bl-themes/bludit-blowfish/
    ```
 
-2. In the Bludit admin panel go to **Settings → Themes** and activate **Blowdit**.
+2. In the Bludit admin panel go to **Settings → Themes** and activate **Blowfish**.
 
-3. Add your assets to `blowdit/img/`:
-   - Your avatar as `spleenftw.jpeg` — used in the homepage hero and the article sidebar compact card.
+3. Add your assets to `img/`:
+   - Your avatar as `spleenftw.jpeg` — used in the homepage hero and the article sidebar card.  
      To change the filename, update `php/sidebar.php` and `php/home.php`.
 
 ## Layout
 
 ```
-blowdit/
-├── index.php          Main template (layout, all inline JS)
+bludit-blowfish/
+├── index.php          Main template (layout, sidebar logic, JS config)
 ├── metadata.json      Theme metadata
+├── manifest.webmanifest
 ├── css/
 │   └── style.css      All styles (CSS custom properties, 5 themes)
+├── js/
+│   └── blowfish.js    Deferred JS bundle (ToC, lightbox, carousel, search, …)
 ├── php/
 │   ├── head.php       , fonts, favicon, anti-FOUC theme script
-│   ├── navbar.php     Navbar, social SVG icons, theme-picker dropdown
+│   ├── navbar.php     Navbar, social icons, theme-picker dropdown
 │   ├── home.php       Profile hero + post listing
-│   ├── page.php       Single page / post
+│   ├── page.php       Single page/post
 │   ├── sidebar.php    Right sidebar plugin container
 │   ├── toc.php        Left ToC sidebar (article pages with headings)
-│   └── footer.php     Footer
+│   ├── footer.php     Footer + search-index JSON
+│   └── icons.php      Inline-SVG icon helper + shared PHP functions
 ├── img/               Social SVG icons + avatar
 └── languages/         Translations (10 languages)
 ```
 
 ## Themes
 
-Each theme is a set of CSS custom properties. Light lives in `:root`; the others
-override it under `[data-theme="dark"]`, `[data-theme="nord"]`,
-`[data-theme="dracula"]` and `[data-theme="catppuccin"]`.
+Each colour theme is a block of CSS custom properties. Light lives in `:root`; the others override it under `[data-theme="dark"]`, `[data-theme="nord"]`, `[data-theme="dracula"]` and `[data-theme="catppuccin"]`.
 
-The attribute is set on `` before the first paint (in `php/head.php`) to
-avoid a flash. The navbar swatch picker updates it at runtime and persists the
-choice to both `localStorage` and a cookie.
+The `data-theme` attribute is set on `` before the first paint (in `php/head.php`) to avoid a flash. The navbar swatch picker updates it at runtime and persists the choice to `localStorage` and a cookie.
 
-To add a new theme, add a variable block in `css/style.css` and add the theme
-name + swatch colours to the picker in `php/navbar.php` and the `THEMES` array
-in `index.php`.
+To add a new theme: add a variable block in `css/style.css`, register the theme name + background colour in `index.php` (`$blowfishThemeBg`), and add a swatch entry in `php/navbar.php`.
 
 ## Table of Contents
 
-When an article's rendered HTML contains any `h2`, `h3` or `h4` headings, the
-layout automatically switches from 2-column to 3-column:
+When an article's rendered HTML contains any `h2`, `h3` or `h4` headings, the layout automatically switches from 2-column to 3-column:
 
 ```
 [ Left ToC (col-md-3) ] [ Article (col-md-6) ] [ Right sidebar (col-md-3) ]
 ```
 
-The ToC is hidden on mobile. The left column has no `align-self-start` so it
-stretches to the full article height, which is what `position: sticky` needs to
-function. The container switches to `.container-wide` (1400 px max-width) and
-the navbar inner container widens to match via `body.has-toc .navbar .container`.
+The sidebar ToC is hidden on mobile; a floating button opens a slide-up drawer instead. The container switches to `.container-wide` (1400 px max-width) and the navbar widens to match via `body.has-toc .navbar .container`.
 
 ## Tabbed code blocks
 
-Use a ` ```tabs ` fenced block. Delimit tabs with `[Tab Name]` (brackets) or
-`@tab Tab Name` (@ prefix):
+Use a ` ```tabs ` fenced block. Delimit tabs with `[Tab Name]` (brackets) or `@tab Tab Name` (@ prefix):
 
 ````
 ```tabs
@@ -101,8 +101,7 @@ root@pgs02:~# psql -c "SELECT …"
 
 ## Image carousel
 
-Use a ` ```carousel ` fenced block. Each non-empty line is one slide. Accepts
-standard markdown image syntax or a bare URL with an optional `| caption`:
+Use a ` ```carousel ` fenced block. Each non-empty line is one slide. Accepts standard markdown image syntax or a bare URL with an optional `| caption`:
 
 ````
 ```carousel
@@ -111,13 +110,19 @@ standard markdown image syntax or a bare URL with an optional `| caption`:
 ```
 ````
 
-Use `![]()` (empty alt) to show no caption. Supports swipe on touch devices.
+Supports swipe on touch devices.
 
-## Randomized navigation
+## Callout boxes
 
-If the **Navigation** (or **Pages**) plugin is in the sidebar, its list is
-shuffled on every page load. The plugin output is wrapped in `.js-random-nav`;
-adjust the detection in `index.php` if your plugin uses a different class.
+```markdown
+> [!NOTE]
+> Useful information.
+
+> [!WARNING]
+> Something to watch out for.
+```
+
+Supported types: `NOTE`, `TIP`, `WARNING`, `DANGER`, `IMPORTANT`.
 
 ## License
 
diff --git a/css/style.css b/css/style.css
index b439c36..48ac9a4 100644
--- a/css/style.css
+++ b/css/style.css
@@ -1,5 +1,5 @@
-/* ========================================
-   BLOWDIT — a Bludit theme inspired by Blowfish
+/* ========================================
+   BLOWFISH — a Bludit theme inspired by Blowfish
    Monochrome palette with light & dark modes
    ======================================== */
 
diff --git a/index.php b/index.php
index 84f6ea6..2878cfe 100644
--- a/index.php
+++ b/index.php
@@ -1,54 +1,54 @@
- Advanced ->
-	// Email account settings). Leave it to auto-detect, or hard-set $blowditEmail
+	// Email account settings). Leave it to auto-detect, or hard-set $blowfishEmail
 	// below to override. Empty -> the icon is hidden.
-	$blowditEmail = '';
+	$blowfishEmail = '';
 	if (isset($site)) {
 		// Try Bludit's site settings (accessor is getValue(); getField() as backup).
 		$bdGet = method_exists($site, 'getValue') ? 'getValue'
 		       : (method_exists($site, 'getField') ? 'getField' : null);
 		if ($bdGet) {
-			$blowditEmail = $site->$bdGet('emailFromAddress');     // Bludit's "Sender email"
-			if (empty($blowditEmail)) { $blowditEmail = $site->$bdGet('email'); }
+			$blowfishEmail = $site->$bdGet('emailFromAddress');     // Bludit's "Sender email"
+			if (empty($blowfishEmail)) { $blowfishEmail = $site->$bdGet('email'); }
 		}
 	}
 	// Bludit's sender email isn't always exposed to themes (it's an SMTP/plugin
 	// setting), so fall back to a fixed address. Set to '' to hide the icon.
-	if (empty($blowditEmail)) { $blowditEmail = 'contact@interlope.xyz'; }
-	$blowditTwitterHandle = '@spleenftw'; // twitter:site / twitter:creator; '' to omit
+	if (empty($blowfishEmail)) { $blowfishEmail = 'contact@interlope.xyz'; }
+	$blowfishTwitterHandle = '@spleenftw'; // twitter:site / twitter:creator; '' to omit
 
 	// Read the theme from a cookie so the root element can be rendered
 	// pre-coloured. This paints the page in the theme colour from the first
 	// byte of every response, eliminating the white flash between navigations.
-	$blowditThemeBg = array(
+	$blowfishThemeBg = array(
 		'light'      => '#ffffff',
 		'dark'       => '#171717',
 		'nord'       => '#2e3440',
 		'dracula'    => '#282a36',
 		'catppuccin' => '#1e1e2e',
 	);
-	$blowditTheme = (isset($_COOKIE['blowdit-theme']) && isset($blowditThemeBg[$_COOKIE['blowdit-theme']]))
-		? $_COOKIE['blowdit-theme']
+	$blowfishTheme = (isset($_COOKIE['blowfish-theme']) && isset($blowfishThemeBg[$_COOKIE['blowfish-theme']]))
+		? $_COOKIE['blowfish-theme']
 		: 'light';
-	$blowditBg     = $blowditThemeBg[$blowditTheme];
-	$blowditScheme = ($blowditTheme === 'light') ? 'light' : 'dark';
+	$blowfishBg     = $blowfishThemeBg[$blowfishTheme];
+	$blowfishScheme = ($blowfishTheme === 'light') ? 'light' : 'dark';
 
 	// Pre-compute before  so we can stamp the has-toc class on it,
 	// which lets CSS align the navbar container with the wider article container.
-	$blowditIsArticle  = ($WHERE_AM_I === 'page' && isset($page) && !$page->isStatic() && !$url->notFound());
-	$blowditHasHeadings = $blowditIsArticle && (bool) preg_match('/content());
+	$blowfishIsArticle  = ($WHERE_AM_I === 'page' && isset($page) && !$page->isStatic() && !$url->notFound());
+	$blowfishHasHeadings = $blowfishIsArticle && (bool) preg_match('/content());
 ?>
 
-
+
 
 
 
->
+>
 
 	
 	
@@ -126,8 +126,8 @@
 		// The hero (and the relocated search) appear on every paginated home page.
 		$heroVisible   = ($WHERE_AM_I === 'home');
 		// Reuse the values pre-computed before  (avoids calling $page->content() twice).
-		$isArticlePage = $blowditIsArticle;
-		$hasHeadings   = $blowditHasHeadings;
+		$isArticlePage = $blowfishIsArticle;
+		$hasHeadings   = $blowfishHasHeadings;
 	?>
 
 	
@@ -179,7 +179,7 @@
 		// jQuery and Bootstrap's JS bundle are intentionally NOT loaded: every
 		// interactive piece in this theme is vanilla JS (theme picker, tabs,
 		// carousel, lightbox), and the only Bootstrap-JS feature used — the
-		// mobile navbar collapse — is reimplemented in blowdit.js. This drops
+		// mobile navbar collapse — is reimplemented in blowfish.js. This drops
 		// ~115 KB. Re-add Theme::jquery() / Theme::jsBootstrap() here if you
 		// install a plugin that depends on them.
 	?>
@@ -190,11 +190,11 @@
 	
 	
 	
 
diff --git a/js/blowdit.js b/js/blowfish.js
similarity index 98%
rename from js/blowdit.js
rename to js/blowfish.js
index 3e2d05d..5ba0405 100644
--- a/js/blowdit.js
+++ b/js/blowfish.js
@@ -1,5 +1,5 @@
-/* ============================================================
-   BLOWDIT — theme behaviour
+/* ============================================================
+   BLOWFISH — theme behaviour
    Deferred, cacheable bundle of all client-side enhancements.
    Loaded with ';
 	} catch (\Throwable $e) {}
diff --git a/php/head.php b/php/head.php
index 9a4adfa..f2e7589 100644
--- a/php/head.php
+++ b/php/head.php
@@ -1,27 +1,27 @@
-
+
 
 
 
 
  '#1f1f1f',
 		'dark'       => '#1f1f1f',
 		'nord'       => '#3b4252',
 		'dracula'    => '#343746',
 		'catppuccin' => '#313244',
 	);
-	$blowditChrome = isset($blowditChromeColors[$blowditTheme]) ? $blowditChromeColors[$blowditTheme] : '#1f1f1f';
+	$blowfishChrome = isset($blowfishChromeColors[$blowfishTheme]) ? $blowfishChromeColors[$blowfishTheme] : '#1f1f1f';
 ?>
-
+
 
-coverImage()): ?>
+coverImage()): ?>
 
 
 
 
-
+
 
 
 
@@ -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. -->
 
@@ -64,13 +64,13 @@
 
 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 @@
 
 
 
-
-
-
+
+
+
 
 
-
+
 
 
 
-
+
 
 
 
-
-
-
+
+
+
 
-
-
+
+
 
-
+
 
 '
 			. json_encode($doc, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
 			. '' . "\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 @@
 ?>
 
 
-
+
 
 
 
@@ -252,7 +252,7 @@
 
 
 
+     (see php/icons.php + blowfish.js), saving ~120 KB font + ~80 KB CSS. -->
 
 
 
 
   
- <?php echo blowdit_text($site->title()); ?> -

title()); ?>

+ <?php echo blowfish_text($site->title()); ?> +

title()); ?>

slogan()) : ?> -

slogan()); ?>

+

slogan()); ?>

description()) : ?> -

description()); ?>

+

description()); ?>

@@ -59,12 +59,12 @@
-

title()); ?>

+

title()); ?>

- date(); ?> + date(); ?> isStatic()) : ?> - readingTime(); ?> + readingTime(); ?>
@@ -75,11 +75,11 @@
- category()); ?> + category()); ?> $tagName) : ?> - +
@@ -120,7 +120,7 @@
  • - +
  • @@ -140,7 +140,7 @@
  • - +
  • diff --git a/php/icons.php b/php/icons.php index f18cbb3..3dde0a3 100644 --- a/php/icons.php +++ b/php/icons.php @@ -1,4 +1,4 @@ - '', @@ -23,7 +23,7 @@ if (!function_exists('blowdit_icon')) { 'link' => '', 'search' => '', 'share' => '', - // --- Theme picker (mirror in blowdit.js) --- + // --- Theme picker (mirror in blowfish.js) --- 'sun' => '', 'moon' => '', 'snow' => '', @@ -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', diff --git a/php/navbar.php b/php/navbar.php index ead0ff4..0e2cb3f 100644 --- a/php/navbar.php +++ b/php/navbar.php @@ -1,7 +1,7 @@ -