Update README and plugin logic: Correct folder structure references and enhance auto-export settings for drafts and published articles.

This commit is contained in:
interlope committed 2026-06-08 18:38:25 +02:00
1 parent bb30dc1f92
commit e7d67add18
2 files changed
+63 -60

No files matched your search

+14 -10
View File
@@ -4,21 +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, with the markdown file inside `article/` and images inside `img/`: 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 `content/` and images inside `img/`:
``` ```
my-article/ my-article/
article/ content/
index.md index.md
img/ img/
photo.png photo.png
screenshot.jpg screenshot.jpg
another-post/ another-post/
article/ content/
index.md index.md
``` ```
Each `index.md` contains a YAML frontmatter block followed by the article content. Image references are written as relative paths from the `article/` subfolder: Each `index.md` contains a YAML frontmatter block followed by the article content. Image references are written as relative paths from the `content/` subfolder:
```markdown ```markdown
--- ---
@@ -51,18 +51,22 @@ Article content with images like ![](../img/photo.png)
| Repository Name | The target repository (e.g. `my-blog`). | | Repository Name | The target repository (e.g. `my-blog`). |
| Branch | Branch to push to (default: `main`). | | Branch | Branch to push to (default: `main`). |
| Path Prefix | Optional subfolder prefix. Leave empty to export at the repo root. | | Path Prefix | Optional subfolder prefix. Leave empty to export at the repo root. |
| Export drafts | When checked, draft articles are also exported. | | Auto-export draft articles on save | When checked, draft articles are automatically pushed to GitHub when saved or modified. **Default is OFF**. |
| Auto-export on save | When checked, articles are automatically pushed to GitHub whenever you save or modify them. Uncheck to only use manual bulk export. | | Auto-export published articles on save | When checked, published articles are automatically pushed to GitHub when saved or modified. **Default is ON**. |
## Bulk export ## Bulk export
The settings page includes an **Export all articles now** button that pushes all your existing articles to GitHub in one go. Useful on first install or after changing the target repository. The settings page includes two export buttons:
- **Export everything** — pushes all articles (both drafts and published) to GitHub in one go.
- **Export published only** — pushes only published articles to GitHub.
Useful on first install or after changing the target repository.
## Behavior ## Behavior
- **On article save** (if auto-export is enabled): `article/index.md` is created or updated, and all images referenced in the content are uploaded to `img/`. - **On article save** (if auto-export is enabled): `content/index.md` is created or updated, and all images referenced in the content are uploaded to `img/`.
- **On article delete** (if auto-export is enabled): both `article/index.md` and all files in `img/` are deleted (GitHub removes the empty folders automatically). - **On article delete** (if auto-export is enabled): both `content/index.md` and all files in `img/` are deleted (GitHub removes the empty folders automatically).
- **Manual bulk export:** Use the "Export all articles now" button to push articles regardless of auto-export setting. - **Manual bulk export:** Use the "Export everything" or "Export published only" button to push articles regardless of auto-export setting.
- **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
+49 -50
View File
@@ -5,25 +5,26 @@ class pluginBluditGithub extends Plugin
public function init() public function init()
{ {
$this->dbFields = [ $this->dbFields = [
'token' => '', 'token' => '',
'owner' => '', 'owner' => '',
'repo' => '', 'repo' => '',
'branch' => 'main', 'branch' => 'main',
'path' => '', 'path' => '',
'exportDrafts' => false, 'exportDraftsAuto' => false,
'autoExport' => true, 'exportPublishedAuto' => true,
]; ];
} }
public function form() public function form()
{ {
$token = $this->getValue('token'); $token = $this->getValue('token');
$owner = $this->getValue('owner'); $owner = $this->getValue('owner');
$repo = $this->getValue('repo'); $repo = $this->getValue('repo');
$branch = $this->getValue('branch'); $branch = $this->getValue('branch');
$path = $this->getValue('path'); $path = $this->getValue('path');
$exportDrafts = $this->getValue('exportDrafts') ? 'checked' : ''; $exportDraftsAuto = $this->getValue('exportDraftsAuto') ? 'checked' : '';
$status = $this->getStatus(); $exportPublishedAuto = $this->getValue('exportPublishedAuto') ? 'checked' : '';
$status = $this->getStatus();
$html = '<div>'; $html = '<div>';
$html .= '<label>GitHub Personal Access Token</label>'; $html .= '<label>GitHub Personal Access Token</label>';
@@ -49,22 +50,23 @@ class pluginBluditGithub extends Plugin
$html .= '<div>'; $html .= '<div>';
$html .= '<label>Path Prefix <em>(optional)</em></label>'; $html .= '<label>Path Prefix <em>(optional)</em></label>';
$html .= '<input name="path" type="text" value="' . htmlspecialchars($path) . '" placeholder="Leave empty to export at repo root">'; $html .= '<input name="path" type="text" value="' . htmlspecialchars($path) . '" placeholder="Leave empty to export at repo root">';
$html .= '<span class="tip">Each article is exported as <code>{key}/index.md</code>. Set a prefix (e.g. <code>articles</code>) to nest under a subfolder.</span>'; $html .= '<span class="tip">Each article is exported as <code>{key}/content/index.md</code>. Set a prefix (e.g. <code>articles</code>) to nest under a subfolder.</span>';
$html .= '</div>'; $html .= '</div>';
$html .= '<div style="margin-top:1.5em;padding-top:1em;border-top:1px solid #eee">';
$html .= '<label>Auto-export settings</label>';
$html .= '<div>'; $html .= '<div>';
$html .= '<label><input name="exportDrafts" type="checkbox" value="1" ' . $exportDrafts . '> Export draft articles</label>'; $html .= '<label><input name="exportDraftsAuto" type="checkbox" value="1" ' . $exportDraftsAuto . '> Auto-export draft articles on save</label>';
$html .= '</div>'; $html .= '</div>';
$autoExport = $this->getValue('autoExport') ? 'checked' : '';
$html .= '<div>'; $html .= '<div>';
$html .= '<label><input name="autoExport" type="checkbox" value="1" ' . $autoExport . '> Auto-export on save <em>(uncheck to only use manual bulk export)</em></label>'; $html .= '<label><input name="exportPublishedAuto" type="checkbox" value="1" ' . $exportPublishedAuto . '> Auto-export published articles on save</label>';
$html .= '</div>';
$html .= '</div>'; $html .= '</div>';
$html .= '<div style="margin-top:1.5em;padding-top:1em;border-top:1px solid #eee">'; $html .= '<div style="margin-top:1.5em;padding-top:1em;border-top:1px solid #eee">';
$html .= '<label>Bulk Export</label>'; $html .= '<label>Bulk Export</label>';
$html .= '<p>Push all ' . ($exportDrafts ? '' : 'published ') . 'articles to GitHub at once.</p>'; $html .= '<input name="bulkExportAll" type="submit" class="btn btn-secondary" value="Export everything">';
$html .= '<input name="bulkExport" type="submit" class="btn btn-secondary" value="Export all articles now">'; $html .= '<input name="bulkExportPublished" type="submit" class="btn btn-secondary" value="Export published only" style="margin-left:0.5em">';
$html .= '</div>'; $html .= '</div>';
if ($status) { if ($status) {
@@ -80,24 +82,28 @@ class pluginBluditGithub extends Plugin
{ {
parent::post(); parent::post();
// Ensure checkboxes are properly saved as boolean (Bludit might store them as strings) $this->db['exportDraftsAuto'] = (isset($_POST['exportDraftsAuto']) && $_POST['exportDraftsAuto']) ? true : false;
$this->db['exportDrafts'] = (isset($_POST['exportDrafts']) && $_POST['exportDrafts']) ? true : false; $this->db['exportPublishedAuto'] = (isset($_POST['exportPublishedAuto']) && $_POST['exportPublishedAuto']) ? true : false;
$this->db['autoExport'] = (isset($_POST['autoExport']) && $_POST['autoExport']) ? true : false;
$this->dbSave(); $this->dbSave();
if (!empty($_POST['bulkExport'])) { if (!empty($_POST['bulkExportAll'])) {
$this->bulkExport(); $this->bulkExport(true);
} elseif (!empty($_POST['bulkExportPublished'])) {
$this->bulkExport(false);
} }
} }
public function afterPageCreate($key) public function afterPageCreate($key)
{ {
try { try {
if (empty($key) || !$this->isConfigured() || !$this->getValue('autoExport')) { if (empty($key) || !$this->isConfigured()) {
return; return;
} }
$page = new Page($key); $page = new Page($key);
if ($this->shouldExport($page)) { $isDraft = $page->getValue('status') === 'draft';
$shouldAutoExport = $isDraft ? $this->getValue('exportDraftsAuto') : $this->getValue('exportPublishedAuto');
if ($shouldAutoExport) {
$this->exportPage($page); $this->exportPage($page);
} }
} catch (Throwable $e) { } catch (Throwable $e) {
@@ -108,11 +114,14 @@ class pluginBluditGithub extends Plugin
public function afterPageModify($key) public function afterPageModify($key)
{ {
try { try {
if (empty($key) || !$this->isConfigured() || !$this->getValue('autoExport')) { if (empty($key) || !$this->isConfigured()) {
return; return;
} }
$page = new Page($key); $page = new Page($key);
if ($this->shouldExport($page)) { $isDraft = $page->getValue('status') === 'draft';
$shouldAutoExport = $isDraft ? $this->getValue('exportDraftsAuto') : $this->getValue('exportPublishedAuto');
if ($shouldAutoExport) {
$this->exportPage($page); $this->exportPage($page);
} }
} catch (Throwable $e) { } catch (Throwable $e) {
@@ -130,8 +139,8 @@ class pluginBluditGithub extends Plugin
$prefix = trim($this->getValue('path'), '/'); $prefix = trim($this->getValue('path'), '/');
$base = ($prefix ? $prefix . '/' : '') . $key; $base = ($prefix ? $prefix . '/' : '') . $key;
// Delete article/index.md // Delete content/index.md
$mdPath = $base . '/article/index.md'; $mdPath = $base . '/content/index.md';
$sha = $this->getFileSha($mdPath); $sha = $this->getFileSha($mdPath);
if ($sha) { if ($sha) {
$this->githubRequest('DELETE', '/contents/' . $mdPath, [ $this->githubRequest('DELETE', '/contents/' . $mdPath, [
@@ -161,14 +170,6 @@ class pluginBluditGithub extends Plugin
// --- Private --- // --- Private ---
private function shouldExport($page)
{
$isDraft = $page->getValue('status') === 'draft';
$exportDraftsVal = $this->getValue('exportDrafts');
$shouldExportDraft = ($exportDraftsVal === true || $exportDraftsVal === '1' || $exportDraftsVal === 1);
return (!$isDraft) || $shouldExportDraft;
}
private function exportPage($page, $saveStatus = true) private function exportPage($page, $saveStatus = true)
{ {
@@ -273,7 +274,7 @@ class pluginBluditGithub extends Plugin
return ($data !== false && $httpCode === 200) ? $data : null; return ($data !== false && $httpCode === 200) ? $data : null;
} }
private function bulkExport() private function bulkExport($includeDrafts = false)
{ {
if (!$this->isConfigured()) { if (!$this->isConfigured()) {
$this->setStatus('Error: GitHub settings not configured.'); $this->setStatus('Error: GitHub settings not configured.');
@@ -282,23 +283,21 @@ class pluginBluditGithub extends Plugin
global $pages; global $pages;
$includeDrafts = (bool)$this->getValue('exportDrafts'); $list = $pages->getList(1, 9999, true, true, true, $includeDrafts, false);
$list = $pages->getList(1, 9999, true, true, true, $includeDrafts, false); $count = 0;
$count = 0;
foreach ($list as $key) { foreach ($list as $key) {
try { try {
$page = new Page($key); $page = new Page($key);
if ($this->shouldExport($page)) { $this->exportPage($page, false);
$this->exportPage($page, false); $count++;
$count++;
}
} catch (Exception $e) { } catch (Exception $e) {
continue; continue;
} }
} }
$this->setStatus(date('Y-m-d H:i:s') . " — Bulk export: {$count} articles pushed."); $type = $includeDrafts ? 'everything' : 'published articles';
$this->setStatus(date('Y-m-d H:i:s') . " — Bulk export: {$count} {$type} pushed.");
} }
private function buildMarkdown($page, $key, $rawContent = null) private function buildMarkdown($page, $key, $rawContent = null)
@@ -381,7 +380,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 . '/article/index.md'; return ($prefix ? $prefix . '/' : '') . $key . '/content/index.md';
} }
private function getFileSha($filePath) private function getFileSha($filePath)