bumpcore / editor.php
Editor.js的PHP集成
Requires
- php: ^8.1
- fakerphp/faker: ^1.21
- illuminate/support: ^10.0|^11.0
- illuminate/validation: ^10.0|^11.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.14.4
- orchestra/testbench: ^8.0|^9.0
- pestphp/pest: ^1.22.4|^2.0
- phpstan/phpstan: ^1.10
This package is auto-updated.
Last update: 2024-09-25 18:19:28 UTC
README
Editor.php
Editor.php是一个旨在轻松解析和操作Editor.js输出的包。它可以与纯PHP或Laravel一起使用。Laravel提供了一些额外的功能。
目录
版本表
快速入门
通过以下方式安装包
composer require bumpcore/editor.php
Editor.php启动非常简单;
use BumpCore\EditorPhp\EditorPhp; // Passing Editor.js's output directly to the `make`. // This will render blocks into html. echo EditorPhp::make($json)->render();
Editor.php支持以下块:
它们都有默认的验证规则和视图以进行渲染。然而,自定义验证和视图是强烈推荐的。
EditorPhp
EditorPhp
类是管理块的主要类。您可以通过此类访问、渲染、转换为数组以及转换为JSON。
创建实例
创建EditorPhp新实例有两种方法
use BumpCore\EditorPhp\EditorPhp; // Using the `new` syntax. $editor = new EditorPhp($json); // Using the `make` syntax. $editor = EditorPhp::make($json);
两种语法相同,它们之间几乎没有什么区别。
访问块
您可以通过blocks属性访问块。
use BumpCore\EditorPhp\EditorPhp; use BumpCore\EditorPhp\Block\Block; use BumpCore\EditorPhp\Blocks\Paragraph; $editor = EditorPhp::make($json); // Stripping all tags from paragraph block's text. $editor->blocks->transform(function(Block $block) { if($block instanceof Paragraph) { $block->set('text', strip_tags($block->get('text'))); } return $block; });
块存储为Illuminate\Support\Collection
。通过使用集合方法,您可以按需操作块。您可以在Laravel的文档中了解有关集合的更多信息。
渲染HTML
渲染HTML非常直接。有多种方式可以渲染您的实例
use BumpCore\EditorPhp\EditorPhp; $editor = EditorPhp::make($json); // Using the `render` function. echo $editor->render(); // Using the `toHtml` function. echo $editor->toHtml(); // Or by casting to a string. echo $editor;
同样,这三种情况都是相同的,没有上下之分。您可以使用您最喜欢的一种。
默认情况下,您有两个用于默认块模板的选项;tailwindcss
和Bootstrap 5
。默认使用的模板是tailwindcss
。您可以通过以下方式切换模板:
use BumpCore\EditorPhp\EditorPhp; // Using tailwind. EditorPhp::useTailwind(); // Using Bootstrap. EditorPhp::useBootstrapFive();
您可以在创建自定义块部分中了解更多有关渲染的信息。
模拟
您可以使用EditorPhp
生成假数据。
use BumpCore\EditorPhp\EditorPhp; // This will return a generated fake JSON. $fake = EditorPhp::fake(); // If we pass first argument true, it will return new `EditorPhp` instance with fake data. $fakeEditor = EditorPhp::fake(true); // You can also pass min lenght and max lenght of blocks. // Below code will generate blocks between 1 and 3. $fakeEditor = EditorPhp::fake(true, 1, 3); echo $fakeEditor->render();
您可以在生成假数据部分中了解更多有关为块生成假数据的信息。
附加
转换为数组
您可以使用toArray()
方法将实例转换为数组。
use BumpCore\EditorPhp\EditorPhp; $editor = EditorPhp::make($json); // This will return ['time' => ..., 'blocks' => [...], 'version' => '...'] $array = $editor->toArray();
转换为JSON
您可以使用toJson(/** 选项 */)
方法将实例转换为JSON。此方法在操作实例时非常有用。
use BumpCore\EditorPhp\EditorPhp; $editor = EditorPhp::make($json); // This will return encoded JSON. $json = $editor->toJson(JSON_PRETTY_PRINT);
时间 & 版本
您可以访问时间和版本
use BumpCore\EditorPhp\EditorPhp; $editor = EditorPhp::make($json); $editor->time; $editor->version;
time
属性是Carbon
实例。您可以在Carbon的文档中了解更多信息。
宏
您可以注册宏并在以后使用它们。宏基于Laravel。
use BumpCore\EditorPhp\EditorPhp; // Registering new macro. EditorPhp::macro( 'getParagraphs', fn () => $this->blocks->filter(fn (Block $block) => $block instanceof Paragraph) ); $editor = EditorPhp::make($json); // This will return a collection that only contains paragraphs. $paragraphs = $editor->getParagraphs();
块
块是 EditorPhp
编辑器的主要构建部分。您可以随心所欲地操作它们,最好的部分是您可以使用它们来存储块逻辑。例如,图片 块需要一个上传器才能工作。您可以在 BumpCore\EditorPhp\Blocks\Image
类中实现相应的功能。
注册块
在我们学习如何自定义块之前,这里是如何注册您的块的方法。
use BumpCore\EditorPhp\EditorPhp; // This will merge without erasing already registered blocks. Other blocks will still remain with the recently registered `image` and `paragraph` blocks. EditorPhp::register([ 'image' => \Blocks\MyCustomImageBlock::class, 'paragraph' => \Blocks\MyCustomParagraphBlock::class, ]); // This will override already registered blocks. We now only have `image` and `paragraph` blocks. EditorPhp::register([ 'image' => \Blocks\MyCustomImageBlock::class, 'paragraph' => \Blocks\MyCustomParagraphBlock::class, ], true);
在注册块时,使用正确的键非常重要。键必须与 Editor.js
的 type
键相同。为了澄清:
{ "time": 1672852569662, "blocks": [ { "type": "paragraph", "data": { "text": "..." } } ], "version": "2.26.4" }
在这个输出中,我们的类型键是 paragraph
,因此我们应该将其注册为 'paragraph' => Paragraph::class
。这可能会根据您在 Editor.js
中注册块的方式而有所不同。EditorPhp
的默认块使用 camelCase
进行注册。
扩展块
如前所述,EditorPhp
几乎支持所有块。然而,它们主要处理块数据的验证和渲染。为了使 Image
块正常工作,它需要一个上传。我们可以在 Image
类中实现这个上传逻辑。
use BumpCore\EditorPhp\Blocks\Image; class MyImageBlock extends Image { public static function uploadTemp(string $fileName = 'image'): array { // ... // Temporary upload logic. return [ 'success' => ..., 'file' => [ 'url' => ..., ], ]; } public function upload(): void { $file = $this->get('file.url'); // Your logic. // ... // Altering the current block's data. $this->set('file.url', ...); } } // ... // Registering customized block. EditorPhp::register([ 'image' => MyImageBlock::class ]);
如您所见,我们已经扩展了 Image
块并添加了两个处理上传的函数。
uploadTemp
函数执行临时文件上传。这是一个静态方法,可以通过 Image::uploadTemp()
在任何地方使用。它返回由 图片 工具所需的数据。
upload
函数有不同的用途。它代表块的最终上传,但不是静态的。此方法假定图像已经临时上传,并且 $json
已加载并解析。因此,我们可以像这样使用此函数:
use BumpCore\EditorPhp\EditorPhp; use Blocks\MyImageBlock; $editor = EditorPhp::make($json); $editor->blocks->each(function(Block $block) { if ($block instanceof MyImageBlock) { $block->upload(); } }); return $editor->toJson();
现在,块执行最终上传,并作为 JSON 保存。
创建自定义块
无法支持所有块,因此我们可以轻松实现自己的块。一个标准的块看起来如下:
use BumpCore\EditorPhp\Block\Block; class MyCustomBlock extends Block { public function render(): string { return view('blocks.my-custom-block', ['data' => $this->data]); } }
如您所见,默认情况下,我们只需要实现渲染逻辑。然而,不仅仅是渲染。
访问块的数据
有多种方法可以访问块的数据。在下面的示例中,您可以看到访问块数据的不同方法。
public function render(): string { // ... // Method 1: Accessing through the data object. $data = $this->data; $data->get('custom.data'); $data->set('custom.data', 'Hello World!'); // Method 2: Accessing by invoking the data object. $data('custom.data'); // Hello World! // Method 3: Using shortcuts. $this->get('custom.data'); $this->set('custom.data', 'Nice!'); // ... }
您可以选择上述任何方法来访问和操作块的数据。此外,您还可以使用以下方法检查数据是否存在或不存在:
$data->has('custom.data'); // or $this->has('custom.data');
验证块数据
验证数据不是必需的,但它可以使您的数据更安全。验证块数据非常简单。我们只需要在我们的块中添加一个 rules
方法。
use BumpCore\EditorPhp\Block\Block; class MyCustomBlock extends Block { // ... public function rules(): array { return [ 'text' => 'required|string|max:255', 'items' => 'sometimes|array', 'items.*.name' => 'required|string|max:255', 'items.*.html' => 'required|string|min:255', ]; } // ... }
当验证块数据失败时,数据将为空。数据验证使用 Laravel 的验证库执行。您可以在 Laravel 文档 中了解更多信息。
清理块数据
如果您愿意,可以净化您数据中的 HTML。防止注入非常重要。净化数据看起来与验证类似。
use BumpCore\EditorPhp\Block\Block; class MyCustomBlock extends Block { // ... public function allow(): array|string { // Specifying one by one. return [ 'text' => [ 'a:href,target,title', // Will allow `a` tag and href, target, and title attributes. 'b', // Will only allow `b` tag with no attributes. ], 'items.*.name' => 'b:*', // Will allow `b` tag with all attributes. 'items.*.html' => '*', // Will allow every tag and every attribute. ]; // Or just allowing all attributes and tags for all data. return '*'; } // ... }
与验证不同,净化将仅删除不需要的标签和属性。
生成假数据
如我们之前提到的,我们可以使用 EditorPhp
生成假数据。但这需要为每个块生成自己的假数据。要生成假数据,我们应该向我们的块添加静态方法。
use BumpCore\EditorPhp\Block\Block; class MyCustomBlock extends Block { // ... public static function fake(\Faker\Generator $faker): array { $items = []; foreach (range(0, $faker->numberBetween(0, 10)) as $index) { $items[] = [ 'name' => fake()->name(), 'html' => $faker->randomHtml(), ]; } return [ 'text' => fake()->text(255), 'items' => $items, ]; } // ... }
通过向我们的块添加 fake
方法,现在 EditorPhp
生成假数据时也会包括 MyCustomBlock
。您可以在 FakerPHP 文档 中了解更多信息。
Laravel特有功能
有几个 Laravel 功能可以使您的生活更加轻松。
类型转换
您可以使用 EditorPhpCast
将您模型的属性转换为 EditorPhp
实例。
use BumpCore\EditorPhp\Casts\EditorPhpCast; use Illuminate\Database\Eloquent\Model; class Post extends Model { protected $casts = [ 'content' => EditorPhpCast::class, ]; } // ... $post = Post::find(1); // Content is `EditorPhp` instance in here. echo $post->content->render();
此外,如果您使用 cast,您也可以在块实例中访问您的模型。
use BumpCore\EditorPhp\Block\Block; use App\Models\Post; class MyBlock extends Block { // ... public static function render(): string { if($this->root->model instanceof Post) { // Do the other thing. } } // ... }
您还可以从块中修改模型。
响应
EditorPhp
实例可以作为响应返回。如果请求期望 JSON,它将自动编码为 JSON。否则,它将被渲染为 HTML。
namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\Models\Post; class ShowPostController extends Controller { public function __invoke(Post $post) { // Depending on the request it will return json or rendered html. return $post->content; } }
视图
您还可以使用 EditorPhp
实例直接在视图中渲染。
{{-- blog.show.blade.php --}} <article> <h1>{{ $post->title }}</h1> <div>{{ $post->content }}</div> </article>
发布视图和配置
在编写文档之前需要检查这一点。
命令
您可以使用 block:make <name>
命令创建全新的块。
php artisan make:block CustomImageBlock
新块将被放置在 app/Blocks
目录下。
贡献
欢迎贡献力量!如果您发现了一个错误或对改进有建议,请打开一个问题或创建一个 pull 请求。以下是一些遵循的指南:
- 将仓库 Fork 并克隆到您的本地计算机。
- 为您的贡献创建一个新的分支。
- 进行更改并彻底测试它们。
- 确保您的代码遵循现有的编码风格和约定。
- 提交您的更改并将它们推送到您 Fork 的仓库。
- 向主仓库提交一个 pull 请求。
请提供您更改的详细描述和它们解决的问题。您的贡献将被审查,并可能提供反馈。感谢您为使此项目更好而提供的帮助!