From 2343999485fd93cfc30fdc3aaf986b9abbea4d83 Mon Sep 17 00:00:00 2001 From: interlope Date: Sun, 1 Nov 2026 19:36:09 +0100 Subject: [PATCH] Prevent autosave exports and preserve raw Markdown --- README.md | 3 ++- metadata.json | 2 +- plugin.php | 12 +++++++----- tests/import.php | 17 +++++++++++++++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 48346d1..e2f6c58 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,8 @@ Backups and asset mapping files remain in the workspace across plugin upgrades. ## Export -- Saving a page exports it when its auto-export setting is enabled. +- Saving a page exports it when its auto-export setting is enabled. Transient `autosave` pages and `autosave-*` keys are never exported. +- Export uses the raw page source, preserving Markdown fences and avoiding repeated rendering of code blocks. Previously exported autosave copies must be removed from repository history separately; this change does not erase existing commits. - **Export everything** exports drafts and published articles; **Export published only** exports the published selection. - Bludit upload URLs become relative `../img/` or `../files/` references. Imported asset mappings retain their original paths. - Exports include the page's actual `author` username so later imports can preserve attribution. diff --git a/metadata.json b/metadata.json index eb9d5fb..eb49ab9 100644 --- a/metadata.json +++ b/metadata.json @@ -2,7 +2,7 @@ "author": "spleenftw", "email": "", "website": "https://github.com/Spleenftw/bludit-github-sync", - "version": "1.1.2", + "version": "1.1.3", "releaseDate": "2026-11-01", "license": "MIT", "compatible": "3.22.0", diff --git a/plugin.php b/plugin.php index 1c2dfb0..fab7099 100644 --- a/plugin.php +++ b/plugin.php @@ -112,10 +112,11 @@ class pluginBluditGithub extends Plugin public function afterPageCreate($key) { try { - if ($this->importing || empty($key) || !$this->isConfigured()) { + if ($this->importing || empty($key) || strpos($key, 'autosave-') === 0 || !$this->isConfigured()) { return; } $page = new Page($key); + if ($page->getValue('type') === 'autosave') { return; } $isDraft = $page->getValue('type') === 'draft'; $shouldAutoExport = $isDraft ? $this->getValue('exportDraftsAuto') : $this->getValue('exportPublishedAuto'); @@ -130,10 +131,11 @@ class pluginBluditGithub extends Plugin public function afterPageModify($key) { try { - if ($this->importing || empty($key) || !$this->isConfigured()) { + if ($this->importing || empty($key) || strpos($key, 'autosave-') === 0 || !$this->isConfigured()) { return; } $page = new Page($key); + if ($page->getValue('type') === 'autosave') { return; } $isDraft = $page->getValue('type') === 'draft'; $shouldAutoExport = $isDraft ? $this->getValue('exportDraftsAuto') : $this->getValue('exportPublishedAuto'); @@ -148,7 +150,7 @@ class pluginBluditGithub extends Plugin public function afterPageDelete($key) { try { - if ($this->importing || empty($key) || !$this->isConfigured()) { + if ($this->importing || empty($key) || strpos($key, 'autosave-') === 0 || !$this->isConfigured()) { return; } @@ -486,7 +488,7 @@ class pluginBluditGithub extends Plugin private function exportPage($page, $saveStatus = true) { $key = $page->getValue('key'); - $rawContent = $page->content(); + $rawContent = $page->contentRaw(); // Export images using URLs found in the content (before rewriting) $this->exportImages($key, $rawContent . "\n" . $page->coverImage()); @@ -623,7 +625,7 @@ class pluginBluditGithub extends Plugin private function buildMarkdown($page, $key, $rawContent = null) { - $content = $rawContent ?? $page->content(); + $content = $rawContent ?? $page->contentRaw(); // Rewrite absolute Bludit upload URLs to relative img/ paths // e.g. https://domain/bl-content/uploads/pages/UUID/image.png → ../img/image.png diff --git a/tests/import.php b/tests/import.php index 9579ad9..1c918f0 100644 --- a/tests/import.php +++ b/tests/import.php @@ -244,6 +244,23 @@ try { check(Session::get('bluditGithubImport')['args']['username'] === 'spleenftw', 'A valid explicit selection overrides an unavailable repository author'); echo "PASS: selected/repository authors on create and update, author export, no impersonation or export loop\n"; + // Transient editor snapshots must never enter the public repository. + $plugin->requests = []; + $pages->add(['slug' => 'autosave-private-snapshot', 'content' => 'private draft', 'type' => 'autosave', 'username' => 'admin']); + $plugin->afterPageCreate('autosave-private-snapshot'); + $plugin->afterPageModify('autosave-private-snapshot'); + $plugin->afterPageDelete('autosave-private-snapshot'); + check($plugin->requests === [], 'No GitHub operations for autosave snapshots'); + $fenced = "```yaml\nfirst: value\n\n indented: value\n```\n"; + $plugin->fixture('export-source', document('export-source', $fenced)); + $plugin->invoke('previewImport', 'export-source', true); $plan = Session::get('bluditGithubImport'); + $plugin->invoke('confirmImport', $plan['confirmation']); + $plugin->requests = []; + $plugin->invoke('exportPage', new Page('export-source')); + $puts = array_values(array_filter($plugin->requests, function ($r) { return $r[0] === 'PUT'; })); + check(count($puts) === 1 && strpos(base64_decode($puts[0][2]['content']), $fenced) !== false, 'Export preserves raw fenced code, not rendered HTML'); + echo "PASS: no autosave exports and raw Markdown export preserves code fences\n"; + // Optional end-to-end fixture using an actual exported article directory. if (($articleDir = getenv('BLOG_ARTICLE_DIR'))) { $slug = basename(rtrim($articleDir, '/'));