devristo/bbcode

适用于 PHP 5.4 及以上版本的简单且灵活的 BBCode 解析器。

v1.0.1 2019-02-01 13:35 UTC

This package is auto-updated.

Last update: 2024-08-29 04:13:11 UTC


README

适用于 PHP 5.4 及以上版本的简单且灵活的 BBCode 解析器。

功能

  • 将 BBCode 文档转换为 DOMDocument。可以通过其 API 修改或使用 XPath 查询。
  • 在文本节点中标注表情符号和 URL。
  • 灵活的递归渲染机制。

安装

开始使用 composer 是最简单的方式。由于 API 尚未最终确定,您需要按照以下方式引用 devristo/bbcode

{
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/Devristo/bbcode.git"
    }
  ], "require": {
    "devristo/bbcode": "dev-master"
  }
}

最小示例

对于基本的 BBCode,devristo/bbcode 提供了开箱即用的支持。例如,对于 [b][i][img][s][u][url] 标签。

<?php
require_once("vendor/autoload.php");

use Devristo\BBCode\BBCode;

$bbcode = new BBCode();
$html = $bbcode->toHtml("Hello [b]world[/b]");

// Echoes 'Hello <b>world</b>'
echo $html;

将 BBCode 转换为 DOMDocument

内部,devristo/bbcode 在将内容渲染为 HTML 之前,将 BBCode 解析为 DOMDocument。

<?php
require_once("vendor/autoload.php");

use Devristo\BBCode\BBCode;

$bbcode = new BBCode();
$document = $bbcode->toDocument("Hello [b]world[/b]");

// Echoes 'world'
echo $document->getElementsByTagName("b")->item(0)->textContent;

### 链接化默认情况下,devristo/bbcode 通过在 DOM 树中创建一个 url 元素来标注所有链接。您可以使用 $bbcode->setLinkify(false) 禁用此行为。以下示例使用链接化和生成的 DOM 模型查询 BBCode 中使用的所有 URL。

<?php
require_once("vendor/autoload.php");

use Devristo\BBCode\BBCode;

$bbcode = new BBCode();
$document = $bbcode->toDocument("
  Hello visitor of www.github.com/Devristo/bbcode , 
  did you come here using [url]https://google.com/[/url] 
  or by [url=https://bing.com/]Bing.com[/url] ?
");

// Echoes:
// www.github.com/Devristo/bbcode
// https://google.com/
// https://bing.com/
foreach($document->getElementsByTagName("url") as $urlElement) {
    $url = $urlElement->getAttribute('url') ?: $urlElement->textContent;
    echo $url. PHP_EOL;
}

### 表情符号与链接类似,devristo/bbcode 在 DOM 树中使用表情符号标签标注表情符号。表情符号基于单词匹配,必须使用 $bbcode->addEmoticon(':)') 定义。它们可以通过设置 'emoticon' 元素的 decorator 进行解析。

<?php
require_once("vendor/autoload.php");

use Devristo\BBCode\BBCode;
use Devristo\BBCode\Parser\RenderContext;
use Devristo\BBCode\Parser\BBDomElement;

$bbcode = new BBCode();
$bbcode->addEmoticon(':)');
$bbcode->getRenderContext()->setDecorator(
 'emoticon', 
 function(RenderContext $context, BBDomElement $element){
    $images = array(
      ':)' => 'smile.gif'
    );
    
    $code = $element->getInnerBB();
    return '<img src="'.$images[$code].'" alt="'.$code.'">';
 }
);

// Echoes 'Hello world <img src="smile.gif" alt=":)">'
echo $bbcode->toHtml("Hello world :)");

定义新标签及其装饰器

尽管所有可能的 BBCode 标签都解析到 DOM 中,但未知标签将由 VerbatimDecorator 渲染,它输出原始输入的 BBCode。要按不同方式渲染标签,其装饰器应设置为 RenderContext

<?php
require_once("vendor/autoload.php");

use Devristo\BBCode\BBCode;
use Devristo\BBCode\Parser\RenderContext;
use Devristo\BBCode\Parser\BBDomElement;

$bbcode = new BBCode();
$bbcode->getRenderContext()->setDecorator(
 'spoiler', 
 function(RenderContext $context, BBDomElement $element){
    return '<div style="background: black; color: black">'.$context->render($element).'</div>';
 }
);

// Echoes '<div style="background: black; color: black">Hello <b>world</b></div>'
echo $bbcode->toHtml("[spoiler]hello [b]world[/spoiler]");

您可以通过显式设置标签的装饰器来覆盖内部 devristo/bbcode 装饰器。如果您想禁用所有内部装饰器,请在定义自己的装饰器之前简单调用 $bbcode->getRenderContext()->removeAllDecorators()

动态更改 RenderContext

您可能经常想更改特定标签的后代元素的渲染方式。例如,我们可以定义一个 [quote] 标签,并不同方式渲染嵌套引用。

<?php
require_once("vendor/autoload.php");

use Devristo\BBCode\BBCode;
use Devristo\BBCode\Parser\RenderContext;
use Devristo\BBCode\Parser\BBDomElement;

$bbcode = new BBCode();
$bbcode->getRenderContext()->setDecorator(
 'quote', 
 function(RenderContext $context, BBDomElement $element){
    // $context is the RenderContext used for direct and indirect descendants of the current element.
    
    $context->setDecorator('quote', function(RenderContext $context, BBDomElement $element){
      return '<blockquote>[ ... ]</blockquote>';
    });
    
    return '<blockquote>'.$context->render($element).'</blockquote>';
 }
);

// Echoes '<blockquote>Hello <blockquote>[ ... ]</blockquote></blockquote>'
echo $bbcode->toHtml("[quote]Hello [quote]world[/quote]");

检索原始 BBCode

有时我们对元素的原始内容感到满意。以下 [code] 标签是一个很好的例子,它将代码标签之间的内容原样渲染。

<?php
require_once("vendor/autoload.php");

use Devristo\BBCode\BBCode;
use Devristo\BBCode\Parser\RenderContext;
use Devristo\BBCode\Parser\BBDomElement;

$bbcode = new BBCode();
$bbcode->getRenderContext()->setDecorator(
 'code', 
 function(RenderContext $context, BBDomElement $element){
    return '<pre>'.$element->getInnerBB().'</pre>';
 }
);

// Echoes '<pre>Hello [quote]world</pre>'
echo $bbcode->toHtml("[code]Hello [quote]world[/code]");