diff --git a/CHANGELOG.md b/CHANGELOG.md
index 073aa68..5996cdb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,30 @@
All notable changes to `WP Block Converter` will be documented in this file.
+## 1.3.0
+
+- Adds macro support to the converter, allowing for custom tags to be added to the
+ converter.
+- Adds support for `hr` tags.
+- Adds support for embeds.
+
+## 1.2.0
+
+- Enhancement: Adds support for non-standard ports in sanitized URLs (e.g.,
+ 8080).
+- Enhancement: Added new filter called `wp_block_converter_sanitized_image_url`
+ which allows the image URL for converted images to be filtered before being
+ applied.
+- Bugfix: Changed the behavior of the `create_or_get_attachment` function to
+ throw an exception instead of returning a `WP_Error`, which wasn't being
+ handled previously and would result in a crash if a non-string value was
+ returned by `upload_image`.
+- Bugfix: Ensure `upload_image` returns the image URL.
+
+## 1.1.0
+
+- Expands PHP version support from just 8.0 to include 8.1 and 8.2
+
## 1.0.0 - 2022-12-19
- Initial release
diff --git a/README.md b/README.md
index 80315cb..05e3e67 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,42 @@ add_filter( 'wp_block_converter_document_html', function( string $blocks, \DOMNo
}, 10, 2 );
```
+### Extending the Converter with Macros
+
+You can extend the converter with macros to add custom tags that are not yet
+supported by the converter.
+
+```php
+use Alley\WP\Block_Converter\Block_Converter;
+use Alley\WP\Block_Converter\Block;
+
+Block_Converter::macro( 'special-tag', function ( \DOMNode $node ) {
+ return new Block( 'core/paragraph', [], $node->textContent );
+} );
+
+// You can also use the raw HTML with a helper method from Block Converter:
+Block_Converter::macro( 'special-tag', function ( \DOMNode $node ) {
+ return new Block( 'core/paragraph', [], Block_Converter::get_node_html( $node ) );
+} );
+```
+
+Macros can also completely override the default behavior of the converter. This
+is useful when you need to make one-off changes to the way the converter works
+for a specific tag.
+
+```php
+use Alley\WP\Block_Converter\Block_Converter;
+use Alley\WP\Block_Converter\Block;
+
+Block_Converter::macro( 'p', function ( \DOMNode $node ) {
+ if (special_condition()) {
+ return new Block( 'core/paragraph', [ 'attribute' => 123 ], 'This is a paragraph' );
+ }
+
+ return Block_Converter::p( $node );
+} );
+```
+
## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
diff --git a/composer.json b/composer.json
index aa54bd9..9fb5e87 100644
--- a/composer.json
+++ b/composer.json
@@ -16,12 +16,12 @@
],
"require": {
"php": "^8.0|^8.1|^8.2",
- "alleyinteractive/composer-wordpress-autoloader": "^1.0"
+ "alleyinteractive/composer-wordpress-autoloader": "^1.0",
+ "mantle-framework/support": "^0.12"
},
"require-dev": {
"alleyinteractive/alley-coding-standards": "^2.0",
- "mantle-framework/testkit": "^0.12",
- "nunomaduro/collision": "^6.0"
+ "mantle-framework/testkit": "^0.12"
},
"config": {
"allow-plugins": {
diff --git a/src/class-block-converter.php b/src/class-block-converter.php
index af41919..9ee3534 100644
--- a/src/class-block-converter.php
+++ b/src/class-block-converter.php
@@ -12,11 +12,16 @@
use DOMElement;
use DOMNode;
use Exception;
+use Mantle\Support\Traits\Macroable;
/**
* Converts a DOMDocument to Gutenberg block HTML.
*/
class Block_Converter {
+ use Macroable {
+ __call as macro_call;
+ }
+
/**
* Setup the class.
*
@@ -89,6 +94,10 @@ public function convert(): string {
* @return Block|null
*/
public function __call( $name, $arguments ): ?Block {
+ if ( static::has_macro( $name ) ) {
+ return static::macro_call( $name, $arguments );
+ }
+
return match ( $name ) {
'ul' => $this->ul( $arguments[0] ),
'ol' => $this->ol( $arguments[0] ),
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 98cc862..3f3eeee 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -7,5 +7,6 @@
* Visit {@see https://mantle.alley.co/testing/test-framework.html} to learn more.
*/
\Mantle\Testing\manager()
+ ->with_sqlite()
->maybe_rsync_plugin()
->install();
diff --git a/tests/feature/test-block-converter.php b/tests/feature/test-block-converter.php
index a0c7b14..95fe69d 100644
--- a/tests/feature/test-block-converter.php
+++ b/tests/feature/test-block-converter.php
@@ -10,6 +10,7 @@
use Alley\WP\Block_Converter\Block;
use Alley\WP\Block_Converter\Block_Converter;
use Alley\WP\Block_Converter\Tests\Test_Case;
+use DOMNode;
/**
* Test case for Block Block_Converter Module.
@@ -157,4 +158,20 @@ public function test_convert_with_filter_override_entire_content() {
$this->assertSame( 'Override', $block );
}
+
+ public function test_macroable() {
+ Block_Converter::macro(
+ 'special-tag',
+ function (DOMNode $node) {
+ return new Block( 'paragraph', [ 'attribute' => '123' ], Block_Converter::get_node_html( $node ) );
+ },
+ );
+
+ $block = ( new Block_Converter( 'content here' ) )->convert();
+
+ $this->assertEquals(
+ 'content here',
+ $block,
+ );
+ }
}