定制 wp-php-toolkit/markdown 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

wp-php-toolkit/markdown

最新稳定版本:v0.7.3

Composer 安装命令:

composer require wp-php-toolkit/markdown

包简介

Markdown component for WordPress.

README 文档

README

slug markdown
title Markdown
install wp-php-toolkit/markdown
credit_title Built on league/commonmark
credit_body Markdown parsing is delegated to <a href="https://commonmark.thephpleague.com/"><code>league/commonmark</code></a>; YAML frontmatter is handled by <a href="https://github.com/webuni/front-matter"><code>webuni/front-matter</code></a>. The toolkit's own work is the bridge between CommonMark's AST and <a href="https://developer.wordpress.org/block-editor/reference-guides/block-api/">WordPress block markup</a>, in both directions.
see_also
blockparser | BlockParser | Understand the block tree created from Markdown output. html | HTML | Rewrite rendered HTML fragments without using DOMDocument. dataliberation | DataLiberation | Turn Markdown folders into import/export streams.

Bidirectional converter between Markdown and WordPress block markup. Useful for moving content between Markdown files and WordPress while preserving the structures both formats can express.

Why this exists

Many publishing workflows start in Markdown: documentation sites, static-site generators, Git-backed editorial workflows, Obsidian vaults, and developer notes. WordPress stores editor content as block markup. Moving between those worlds by string replacement loses metadata and quickly breaks on lists, tables, code blocks, and frontmatter.

The Markdown component provides a structured bridge. MarkdownConsumer turns Markdown plus frontmatter into block markup and metadata; MarkdownProducer turns supported block markup back into Markdown. The conversion is meant for practical content workflows, not byte-identical round-tripping of every custom block attribute.

Markdown to blocks

Feed Markdown into MarkdownConsumer, get block markup back. The result is a BlocksWithMetadata object (defined in WordPress\DataLiberation\DataFormatConsumer — the shared shape every DataFormatConsumer in the toolkit emits) that holds both the rendered blocks and any frontmatter parsed from the document.

<?php
require '/wordpress/wp-content/php-toolkit/vendor/autoload.php';

use WordPress\Markdown\MarkdownConsumer;

$result = ( new MarkdownConsumer( "# Hello\n\nWelcome to **WordPress**." ) )->consume();
echo $result->get_block_markup();
<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading" id="hello">Hello</h1>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Welcome to <b>WordPress</b>.</p>
<!-- /wp:paragraph -->

Round-trip: blocks back to Markdown

Pair MarkdownProducer with MarkdownConsumer to convert in either direction. Round-tripping is lossy for block attributes that have no Markdown representation (custom classes, alignment), so do not expect byte-perfect equality.

<?php
require '/wordpress/wp-content/php-toolkit/vendor/autoload.php';

use WordPress\Markdown\MarkdownConsumer;
use WordPress\Markdown\MarkdownProducer;

$md       = "## Round trip\n\n- one\n- two\n- three\n";
$blocks   = ( new MarkdownConsumer( $md ) )->consume();
$markdown = ( new MarkdownProducer( $blocks ) )->produce();

echo $markdown;
## Round trip

- one
- two
- three

Reading YAML frontmatter as post meta

Frontmatter keys come back as arrays so a single key can hold multiple values. Use get_meta_value() when you only want the first scalar.

<?php
require '/wordpress/wp-content/php-toolkit/vendor/autoload.php';

use WordPress\Markdown\MarkdownConsumer;

$md = <<<MD
---
post_title: "The Name of the Wind"
post_status: publish
tags: [fantasy, kingkiller]
---

Once upon a time...
MD;

$consumer = new MarkdownConsumer( $md );
$consumer->consume();

echo 'Title: '   . $consumer->get_meta_value( 'post_title' )  . "\n";
echo 'Status: '  . $consumer->get_meta_value( 'post_status' ) . "\n";
$metadata = $consumer->get_all_metadata();
echo 'Tags: ' . implode( ', ', $metadata['tags'][0] ) . "\n";
Title: The Name of the Wind
Status: publish
Tags: fantasy, kingkiller

Migrating an Obsidian or Hugo folder of Markdown

Walk a directory of .md files (Obsidian vault, Hugo content/, Jekyll _posts) and emit one block-markup record per file.

<?php
require '/wordpress/wp-content/php-toolkit/vendor/autoload.php';

use WordPress\Markdown\MarkdownConsumer;

@mkdir( '/tmp/vault', 0777, true );
file_put_contents( '/tmp/vault/welcome.md', "---\ntitle: Welcome\n---\n\nHello world." );
file_put_contents( '/tmp/vault/roadmap.md', "# Roadmap\n\n1. Ship\n2. Iterate" );

foreach ( glob( '/tmp/vault/*.md' ) as $path ) {
	$consumer = new MarkdownConsumer( file_get_contents( $path ) );
	$consumer->consume();
	$title = $consumer->get_meta_value( 'title' );
	if ( ! $title ) $title = basename( $path, '.md' );
	echo "=== $title ($path) ===\n";
	echo substr( $consumer->get_block_markup(), 0, 120 ) . "...\n\n";
}
=== roadmap (/tmp/<tempfile>/roadmap.md) ===
<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading" id="roadmap">Roadmap</h1>
<!-- /wp:heading -->

<!-- wp:lis...

=== Welcome (/tmp/<tempfile>/welcome.md) ===
<!-- wp:paragraph -->
<p>Hello world.</p>
<!-- /wp:paragraph -->

...

Counting blocks produced by a Markdown document

After conversion, the block markup is plain WordPress block markup, so parse_blocks() works on it directly. The standard way to introspect what the converter emitted before saving to the database.

<?php
require '/wordpress/wp-content/php-toolkit/vendor/autoload.php';

use WordPress\Markdown\MarkdownConsumer;

$md = <<<MD
# Title

A paragraph with **bold** and *italics*.

| Col A | Col B |
|-------|-------|
| 1     | 2     |

```php
echo 'hi';
```

> A quote.
MD;

$blocks = ( new MarkdownConsumer( $md ) )->consume()->get_block_markup();
$counts = array();
$queue  = parse_blocks( $blocks );

while ( $queue ) {
	$block = array_shift( $queue );
	if ( null !== $block['blockName'] ) {
		$name             = $block['blockName'];
		$counts[ $name ] = isset( $counts[ $name ] ) ? $counts[ $name ] + 1 : 1;
	}
	foreach ( $block['innerBlocks'] as $inner_block ) {
		$queue[] = $inner_block;
	}
}
foreach ( $counts as $name => $count ) {
	echo "{$name}: {$count}\n";
}
core/heading: 1
core/paragraph: 2
core/table: 1
core/code: 1
core/quote: 1

统计信息

  • 总下载量: 26
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 1
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: GPL-2.0-or-later
  • 更新时间: 2025-09-06

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固