前面在文章表中添加了 slug
字段,用于存文章标题的英文翻译,并且在管理后台添加和编辑文章的时候可以填入 slug
字段。现在来做一点修改,在添加文章的时候如果没有填入 slug
字段的时候,自动将文章标题翻译为英文,并存到 slug
字段。
为了实现自动生成 slug
需要两个工具:
- 百度翻译 API。
overtrue/pinyin
扩展包。
在没有填写 slug
字段的时候,调用百度翻译 API 将文章标题翻译成英文,百度翻译的 API 免费次数是有限的,如果百度翻译不可用的时候,就使用 overtrue/pinyin
将文章标题转换为汉语拼音。
安装扩展
运行如下命令安装 overtrue/pinyin
扩展:
composer require "overtrue/pinyin"
添加处理器
现在添加一个处理器来实现上面的逻辑,运行如下命令创建一个 Handlers
目录:
mkdir app/Handlers
运行如下命令创建一个 SlugTranslateHandler.php
文件:
touch app/Handlers/SlugTranslateHandler.php
添加如下内容:
<?php namespace App\Handlers;
use GuzzleHttp\Client;
use Overtrue\Pinyin\Pinyin;
use Illuminate\Support\Str;
class SlugTranslateHandler
{
public function translate($text)
{
$http = new Client;
$api = 'http://api.fanyi.baidu.com/api/trans/vip/translate?';
$appid = config('services.baidu_translate.appid');
$key = config('services.baidu_translate.key');
$salt = time();
if (empty($appid) || empty($key)) {
return $this->pinyin($text);
}
$sign = md5($appid. $text . $salt . $key);
$query = http_build_query([
"q" => $text,
"from" => "zh",
"to" => "en",
"appid" => $appid,
"salt" => $salt,
"sign" => $sign,
]);
$response = $http->get($api.$query);
$result = json_decode($response->getBody(), true);
if (isset($result['trans_result'][0]['dst'])) {
return Str::slug($result['trans_result'][0]['dst']);
} else {
return $this->pinyin($text);
}
}
public function pinyin($text)
{
return Str::slug(app(Pinyin::class)->permalink($text));
}
}
配置文件
要使用百度翻译 API 需要去百度翻译开放平台申请,在「管理后台」可以看到 appid
和 key
,然后将 appid
和 key
存放到 .env
文件中。
.env
.
.
.
BAIDU_TRANSLATE_APPID=xxxxxxxxxxxxx
BAIDU_TRANSLATE_KEY=xxxxxxxxxxxxxxxxx
在 env.example
中也增加相应的键:
env.example
BAIDU_TRANSLATE_APPID=
BAIDU_TRANSLATE_KEY=
将这种第三方服务授权认证信息存放于 services.php
里:
config/services.php
<?php return [
.
.
.
'baidu_translate' => [
'appid' => env('BAIDU_TRANSLATE_APPID'),
'key' => env('BAIDU_TRANSLATE_KEY'),
],
];
调用翻译
修改文章模型观察器:
app/Observers/ArticleObserver.php
.
.
.
public function saving(Article $article)
{
$article->excerpt = $this->make_excerpt($article->content);
if ( ! $article->slug) {
$article->slug = app(SlugTranslateHandler::class)->translate($article->title);
}
}
.
.
.
百度翻译报错
百度翻译可能报INVALID_CLIENT_IP
错误,格式如下:
array:3 [
"error_code" => "58000"
"error_msg" => "INVALID_CLIENT_IP"
"data" => array:1 [
"client_ip" => "220.165.198.126"
]
]
根据错误码来定位错误,客户端 IP 非法,请检查申请里面填写的服务器地址。