您将如何在多语言Laravel应用程序中组织邮件

时间:2018-03-16 19:11:34

标签: php laravel email laravel-blade

我很好奇如何在多语言应用程序中有效地生成电子邮件。

为了让所有答案保持一致:让我们说你有一个典型的商业通讯,里面有很多图片,标记,当然还有很多文字段落。假设所有文本都不是来自数据库,而应该是硬编码的。此外,这些段落中的某些词语可以加粗,强调,......时事通讯将在订阅者的首选语言环境中发送。

如何构建系统来处理这个问题?

  • 您会使用select part, operation, sum(estimatedrate) as estimatedrate, sum(actualrate) as actualrate from ((select part, operation, estimatedrate, 0 as actualrate from table1 ) union all (select part, operation, 0 as estimatedrate, 0 actualrate from table1 ) ) er group by part, operation; 引用每个段落并定义Laravel的 lang 文件夹中的所有翻译吗?然后单个单词标记部分怎么样?在语言文件中加入HTML标签对我来说感觉不对。
  • 或者您是否会为电子邮件创建单独的语言文件夹(例如views / emails / en)并使Laravel获取正确的语言文件夹?但随后可能存在大量重复的邮件布局定义......
  • 或许还有其他什么呢?

2 个答案:

答案 0 :(得分:3)

对于包含静态内容的简报:

  1. 避免翻译文件
  2. 将模板组合用于可重复使用的结构元素
  3. Laravel的本地化系统适用于应用程序中的字符串,但是,对于电子邮件中的文本内容,这些定义将很难维护,尤其是对于包含内联标记或定期更改的内容。包含许多trans()次调用的模板也会渲染得更慢,尤其是在批量处理数千封电子邮件时。

    如果其他人写了内容,在需要的地方添加一些Blade指令比将每个文本块提取到本地化条目要容易得多。请记住,我们需要为每个简报重复这项工作。

    相反,只需将内容直接写入模板,并对翻译为不同语言的消息使用命名层次结构。将结构和显示元素提取到可重用的组件中,以最大限度地减少与内容混合的标记量。

    我们的模板文件层次结构可能如下所示:

    resources/views/newsletters/
    ├── components/
    │   └── article_summary.blade.php
    ├── en/
    │   └── 2018-01-01.blade.php
    ├── es/
    │   └── 2018-01-01.blade.php
    ├── fr/
    │   └── 2018-01-01.blade.php
    └── newsletter.blade.php
    

    newsletter.blade.php 主模板包含每个简报中显示的基本元素,如标题,徽标和页脚。它将@include()根据用户的区域设置和发布日期提供相应的新闻通讯机构:

    {{-- ... common header markup ... --}}
    
    @include("newsletters.$locale.$date")
    
    {{-- ... common footer markup ... --}}
    

    本地化文件夹中的每个模板都包含该语言中邮件的文本,并根据需要使用一些内联HTML或markdown进行格式化。这是一个例子:

    # Newsletter Title
    
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc 
    finibus sapien nec sapien dictum, vitae dictum dolor mattis. 
    Nunc bibendum id augue...
    
    @component('newsletters.components.article_summary', [
        'title' => 'Article Title 1', 
        'fullArticleUrl' => 'http://...',
    ])
    Ut aliquet lobortis leo, cursus volutpat mi convallis ut. 
    Vivamus id orci ut quam rhoncus eleifend. Nulla condimentum...
    @endcomponent
    
    @component('newsletters.components.article_summary', [
        'title' => 'Article Title 2', 
        'fullArticleUrl' => 'http://...',
    ])
    Donec non finibus tellus, efficitur tincidunt leo. Nam nibh 
    augue, consectetur tincidunt dui et, fermentum dictum eros...
    @endcomponent
    

    正如我们所看到的,从消息的内容中分散注意力很少。 article_summary组件隐藏了邮件正文中的标记:

    <div class="summary">
        <a href="{{ $fullArticleUrl }}">
            <h2>{{ $title }}</h2>
        </a>
    
        <p>{{ $slot }}</p>
    </div>
    

    通过使用组件,我们可以自由地更改每个简报中的布局,并且我们避免重写我们经常使用的标记。 Laravel包含some useful built-in components标记消息。

    要发送消息,我们只需传递我们的主模板将从可用语言解析的语言环境和简报日期:

    public function build() 
    {
        return $this->->markdown('newsletters.newsletter')->with([ 
            'locale' => $this->user->locale,
            'date' => '2018-01-01',
        ]);
    }
    

    作为最后一点,我们不需要完全跳过使用trans()。在某些情况下可能有意义,例如在共享组件中。对于大多数内容,我们通过直接在模板中编写它来获得可读性和可维护性。

答案 1 :(得分:1)

我会在第一个选项中进行一些修改,在电子邮件中使用降价解析器,因此您不会将HTML合并到语言文件中,您将发送已解析的降价字符串到刀片模板:

  • 每次需要更改模板时,您都不必为每种语言更新每个模板。

  • 本地化代码已经在Laravel&amp;刀片模板引擎。

  • 对于每日广告系列电子邮件,您只能创建一个模板(对于RTL等语言可能再创建一个模板)和 nxm 翻译字符串,其中 n 代表模板包含的每个字符串,代表每种语言的 m

  • 您将能够使用字符串修饰符,例如奇点/多数,替换,并使用您自己的助手扩展系统。

例如,可以像这样构建一个简单的html电子邮件(使用Laravel 5.6):


翻译文件结构

/resources
    /lang
        /en
            /dailydigest.php
        /de
            /dailydigest.php


可以使用 DailyDigest.php

<?php

namespace App\Mail;

use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Markdown;
use Illuminate\Queue\SerializesModels;

class DailyDigest extends Mailable
{
    use Queueable;

    protected $user;

    public function __construct($user)
    {
        $this->user= $user;
    }

    public function build()
    {
        return $this
            ->from("admin@example.com")
            ->view('emails.dailydigest', [
                 'user' => $this->user,
                 'messageSection1' => Markdown::parse(Lang::get("dailydigest.message1",[],$this->user->locale)),
                 'messageImage1' => 'http://example.com/images/test.png',
                 'messageSection2' => Markdown::parse(Lang::get("dailydigest.message2",[],$this->user->locale)),

                 // if it's a language specific image
                 'messageImage2' => Lang::get("dailydigest.image2",[],$this->user->locale),   
               ]);
    }
}


模板 /resources/views/emails/dailydigest.blade.php

包含HTML和刀片指令的标准刀片模板,为每日摘要电子邮件创建。


控制器 SendDailyDigest.php

<?php

namespace App\Http\Controllers;

use App\User;    
use App\Mail\DailyDigest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Http\Controllers\Controller;

class DailyDigestController extends Controller
{
    /**
     * Send the dailydigest to all members.
     *
     * @param  Request  $request
     * @return Response
     */
    public function send(Request $request)
    {   
        $users = App\User::all();
        // build the email message with the users locale and add to queue
        foreach($users as $user){
            Mail::to($user->email)
                ->send(new DailyDigest($user))
                ->queue("digest");
        }
    }
}

我最近发现了一本出版物:

https://laravel-news.com/laravel-campaign-monitor