laravel-css-inliner/css-inliner

将 Laravel 邮件中的 CSS 类转换为内联样式

2.0.0 2023-06-08 11:33 UTC

This package is auto-updated.

Last update: 2024-09-08 14:36:13 UTC


README

Static Analysis Tests

概览

此包利用 tijsverkoyen/css-to-inline-styles 将可邮寄视图中的 CSS 类转换为内联样式,以改善电子邮件客户端兼容性。

您可以选择利用此包的自动化功能,或者选择挂钩到此包的事件(甚至 Laravel 的核心事件),并手动选择要转换的内容以及要使用的样式表。请参阅使用部分以获取更多详细信息。

安装

通过 Composer

composer require bradietilley/laravel-css-inliner

使用方法

为了演示目的,我们将使用外观 BradieTilley\LaravelCssInliner\Facades\CssInline,但是如果您喜欢直接使用实例(像我一样),您可以将 BradieTilley\LaravelCssInliner\Facades\CssInline:: 替换为以下任何一个

  • BradieTilley\LaravelCssInliner\Facades\CssInline:
  • BradieTilley\LaravelCssInliner\CssInliner::singleton()->
  • app(BradieTilley\LaravelCssInliner\CssInliner::class)->
  • app()->make(BradieTilley\LaravelCssInliner\CssInliner::class)->

通过 PHP 添加 CSS

在任何时候(在 HTML 转换之前),您都可以定义您希望添加到每个由 CSS Inliner 转换的 HTML 字符串或电子邮件中的 CSS 文件或原始 CSS。一个很好的例子是一个所有电子邮件都应该继承的基本样式表。

use BradieTilley\LaravelCssInliner\Facades\CssInline;

CssInline::addCssPath(resource_path('css/email.css'));
CssInline::addCssRaw('body { background: #eee; }');

# Or, you can achieve the same outcome by letting CssInline decide whether it's a path or raw CSS:
CssInline::addCss(resource_path('css/email.css'));
CssInline::addCss('body { background: #eee; }');

手动转换

您可能希望手动转换 HTML 字符串或电子邮件中的某些 CSS。

use BradieTilley\LaravelCssInliner\Facades\CssInline;
use Symfony\Component\Mime\Email;

CssInline::addCss('.font-bold { font-weight: bold; }');

# Convert an HTML string
$html = CssInline::convert('<html><body><div class="font-bold">Bold</div></body></html>');
echo $html; // <html><body><div class="font-bold" style="font-weight: bold;">Bold</div></body></html>

# Convert an email
$email = new Email();
$email->html('<html><body><div class="font-bold">Bold</div></body></html>');
CssInline::convertEmail($email);
echo $email->getHtmlBody(); // <html><body><div class="font-bold" style="font-weight: bold;">Bold</div></body></html>

选项:自动解析 Laravel 电子邮件(或不自动解析 Laravel 电子邮件)

您可能希望有条件地启用或禁用 CSS Inliner,用于从 Laravel 发送的邮件(通过 Mail::send())。为此,我们可以利用 emailListener 选项。默认值为 true(因此将自动转换从 Laravel 发送的电子邮件中找到的 CSS 类)。

use BradieTilley\LaravelCssInliner\Facades\CssInline;

CssInline::emailListenerEnabled(); // Current state: true or false
CssInline::enableEmailListener(); // Enables option; returns instance of CssInliner
CssInline::disableEmailListener(); // Disables option; returns instance of CssInliner

选项:从给定的任何 HTML 或电子邮件中读取 CSS(样式和链接元素)

您可能希望解析 HTML 或电子邮件中找到的 <style><link> 样式表,例如,如果您想将特定于电子邮件的 CSS 存储在电子邮件视图中。为此,我们可以利用 cssFromHtmlContent 选项。默认值为 false

use BradieTilley\LaravelCssInliner\Facades\CssInline;

CssInline::cssFromHtmlContentEnabled(); // Current state: true or false
CssInline::enableCssExtractionFromHtmlContent(); // Enables option; returns instance of CssInliner
CssInline::disableCssExtractionFromHtmlContent(); // Disables option; returns instance of CssInliner

选项:在读取 CSS(如上所述)之后,从 HTML 或电子邮件中删除原始 CSS(样式和链接元素)

您可能希望在将 CSS 转换为内联样式后从 HTML 或电子邮件中删除大型 <style><link> 样式表,以减少从您的系统发送的电子邮件的有效负载大小。为此,我们可以利用 cssRemovalFromHtmlContent 选项。默认值为 false

