Irisable212 downloadsPublish and explicitly synchronize notes with WordPress using Gutenberg blocks, media reuse, previews, and guarded pull and merge workflows.
Current prerelease: 1.2.0-rc.1, paired with WP Title Layer 1.0.0-rc.4. Stable users may stay on 1.1.2 while the new role/group workflow completes manual acceptance.
English | 简体中文
Publish and explicitly synchronize Obsidian notes with WordPress while keeping Markdown, front matter, media, and WordPress-native editing under your control.
This project is an independently maintained fork of
devbean/obsidian-wordpress.
It has expanded from one-way publishing into a guarded editorial workflow with
Gutenberg output, media deduplication, preview, multi-site publishing, and
reviewed WordPress-to-Obsidian synchronization.
Release status: WP Publisher is available from Obsidian's Community Plugins directory. The P0-P3 feature set has passed local, clean-Vault, and real-site testing.
The complete implementation map and acceptance history are in
docs/feature-map.md.
You can also open the WP Publisher community directory page.
main.js, manifest.json, and styles.css from the same GitHub
release.<Vault>/.obsidian/plugins/.Disable the legacy obsidian-wordpress plugin while using this fork to avoid
duplicate commands and publishing through the wrong plugin.
npm ci
npm test
npm run build
For local development, run npm run dev and link this repository into a test
Vault's plugin directory. Use a dedicated test Vault rather than a primary
Vault while developing.
Create a profile in Settings > WP Publisher > Profiles. Supported transports are:
Use a dedicated, revocable WordPress Application Password rather than your main account password whenever possible.
Wordfence can disable WordPress Application Passwords. In that configuration, the REST API remains reachable but authenticated Publisher requests are rejected. WP Publisher reports the HTTP status and WordPress error code; the Companion does not bypass the policy or silently fall back to XML-RPC.
WordPress.com is not a supported connection type in the current release. New profiles cannot select it. A profile that already contains a saved legacy token remains readable for migration compatibility, but the token cannot be authorized, validated, or refreshed by this release.
Open a Markdown note and run Publish to WordPress from the command palette. The publish dialog shows whether the action will create a new post or update an existing one. Existing posts can use a full update or a content-only update.
The faster Publish with default options command uses the default profile, profile defaults, note properties, and any resolved publishing controls without opening the full dialog.
Gutenberg Block Editor output is the default. Change Content format in the plugin settings only when a site requires classic HTML.
All fields are optional. Canonical note-controlled properties include:
---
title: A WordPress title
subtitle: An optional subtitle
series: an-existing-series-slug
seriesSeason: 2
seriesLabel: "15A"
slug: a-portable-slug
excerpt: A short WordPress excerpt
metaDescription: A Rank Math SEO description
focusKeyword:
- first keyword
- second keyword
featuredImage: Images/cover.jpg
categories:
- parent-category
- child-category
wpTags:
- Obsidian publishing
- WordPress workflow
status: draft
commentStatus: open
---
Compatibility aliases remain readable for focus_keyword,
meta_description, secondaryTitle, secondary_title, and comment_status.
subtitle writes WP Title Layer's canonical wptl_subtitle field when
the selected post type exposes it. A legacy Secondary Title site can still use
the Companion fallback, but the two fields are never dual-written. Existing
notes keep using either compatible property name; new notes and newly pulled
subtitles prefer subtitle.
series refers to one Series already defined by WP Title Layer. Flat Series
need only the slug; seasoned Series also use the Season's stable public
seriesSeason ID. Omitting series while updating preserves the remote
placement, while series: "" explicitly removes it. Core REST supports normal
article placement. WP Title Layer rc.4 can additionally enable seriesRole
(intro, epilogue, appendix) through its public book-structure capability.
Non-article roles use seriesScope: series or season; whole-Series scope
cannot include a Season. Older/unknown capabilities block advanced writes,
not readback. XML-RPC Series remains unsupported. A seasoned Series is published to multiple sites one site at a time so
each site's Season label can be reviewed. Series definitions and ordering remain
owned by WordPress.
seriesGroup: "W1 Seeing human weakness" assigns a content group within the
selected Series and Season (WP Title Layer rc.3 or later with the REST field
enabled). Omit this property to preserve the remote group, or use
seriesGroup: "" to clear it. Only strings are accepted; a blank YAML value
is not a clear instruction. Publishing reads back the canonical group name
and updates the note only if you have not edited that property in the meantime.
Unsupported sites stop group publishing with an explicit message. Pull and
merge also support the group as a separate field.
Groups apply only to main articles. Non-article roles hide the group control
and preserve historical values without sending or clearing them.
wpTags contains WordPress tag names and may include spaces. The transport
resolves them to the selected site's term IDs and slugs, so site-specific
identifiers are not stored in the note. Obsidian's tags property and inline
#tags stay local and are never changed or published by the plugin. For
existing notes, front matter tags is accepted as a legacy fallback only when
wpTags is absent; the next successful full publish of a post writes wpTags.
Use wpTags: [] to publish no WordPress tags.
After a successful publish, the plugin may maintain these relationship and activity properties:
wpProfilewpPostIdwpPostTypewpLastPublishedAtwpLastPublishActionWrite-back is non-destructive: unrelated properties are preserved, categories
remain human-readable slugs, and wpTags uses WordPress tag names rather than
site-specific IDs.
Normal Markdown alt text is sent as image Alt Text and does not become a visible caption automatically:

