- Use function replacer in rewriteBody to prevent $& / $$ / $` / $' pattern corruption when alt text or siteUrl contains dollar-sign sequences - Detect empty staged index after `git add -A` and throw a clear "No changes to publish" error instead of a cryptic git failure - Correct README flat-slug description: single image → <slug>.<ext>, multiple → <slug>-1.<ext>, <slug>-2.<ext> (original filename discarded) - Harden askpass dir resolution: show a Notice and return early if getFullPath is absent (desktop-only guard), rather than passing a bad path Co-Authored-By: Claude <noreply@anthropic.com>
95 lines
4.0 KiB
Markdown
95 lines
4.0 KiB
Markdown
# Obsidian Jekyll Publish
|
|
|
|
An Obsidian plugin that publishes the active note as a Jekyll blog post via git. Images are copied alongside the post using one of two configurable strategies, and credentials are handled by your system git — nothing is stored inside Obsidian.
|
|
|
|
## What it does
|
|
|
|
1. Opens a "Publish to Jekyll" modal for the currently active markdown file.
|
|
2. Lets you confirm or adjust the slug, date, frontmatter, image strategy, and commit message.
|
|
3. Clones (or updates) your Jekyll site repository into a temporary directory.
|
|
4. Writes the post as `_posts/<date>-<slug>.md` (or your configured path).
|
|
5. Copies any embedded images according to the selected strategy.
|
|
6. Commits and pushes to your configured remote and branch.
|
|
|
|
## Installation
|
|
|
|
1. Build the plugin (see Development below) or download the release assets.
|
|
2. Copy `dist/main.js`, `dist/manifest.json`, and `dist/styles.css` into:
|
|
```
|
|
<your-vault>/.obsidian/plugins/jekyll-publish/
|
|
```
|
|
3. Reload Obsidian and enable **Jekyll Publish** under Settings → Community plugins.
|
|
|
|
## Settings
|
|
|
|
| Setting | Description | Default |
|
|
|---|---|---|
|
|
| Remote URL | Git remote URL for your Jekyll site (HTTPS or SSH) | _(empty)_ |
|
|
| Branch | Branch to push to | `main` |
|
|
| Posts directory | Destination directory inside the repo | `_posts` |
|
|
| Images directory | Where images are copied inside the repo | `assets/img` |
|
|
| Default image strategy | `flat-slug` or `per-post-folder` (see below) | `flat-slug` |
|
|
| Preset frontmatter | Key/value pairs always injected into every post | _(empty)_ |
|
|
| Commit message template | Template; `{{title}}` is replaced by the note title | `Publish: {{title}}` |
|
|
| Author name | Git author name for commits | _(empty)_ |
|
|
| Author email | Git author email for commits | _(empty)_ |
|
|
|
|
## Image strategies
|
|
|
|
**flat-slug** — all images for the post are copied flat into `<images-dir>/`. A single image is renamed to `<slug>.<ext>`; multiple images are renamed to `<slug>-1.<ext>`, `<slug>-2.<ext>`, … (the original Obsidian filename is discarded). Keeps the images directory shallow; suitable for sites with few images per post.
|
|
|
|
**per-post-folder** — images are copied into `<images-dir>/<slug>/` preserving their original filenames. Keeps each post's images grouped together; suitable for posts with many images.
|
|
|
|
## Credentials model
|
|
|
|
The plugin uses your **system git** binary for all remote operations. No passwords or tokens are stored inside Obsidian or the plugin's data files.
|
|
|
|
When git needs a credential (e.g. HTTPS password or a personal access token), an **askpass bridge** intercepts the prompt and shows a native Obsidian modal so you can type the value. The value is passed directly to git through a temporary socket and is never persisted.
|
|
|
|
For SSH remotes, the plugin relies on your existing SSH agent or `~/.ssh` key configuration — no extra steps needed.
|
|
|
|
## Development
|
|
|
|
### Requirements
|
|
|
|
- Node.js 20+
|
|
- npm
|
|
|
|
### Build
|
|
|
|
```sh
|
|
npm install
|
|
npm run build
|
|
# Output: dist/main.js dist/manifest.json dist/styles.css
|
|
```
|
|
|
|
### Unit tests
|
|
|
|
```sh
|
|
npm test
|
|
```
|
|
|
|
Runs the Vitest suite (frontmatter parsing, slug derivation, image path logic, git helpers, publish pipeline).
|
|
|
|
### E2E tests
|
|
|
|
The E2E suite boots the real Obsidian binary in a headless X display and drives it via the Chrome DevTools Protocol.
|
|
|
|
**Prerequisites:**
|
|
|
|
- `xvfb-run` on PATH (install: `sudo apt install xvfb`)
|
|
- Obsidian AppImage placed at `~/.cache/obsidian-e2e/Obsidian.AppImage`
|
|
(download from <https://obsidian.md/download>)
|
|
|
|
```sh
|
|
npm run e2e
|
|
```
|
|
|
|
The script:
|
|
1. Extracts the AppImage (once, cached).
|
|
2. Provisions a throwaway vault at `.obsidian-e2e/` with the plugin installed.
|
|
3. Launches Obsidian with `--remote-debugging-port` and connects Playwright over CDP.
|
|
4. Runs the smoke spec: plugin loads, command `jekyll-publish:publish-current-note` is registered, opening a note and executing the command shows a modal with heading "Publish to Jekyll".
|
|
|
|
The `.obsidian-e2e/` directory and Playwright `test-results/` are excluded from git.
|