use BradieTilley\LaravelCssInliner\Facades\CssInline;

CssInline::cssRemovalFromHtmlContentEnabled(); // Current state: true or false
CssInline::enableCssRemovalFromHtmlContent(); // Enables option; returns instance of CssInliner
CssInline::disableCssRemovalFromHtmlContent(); // Disables option; returns instance of CssInliner
use BradieTilley\LaravelCssInliner\Facades\CssInline;

CssInline::doSomething();
CssInliner::addCssPath(resource_path('css/email.css'));
CssInliner::addCssRaw('.text-success { color: #00ff00; }');

# Convert your own HTML/CSS
$html = '<span class="text-success">Success text</span>';
$html = CssInliner::convert($html);

echo $html; // <span class="text-success" style="color: #00ff00;">Success text</span>

事件

CssInliner 会触发四个事件 - 两个用于 HTML 转换,所有四个用于电子邮件转换。事件调用的顺序是

  • 1st: BradieTilley\LaravelCssInliner\Events\PreEmailCssInlineEvent(仅限电子邮件)
  • 2nd: BradieTilley\LaravelCssInliner\Events\PreCssInlineEvent(电子邮件 + HTML)
  • 3rd: BradieTilley\LaravelCssInliner\Events\PostCssInlineEvent(电子邮件 + HTML)
  • 4th: BradieTilley\LaravelCssInliner\Events\PostEmailCssInlineEvent(仅限电子邮件)

可以通过 Laravel 的常规方式监听事件。例如

Event::listen(\BradieTilley\LaravelCssInliner\Events\PreEmailCssInlineEvent::class, fn () => doSomething());

或者,您可能希望使用回调方法 hook 到 CSS Inliner:beforeConvertingEmailafterConvertingEmailbeforeConvertingHtmlafterConvertingHtml。这些方法接受一个回调,实际上是 Event::listen() 的代理,因此您可以将以下示例中使用的回调视为对应 CssInliner 事件的 Event::listen() 的第二个参数。

事件:在电子邮件转换之前(beforeConvertingEmail

CssInliner::beforeConvertingEmail(function (PreEmailCssInlineEvent $event) {
    # You have access to the unconverted-Email and CSS Inliner instance via the event
    $event->email; // instanceof: \Symfony\Component\Mime\Email
    $event->cssInliner; // instanceof BradieTilley\LaravelCssInliner\CssInliner
    echo $event->email->getHtmlBody(); // <html>...</html>

    # Because this is a 'before' event, you may choose to halt the conversion of this *one* Email
    return $event->cssInliner->halt();
    # Laravel will halt any other event listeners; CSS Inliner will return the Email immediately (and not convert it)
});

事件:在 HTML 转换之前(beforeConvertingHtml

CssInliner::beforeConvertingHtml(function (PreCssInlineEvent $event) {
    # You have access to the unconverted-HTML and CSS Inliner instance via the event
    $event->html; // string
    $event->cssInliner; // instanceof BradieTilley\LaravelCssInliner\CssInliner
    echo $event->html; // <html>...</html>

    # Because this is a 'before' event, you may choose to halt the conversion of this *one* HTML string
    return $event->cssInliner->halt();
    # Laravel will halt any other event listeners; CSS Inliner will return the HTML immediately (and not convert it) 
});

事件:在 HTML 转换之后(afterConvertingHtml

CssInliner::afterConvertingHtml(function (PostCssInlineEvent $event) {
    # You have access to the converted-HTML and CSS Inliner instance via the event
    $event->html; // string
    $event->cssInliner; // instanceof BradieTilley\LaravelCssInliner\CssInliner
    echo $event->html; // <html>...</html>

    # Because this is an 'after' event, you cannot halt the conversion of the HTML string (unlike the 'before' event)
});

事件:在电子邮件转换之后(afterConvertingEmail

CssInliner::afterConvertingEmail(function (PostEmailCssInlineEvent $event) {
    # You have access to the converted-Email and CSS Inliner instance via the event
    $event->email; // instanceof: \Symfony\Component\Mime\Email
    $event->cssInliner; // instanceof BradieTilley\LaravelCssInliner\CssInliner
    echo $event->email->getHtmlBody(); // <html>...</html>

    # Because this is an 'after' event, you cannot halt the conversion of the Email (unlike the 'before' event)
});

变更日志

有关最近更改的详细信息,请参阅变更日志

测试

composer test

贡献

有关详细信息,请参阅贡献指南