| 开发者 | umayajans |
|---|---|
| 更新时间 | 2026年5月7日 17:21 |
| PHP版本: | 7.4 及以上 |
| WordPress版本: | 6.9 |
| 版权: | GPLv2 or later |
| 版权网址: | 版权信息 |
Accept header and, only when text/markdown is requested, intercepts the response and serves a clean, agent-friendly Markdown representation of the page.
Browsers, search engines, and any client that does not explicitly ask for Markdown receive the unchanged HTML response. There is no settings page, no cron job, and no external service call.
Key features
Accept: text/markdown is present. Regular visitors and search engines are never affected.the_content for posts/pages, falls back to a DOM-based extractor for archives, taxonomies, and the homepage.save_post, term edits, theme switches, and menu updates.Vary: Accept, X-Robots-Tag: noindex, and X-Content-Type-Options: nosniff on every Markdown response.umay_mdn_bypass — Return true to skip Markdown handling for the current request.umay_mdn_cache_ttl — Override the default 12-hour cache lifetime (in seconds, minimum 60).umay_mdn_rate_limit — Override the default 30-requests-per-minute rate limit.umay_mdn_converter_options — Modify the league/html-to-markdown converter options array.markdown-negotiator folder (or the ZIP) via Plugins > Add New > Upload Plugin.curl -H "Accept: text/markdown" https://your-site.com/
You should get back a Content-Type: text/markdown; charset=utf-8 response with a YAML front-matter and a Markdown body.No. The plugin returns immediately on template_redirect priority 1 if the request does not include Accept: text/markdown. The cost is roughly a single if check per request.
No. The plugin does not call any external service, does not send analytics, does not check for updates against a remote server, and does not load any remote assets. All HTML-to-Markdown conversion happens locally using the bundled league/html-to-markdown library.
Per-URL cache keys are deleted on save_post and transition_post_status for the affected post. Term edits, theme switches, and menu updates flush the entire Markdown cache.
No. Logged-in requests always fall back to HTML to avoid leaking nonces, admin bars, or per-user content into a shared Markdown cache. This is by design.
Deactivate and re-activate the plugin. Deactivation calls Cache::flush_all().
No. Every Markdown response includes X-Robots-Tag: noindex to prevent duplicate-content issues. The HTML version remains the canonical, indexable representation.
The plugin sets Vary: Accept so any well-behaved cache layer will store the Markdown and HTML variants separately. If your cache layer ignores the Vary header, exclude the URLs from the cache when the Accept: text/markdown header is present.
umay-ai-markdown to markdown-negotiator across plugin header, gettext calls, and POT file (per WP.org review feedback).echo $markdown with wp_kses( $markdown, array() ) to satisfy Plugin Check's late-escape rule while preserving Markdown syntax.markdown-negotiator (per WordPress.org review feedback to ensure the name is distinctive).libxml_disable_entity_loader() calls in ContentExtractor and Converter. XXE protection unchanged: libxml 2.9+ disables external entities by default, and LIBXML_NONET is still passed to loadHTML().ob_start( $callback ) on template_redirect with a template_include filter that opens and closes its buffer (ob_start paired with ob_get_clean) inside a single function scope, satisfying Plugin Check's buffer-pairing requirement.try/catch around the template render so a fatal in a theme/plugin returns a clean 500 instead of a half-buffered response.<style>, <script>, <noscript> blocks via regex (defense in depth on top of league/html-to-markdown's remove_nodes).data-lazy-src / data-src / data-original and the first srcset URL into the real src. Drops empty/placeholder images.href="#elementor-action:...", javascript:, or bare # are unwrapped to plain text.init and a base POT file ships in /languages/.