Add an adjacent wp-media comment when attachment metadata is needed:

%% wp-media
title: Cover image title
altText: A more specific accessible description
caption: =alt
description: Media-library description
%%
caption: =alt explicitly reuses the final Alt Text as both the WordPress
attachment caption and the editable Gutenberg figcaption.
An explicit title remains the media-library attachment title. It is not
prepended to the visible figcaption; a literal caption is rendered as that
caption and nothing more.
When featuredImage points to an image that is not shown in the article body,
place an image-free wp-media block as the first non-empty body content. That
block supplies metadata for the featured image and is removed from the
published body. Its caption updates the WordPress attachment but does not
create a figcaption because no body image exists:
%% wp-media
title: Cover image title
altText: Accessible cover description
caption: Media-library caption
description: Longer attachment description
%%
Synchronization is always user initiated. The command palette provides:
The plugin deliberately does not perform timer-based sync, automatic deletion propagation, silent conflict selection, batch pull, or binary media merge.
Install WP Publisher Companion on
self-hosted WordPress when you need protected Rank Math fields, legacy Secondary
Title, or XML-RPC attachment metadata. WP Title Layer canonical subtitles and
Series use the post type's core REST contract instead. Companion 0.5.0 reports
the active subtitle provider and disables legacy _secondary_title writes when
WP Title Layer is active. Ordinary post publishing continues without it;
unsupported controls are shown as unavailable rather than silently failing.
data.json.npm run lint # TypeScript lint
npm test # behavioral regression suite
npm run build # TypeScript validation and production bundle
npm run check # lint, tests, and production build
npm run release:check # release metadata, docs, translations, and packages
npm run version:set -- 1.2.3 # synchronize release version files
npm run dev # watch build for local Obsidian testing
See CHANGELOG.md for release notes and
docs/feature-map.md for the canonical feature map.
Release maintainers should complete the
docs/release-checklist.md.
Tagged builds are packaged as draft GitHub releases so the assets can be
inspected before publication.
Licensed under the Apache License 2.0. Historical upstream changelog
entries and authorship are retained in recognition of the original
devbean/obsidian-wordpress project.
English | 简体中文
将 Obsidian 笔记发布到 WordPress,并通过明确触发的同步流程保持两端一致, 同时让 Markdown、Front Matter、媒体文件和 WordPress 原生编辑始终处于你的掌控之中。
本项目是
devbean/obsidian-wordpress
的独立维护分支。它已从单向发布工具扩展为一套受保护的编辑工作流,支持
Gutenberg 输出、媒体去重、发布预览、多站点发布,以及经过审阅的
WordPress 到 Obsidian 同步。
发布状态: WP Publisher 已进入 Obsidian 社区插件目录。P0-P3 功能集已经通过本地测试、空白 Vault 测试和真实站点测试。
完整实现地图和验收记录请参阅
docs/feature-map.md。
也可以打开 WP Publisher 社区插件页面。
main.js、manifest.json 和 styles.css。<Vault>/.obsidian/plugins/ 下的同一个文件夹。使用本分支时请禁用旧版 obsidian-wordpress 插件,以免出现重复命令,
或误用旧插件执行发布。
npm ci
npm test
npm run build
本地开发时可运行 npm run dev,并将本仓库链接到测试 Vault 的插件目录。
开发期间请使用专用测试 Vault,不要直接使用主要 Vault。
在 设置 > WP Publisher > WordPress 账户 中创建账号配置。 支持以下连接方式:
如条件允许,请使用专用、可撤销的 WordPress Application Password, 不要使用 WordPress 账号主密码。
Wordfence 可以禁用 WordPress Application Password。此时 REST API 本身仍可访问, 但 Publisher 的认证请求会被拒绝。插件会显示 HTTP 状态和 WordPress 错误 code; Companion 不会绕过该策略,也不会静默切换到 XML-RPC。
当前版本不支持新建 WordPress.com 连接。新账号不能选择 WordPress.com。 如果已有账号保存了旧版 token,插件仍可读取它以便迁移,但本版本不能授权、 验证或刷新该 token。
打开一个 Markdown 笔记,然后从命令面板运行 发布当前笔记。 发布窗口会明确显示本次操作将新建文章还是更新已有文章。更新已有文章时, 可以选择完整更新或仅更新正文。
更快捷的 使用默认参数发布当前笔记 命令不会打开完整发布窗口, 而是直接使用默认账号、账号默认值、笔记属性和已经解析出的发布控制项。
默认使用 Gutenberg 区块编辑器格式。只有当站点需要经典 HTML 时, 才应在插件设置中修改 WordPress 内容格式。
所有字段均为可选。由笔记控制的标准属性包括:
---
title: A WordPress title
subtitle: An optional subtitle
series: an-existing-series-slug
seriesSeason: 2
seriesLabel: "15A"
slug: a-portable-slug
excerpt: A short WordPress excerpt
metaDescription: A Rank Math SEO description
focusKeyword:
- first keyword
- second keyword
featuredImage: Images/cover.jpg
categories:
- parent-category
- child-category
wpTags:
- Obsidian 发布
- WordPress 工作流
status: draft
commentStatus: open
---
插件仍兼容读取 focus_keyword、meta_description、secondaryTitle、
secondary_title 和 comment_status 等旧属性名。
当所选文章类型公开相应能力时,subtitle 写入 WP Title Layer canonical
字段 wptl_subtitle。旧 Secondary Title 站点仍可使用 Companion 回退,但插件
不会同时双写两个副标题字段。已有笔记继续沿用原属性名;新笔记及新拉取的副标题
首选 subtitle。
series 指向 WP Title Layer 中已经存在的一个系列。平铺系列只需 slug;分季系列
还需填写该分季稳定的公开 seriesSeason ID。更新文章时省略 series 会保留远端
归属,series: "" 才表示明确移出系列。WordPress 核心 REST 支持普通 article
归属;WPTL rc.4 的公共书籍式结构能力还可开放 seriesRole:intro、epilogue、
appendix。非正文以 seriesScope: series 或 season 区分全系列和分季范围;
全系列范围不能同时带季。旧版或未知能力阻止高级角色写入,但仍可读回。
XML-RPC Series 仍不支持。
分季 Series 的多站点发布须逐站执行,以便分别核对各站的 Season 名称。系列定义
和篇序仍完全由 WordPress 管理。
seriesGroup: "W1 看见人的软弱" 指定所选系列和季内的内容分组,需要支持该
REST 字段的 WP Title Layer rc.3 或更新版本。省略属性保留远端分组;
seriesGroup: "" 明确取消分组。只接受字符串,不能用 YAML 空值代替清空。
发布后读取规范组名,仅在笔记中的原属性未被你修改时回写。目标站不支持时会
明确提示并停止此次发布。拉取和冲突合并也可单独选择内容分组字段。
分组仅作用于主要文章;非正文不显示分组输入框,保留历史值但不发送或清空。
wpTags 专门保存 WordPress 标签名称,可以包含空格;发布时再解析为所选站点的
term ID 和 slug,不把站点专属标识存入笔记。Obsidian 自身的 tags 属性和正文内
的 #标签 只留在本地,插件不会修改或发布它们。对于旧笔记,仅当 wpTags
不存在时,front matter 的 tags 才会作为兼容输入;下次对文章执行完整发布后
会写入 wpTags。如需明确不发布任何 WordPress 标签,请设置 wpTags: []。
发布成功后,插件可能维护以下关联和活动记录属性:
wpProfilewpPostIdwpPostTypewpLastPublishedAtwpLastPublishAction回填操作是非破坏性的:无关属性会被保留,分类仍使用便于阅读和迁移的 slug,
wpTags 使用 WordPress 标签名称,二者都不会替换为站点内部 ID。
普通 Markdown 图片的替代文字会作为图片 Alt Text 发送到 WordPress, 不会自动成为可见图注:

