Update README and plugin logic: Clarify article export structure and enhance image deletion process in GitHub integration

This commit is contained in:
interlope committed 2026-06-01 17:34:52 +02:00
1 parent acc60c7007
commit 54b88e49c5
2 files changed
+33 -17

No files matched your search

+10 -5
View File
@@ -4,16 +4,21 @@ A [Bludit](https://www.bludit.com) plugin that automatically exports your blog a
## What it does ## What it does
Whenever you create, update, or delete an article in Bludit, the plugin pushes the change to a GitHub repository via the GitHub API. Each article is exported as its own folder containing an `index.md` file: Whenever you create, update, or delete an article in Bludit, the plugin pushes the change to a GitHub repository via the GitHub API. Each article is exported as its own folder, with the markdown file inside `article/` and images inside `img/`:
``` ```
my-article/ my-article/
article/
index.md index.md
img/
photo.png
screenshot.jpg
another-post/ another-post/
article/
index.md index.md
``` ```
Each `index.md` contains a YAML frontmatter block followed by the article content: Each `index.md` contains a YAML frontmatter block followed by the article content. Image references are written as relative paths from the `article/` subfolder:
```markdown ```markdown
--- ---
@@ -28,7 +33,7 @@ description: "Optional meta description"
category: tech category: tech
--- ---
Article content here... Article content with images like ![](../img/photo.png)
``` ```
## Installation ## Installation
@@ -54,8 +59,8 @@ The settings page includes an **Export all articles now** button that pushes all
## Behavior ## Behavior
- **On article save:** the article's `index.md` is created or updated in the repository. - **On article save:** `article/index.md` is created or updated, and all images referenced in the content are uploaded to `img/`.
- **On article delete:** the article's `index.md` is deleted from the repository (GitHub removes the empty folder automatically). - **On article delete:** both `article/index.md` and all files in `img/` are deleted (GitHub removes the empty folders automatically).
- **Errors** are displayed in the plugin settings panel and never interfere with Bludit's own save process. - **Errors** are displayed in the plugin settings panel and never interfere with Bludit's own save process.
## Requirements ## Requirements
+23 -12
View File
@@ -115,23 +115,34 @@ class pluginBluditGithub extends Plugin
if (empty($key) || !$this->isConfigured()) { if (empty($key) || !$this->isConfigured()) {
return; return;
} }
// List all files in the article's folder and delete them
$prefix = trim($this->getValue('path'), '/');
$dirPath = ($prefix ? $prefix . '/' : '') . $key;
$items = $this->githubRequest('GET', '/contents/' . $dirPath);
if (!is_array($items)) { $prefix = trim($this->getValue('path'), '/');
return; $base = ($prefix ? $prefix . '/' : '') . $key;
// Delete article/index.md
$mdPath = $base . '/article/index.md';
$sha = $this->getFileSha($mdPath);
if ($sha) {
$this->githubRequest('DELETE', '/contents/' . $mdPath, [
'message' => 'Delete: ' . $key,
'sha' => $sha,
'branch' => $this->getValue('branch'),
]);
} }
// Delete all files in img/
$items = $this->githubRequest('GET', '/contents/' . $base . '/img');
if (is_array($items)) {
foreach ($items as $item) { foreach ($items as $item) {
if ($item['type'] === 'file') { if ($item['type'] === 'file') {
$this->githubRequest('DELETE', '/contents/' . $item['path'], [ $this->githubRequest('DELETE', '/contents/' . $item['path'], [
'message' => 'Delete: ' . $key . '/' . $item['name'], 'message' => 'Delete image: ' . $key . '/img/' . $item['name'],
'sha' => $item['sha'], 'sha' => $item['sha'],
'branch' => $this->getValue('branch'), 'branch' => $this->getValue('branch'),
]); ]);
} }
} }
}
} catch (Throwable $e) { } catch (Throwable $e) {
$this->setStatus('Error (afterPageDelete): ' . $e->getMessage()); $this->setStatus('Error (afterPageDelete): ' . $e->getMessage());
} }
@@ -214,7 +225,7 @@ class pluginBluditGithub extends Plugin
} }
} }
$repoPath = ($prefix ? $prefix . '/' : '') . $key . '/' . $filename; $repoPath = ($prefix ? $prefix . '/' : '') . $key . '/img/' . $filename;
$sha = $this->getFileSha($repoPath); $sha = $this->getFileSha($repoPath);
$data = [ $data = [
@@ -262,11 +273,11 @@ class pluginBluditGithub extends Plugin
{ {
$content = $rawContent ?? $page->content(); $content = $rawContent ?? $page->content();
// Rewrite absolute Bludit upload URLs to relative filenames // Rewrite absolute Bludit upload URLs to relative img/ paths
// e.g. https://domain/bl-content/uploads/pages/UUID/image.png → image.png // e.g. https://domain/bl-content/uploads/pages/UUID/image.png → ../img/image.png
$content = preg_replace( $content = preg_replace(
'/https?:\/\/[^\/]+\/bl-content\/uploads\/pages\/[^\/]+\/([^"\')\s<>]+)/', '/https?:\/\/[^\/]+\/bl-content\/uploads\/pages\/[^\/]+\/([^"\')\s<>]+)/',
'$1', '../img/$1',
$content $content
); );
@@ -313,7 +324,7 @@ class pluginBluditGithub extends Plugin
private function getFilePath($key) private function getFilePath($key)
{ {
$prefix = trim($this->getValue('path'), '/'); $prefix = trim($this->getValue('path'), '/');
return ($prefix ? $prefix . '/' : '') . $key . '/index.md'; return ($prefix ? $prefix . '/' : '') . $key . '/article/index.md';
} }
private function getFileSha($filePath) private function getFileSha($filePath)