bayareawebpro/laravel-dom-pipeline
Composer 安装命令:
composer require bayareawebpro/laravel-dom-pipeline
包简介
A DOM Pipeline Utility for Modifying HTML
README 文档
README
composer require bayareawebpro/laravel-dom-pipeline
https://packagist.org/packages/bayareawebpro/laravel-dom-pipeline
Laravel DOM Pipeline allows you to pipe HTML content through a series of classes
which can be helpful with sanitization and server-side enhancement / modification of page
elements. The pipeline will not return the <body> tag or any other tags outside the
body scope.
Usage:
use BayAreaWebPro\DomPipeline\DomPipeline; use My\Pipes\{ LazyLoadImageTags, LazyLoadVideoTags, BuildTableOfContents }; $modified = DomPipeline::make($html, [ LazyLoadImageTags::class, LazyLoadVideoTags::class, BuildTableOfContents::class, ]);
Example Dom Pipe Class
LazyLoad Images
<?php declare(strict_types=1); namespace App\Services\Html\Formatters; use Closure; use DOMElement; use DOMDocument; class LazyLoadImages { public function handle(DOMDocument $dom, Closure $next) { foreach ($dom->getElementsByTagName('img') as $node) { $this->lazyLoad($node); } return $next($dom); } protected function lazyLoad(DOMElement $node): void { if (!$node->hasAttribute('loading')) { $node->setAttribute('loading', 'lazy'); } } }
Element to VueComponent
Convert an Iframe into a Vue Component extracting the video ID from the URL.
<?php declare(strict_types=1); namespace App\Services\Html\Formatters; use Closure; use DOMElement; use DOMDocument; class LazyLoadVideos { public function handle(DOMDocument $dom, Closure $next) { $xpath = new \DOMXPath($dom); foreach($xpath->query('//iframe[@class="media"]') as $node){ $this->lazyLoad($dom, $node); } return $next($dom); } protected function lazyLoad(DOMDocument $dom, DOMElement $node): void { if(is_null($node->parentNode)) return; // Match the YouTube Video ID. // https://stackoverflow.com/questions/2936467/parse-youtube-video-id-using-preg-match preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i', (string) $node->getAttribute('src'), $matches ); if(isset($matches[1])){ // Create a new HTML fragment. $fragment = $dom->createDocumentFragment(); $fragment->appendXML(<<<HTML <v-video id="$matches[1]" label="Click to play..." :show-image="true"></v-video> HTML); // Replace Self with Fragment. $node->parentNode->replaceChild($fragment, $node); } } }
Table of Contents
<?php declare(strict_types=1); namespace App\Services\Html\Formatters; use DOMElement; use Closure; use StdClass; use DOMDocument; use Illuminate\Support\Str; use Illuminate\Support\Collection; use Illuminate\Support\Facades\View; class TableOfContents { public function handle(DOMDocument $dom, Closure $next) { $nodes = Collection::make(); $xpath = new \DOMXPath($dom); foreach ($xpath->query('//h1|//h2|//h3|//h4|//h5|//h6') as $node) { $text = strip_tags(html_entity_decode((string) $node->nodeValue)); $nodes->push($this->makeBookmark($node, $text)); } if($nodes->count() > 5){ View::share('tableOfContents', $nodes->take(25)); } return $next($dom); } protected function makeBookmark(DOMElement $node, string $text): StdClass { $bookmark = (object)[ 'anchor' => Str::slug($text), 'text' => Str::title(Str::replaceLast('.', '', $text)), ]; $node->setAttribute('id', $bookmark->anchor); return $bookmark; } }
统计信息
- 总下载量: 1.33k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 5
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2020-04-23