需要设置附件元数据时,可在图片后加入相邻的 wp-media 注释:

%% wp-media
title: Cover image title
altText: A more specific accessible description
caption: =alt
description: Media-library description
%%
caption: =alt 会明确要求插件将最终 Alt Text 同时用作 WordPress
附件说明文字和可编辑的 Gutenberg figcaption。
显式 title 只作为媒体库中的附件标题,不会再被拼到可见 figcaption 前面;
字面 caption 的可见内容就是它本身。
同步始终由用户主动触发。命令面板提供以下功能:
插件刻意不提供定时后台同步、自动传播删除、静默选择冲突结果、批量拉取, 或二进制媒体合并。
当自托管 WordPress 需要写入受保护的 Rank Math 字段、旧 Secondary Title,
或通过 XML-RPC 更新附件元数据时,请安装
WP Publisher Companion。
WP Title Layer canonical 副标题和系列归属改由文章类型的核心 REST 契约处理。
Companion 0.5.0 会报告当前副标题提供者,并在 WP Title Layer 激活时停用旧
_secondary_title 写入。
不安装 Companion 仍可正常发布普通文章;不受支持的控制项会明确显示为不可用,
而不是静默失败。
data.json 中。npm run lint # TypeScript lint
npm test # 行为回归测试
npm run build # TypeScript 验证和生产构建
npm run check # lint、测试和生产构建
npm run release:check # 发布元数据、文档、翻译和安装包检查
npm run version:set -- 1.2.3 # 同步发布版本文件
npm run dev # 为本地 Obsidian 测试启动监听构建
版本说明请参阅
CHANGELOG.md,
标准功能地图请参阅
docs/feature-map.md。
发布维护者还应完成
docs/release-checklist.md。
带标签的构建会被打包为 GitHub Draft Release,以便在公开发布前检查附件。
本项目采用
Apache License 2.0。
历史上游变更记录和作者信息继续保留,以致谢原始
devbean/obsidian-wordpress 项目。