ueberdosis/tiptap-php
Composer 安装命令:
composer require ueberdosis/tiptap-php
包简介
A PHP package to work with Tiptap output
README 文档
README
A PHP package to work with Tiptap content. You can transform Tiptap-compatible JSON to HTML, and the other way around, sanitize your content, or just modify it.
Installation
You can install the package via composer:
composer require ueberdosis/tiptap-php
Usage
The PHP package mimics large parts of the JavaScript package. If you know your way around Tiptap, the PHP syntax will feel familiar to you.
Convert Tiptap HTML to JSON
Let’s start by converting a HTML snippet to a PHP array with a Tiptap-compatible structure:
(new \Tiptap\Editor) ->setContent('<p>Example Text</p>') ->getDocument(); // Returns: // ['type' => 'doc', 'content' => …]
You can get a JSON string in PHP, too.
(new \Tiptap\Editor) ->setContent('<p>Example Text</p>') ->getJSON(); // Returns: // {"type": "doc", "content": …}
Convert Tiptap JSON to HTML
The other way works aswell. Just pass a JSON string or an PHP array to generate the HTML.
(new \Tiptap\Editor) ->setContent([ 'type' => 'doc', 'content' => [ [ 'type' => 'paragraph', 'content' => [ [ 'type' => 'text', 'text' => 'Example Text', ], ] ] ], ]) ->getHTML(); // Returns: // <h1>Example Text</h1>
This doesn’t fully adhere to the ProseMirror schema. Some things are supported too, for example aren’t marks allowed in a CodeBlock.
If you need better schema support, create an issue with the feature you’re missing.
Syntax highlighting for code blocks with highlight.php
The default CodeBlock extension doesn’t add syntax highlighting to your code blocks. However, if you want to add syntax highlighting to your code blocks, there’s a special CodeBlockHighlight extension.
Swapping our the default one works like that:
(new \Tiptap\Editor([ 'extensions' => [ new \Tiptap\Extensions\StarterKit([ 'codeBlock' => false, ]), new \Tiptap\Nodes\CodeBlockHighlight(), ], ])) ->setContent('<pre><code><?php phpinfo()</code></pre>') ->getHTML(); // Returns: // <pre><code class="hljs php"><span class="hljs-meta"><?php</span> phpinfo()</code></pre>
This is still unstyled. You need to load a CSS file to add colors to the output, for example like that:
<link rel="stylesheet" href="//unpkg.com/@highlightjs/cdn-assets@11.4.0/styles/default.min.css">
Boom, syntax highlighting! By the way, this is powered by the amazing scrivo/highlight.php.
Syntax highlighting for code blocks with Shiki (Requires Node.js)
There is an alternate syntax highlighter that utilizes Shiki. Shiki is a beautiful syntax highlighter powered by the same language engine that many code editors use. The major differences from the CodeBlockHighlight extensions are:
- you must install the
shikinpm package. - Shiki code highlighting works by injecting inline styles so pulling in a external css file is not required.
- you can use most VS Code themes to highlight your code.
To use the Shiki extension, first install the npm package
npm install shiki
Then follow the example below:
(new \Tiptap\Editor([ 'extensions' => [ new \Tiptap\Extensions\StarterKit([ 'codeBlock' => false, ]), new \Tiptap\Nodes\CodeBlockShiki(), ], ])) ->setContent('<pre><code><?php phpinfo()</code></pre>') ->getHTML();
To configure the theme or default language for code blocks pass additonal configuration into the constructor as show below:
(new \Tiptap\Editor([ 'extensions' => [ new \Tiptap\Extensions\StarterKit([ 'codeBlock' => false, ]), new \Tiptap\Nodes\CodeBlockShiki([ 'theme' => 'github-dark', // default: nord, see https://github.com/shikijs/shiki/blob/main/docs/themes.md 'defaultLanguage' => 'php', // default: html, see https://github.com/shikijs/shiki/blob/main/docs/languages.md 'guessLanguage' => true, // default: true, if the language isn’t passed, it tries to guess the language with highlight.php ]), ], ])) ->setContent('<pre><code><?php phpinfo()</code></pre>') ->getHTML();
Under the hood the Shiki extension utilizes Shiki PHP by Spatie, so please see the documentation for additional details and considerations.
Convert content to plain text
Content can also be transformed to plain text, for example to put it into a search index.
(new \Tiptap\Editor) ->setContent('<h1>Heading</h1><p>Paragraph</p>') ->getText(); // Returns: // "Heading // // Paragraph"
What’s coming between blocks can be configured, too.
(new \Tiptap\Editor) ->setContent('<h1>Heading</h1><p>Paragraph</p>') ->getText([ 'blockSeparator' => "\n", ]); // Returns: // "Heading // Paragraph"
Sanitize content
A great use case for the PHP package is to clean (or “sanitize”) the content. You can do that with the sanitize() method. Works with JSON strings, PHP arrays and HTML.
It’ll return the same format you’re using as the input format.
(new \Tiptap\Editor) ->sanitize('<p>Example Text<script>alert("HACKED!")</script></p>'); // Returns: // '<p>Example Text</p>'
Modifying the content
With the descendants() method you can loop through all nodes recursively as you are used to from the JavaScript package. But in PHP, you can even modify the node to update attributes and all that.
Warning: You need to add
&to the parameter. Thats keeping a reference to the original item and allows to modify the original one, instead of just a copy.
$editor->descendants(function (&$node) { if ($node->type !== 'heading') { return; } $node->attrs->level = 1; });
Configuration
Pass the configuration to the constructor of the editor. There’s not much to configure, but at least you can pass the initial content and load specific extensions.
new \Tiptap\Editor([ 'content' => '<p>Example Text</p>', 'extensions' => [ new \Tiptap\Extensions\StarterKit, ], ])
The StarterKit is loaded by default. If you just want to use that, there’s no need to set it.
Extensions
By default, the StarterKit is loaded, but you can pass a custom array of extensions aswell.
new \Tiptap\Editor([ 'extensions' => [ new \Tiptap\Extensions\StarterKit, new \Tiptap\Marks\Link, ], ])
Configure extensions
Some extensions can be configured. Just pass an array to the constructor, that’s it. We’re aiming to support the same configuration as the JavaScript package.
new \Tiptap\Editor([ 'extensions' => [ // … new \Tiptap\Nodes\Heading([ 'levels' => [1, 2, 3], ]), ], ])
You can pass custom HTML attributes through the configuration, too.
new \Tiptap\Editor([ 'extensions' => [ // … new \Tiptap\Nodes\Heading([ 'HTMLAttributes' => [ 'class' => 'my-custom-class', ], ]), ], ])
For the StarterKit, it’s slightly different, but works as you are used to from the JavaScript package.
new \Tiptap\Editor([ 'extensions' => [ new Tiptap\Extensions\StarterKit([ 'codeBlock' => false, 'heading' => [ 'HTMLAttributes' => [ 'class' => 'my-custom-class', ], ] ]), ], ])
Extend existing extensions
If you need to change minor details of the supported extensions, you can just extend an extension.
<?php class CustomBold extends \Tiptap\Marks\Bold { public function renderHTML($mark) { // Renders <b> instead of <strong> return ['b', 0] } } new \Tiptap\Editor([ 'extensions' => [ new Paragraph, new Text, new CustomBold, ], ])
Custom extensions
You can even build custom extensions. If you are used to the JavaScript API, you will be surprised how much of that works in PHP, too. 🤯 Find a simple example below.
Make sure to dig through the extensions in this repository to learn more about the PHP extension API.
<?php use Tiptap\Core\Node; class CustomNode extends Node { public static $name = 'customNode'; public static $priority = 100; public function addOptions() { return [ 'HTMLAttributes' => [], ]; } public function parseHTML() { return [ [ 'tag' => 'my-custom-tag[data-id]', ], [ 'tag' => 'my-custom-tag', 'getAttrs' => function ($DOMNode) { return ! \Tiptap\Utils\InlineStyle::hasAttribute($DOMNode, [ 'background-color' => '#000000', ]) ? null : false; }, ], [ 'style' => 'background-color', 'getAttrs' => function ($value) { return (bool) preg_match('/^(black)$/', $value) ? null : false; }, ], ]; } public function renderHTML($node) { return ['my-custom-tag', ['class' => 'foobar'], 0] } }
Extension priority
Extensions are evaluated in the order of descending priority. By default, all Nodes, Marks, and Extensions, have a priority value of 100.
Priority should be defined when creating a Node extension to match markup that could be matched be other Nodes - an example of this is the TaskItem Node which has evaluation priority over the ListItem Node.
Testing
composer test
You can install nodemon (npm install -g nodemon) to keep the test suite running and watch for file changes:
composer test-watch
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.
ueberdosis/tiptap-php 适用场景与选型建议
ueberdosis/tiptap-php 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 13.6M 次下载、GitHub Stars 达 266, 最近一次更新时间为 2022 年 01 月 25 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「tiptap」 「prosemirror」 「ueberdosis」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 ueberdosis/tiptap-php 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 ueberdosis/tiptap-php 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 ueberdosis/tiptap-php 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Takes HTML and outputs ProseMirror compatible JSON.
Takes HTML and outputs ProseMirror compatible JSON.
Pandoc PHP Package
Work with ProseMirror JSON in PHP.
A flexible visual editor field for Craft.
A PHP package to work with Tiptap output
统计信息
- 总下载量: 13.6M
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 266
- 点击次数: 24
- 依赖项目数: 31
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2022-01-25