Laravel 中创建 RSS Feed 教程

翻译 Summer ⋅ 于 2周前 ⋅ 351 阅读 ⋅ 原文地址
这是一篇社区协同翻译的文章,已完成翻译,更多信息请点击 协同翻译介绍

RSS feed

在 Laravel 中创建一个 RSS 订阅并不是什么难事,但是使用一个现成的包和一些小技巧能够帮助你更快的创建一个 RSS 订阅。

下面我们将使用 spatie/laravel-feed 包来从一个全新的 Laravel 5.6 项目走到服务 RSS 订阅。

JiaZombie 翻译于 2周前

安装

首先,我们需要创建一个新的 Laravel 项目。你可以使用 laravel new 安装器命令,或者使用 composer:

composer create-project --prefer-dist laravel/laravel:5.6 rss-example
cd rss-example

然后,我们需要安装 spatie/laravel-feed 包,并复制其配置文件到项目中:

composer require spatie/laravel-feed
php artisan vendor:publish\
  --provider="Spatie\Feed\FeedServiceProvider"\
  --tag="config"
JiaZombie 翻译于 2周前
rayle 审阅

数据建模

我们将创建一些测试模型数据为事件集设置 RSS 源。假定这些模型就是为接下来要举办的教堂或者小组活动准备的 RSS 源。模型名称 Event 稍显累赘,但是这是我能想到的最好名字了,接下来我们均使用这个名字。

首先,我们为 RSS 源创建模型以及迁移\文件和工厂文件:

php artisan make:model Event -mf
Model created successfully.
Factory created successfully.
Created Migration: 2018_04_03_033916_create_events_table

在迁移类中,定义一个简单的数据库结构:

public function up()
{
    Schema::create('events', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->text('description');
        $table->string('author');
        $table->timestamps();
    });
}

接下来,打开 database/factories/EventFactory.php 文件然后增加如下内容:

$factory->define(App\Event::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'description' => "<p>".implode("</p>\n\n<p>", $faker->paragraphs(rand(3,6)))."</p>",
        'author' => $faker->name,
    ];
});
wilson_yang 翻译于 2周前

也许有生成 HTML 描述的更佳方式,但我仍假设用于创建事件的 UI 会提供用于编写描述的 WYSIWYG 字段。

我们可以使用上文中的已定义的数据库结构和工厂类填充一些测试数据,用以完成我们的 RSS 源设置。

php artisan make:seeder EventsSeeder

在已创建的 EventsSeeder类中,生成一些可用的数据库填充事件:

<?php

use Illuminate\Database\Seeder;

class EventsSeeder extends Seeder
{
    /**
     * 运行数据库填充
     *
     * @return void
     */
    public function run()
    {
        factory('App\Event', 50)->create();
    }
}

然后,添加 EventsSeeder 到 DatabaseSeeder 类:

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * 运行数据库填充
     *
     * @return void
     */
    public function run()
    {
        $this->call(EventsSeeder::class);
    }
}
wilson_yang 翻译于 2周前

你或许需要运行 composer dump-autoload 来加载种子文件,这取决于你是怎么创建它们的。然后,执行迁移(假定你已经按照文档配置好数据库)来创建数据表并填充一些数据:

php artisan migrate:fresh --seed
Dropped all tables successfully.
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Migrating: 2018_04_03_034457_create_events_table
Migrated:  2018_04_03_034457_create_events_table
Seeding: EventsSeeder

就这样,我们已经有一些假数据来继续了!

Zhibin 翻译于 2周前

配置模型

使用 Spatie 包,我们在 App\Event 模型中实现一个接口来支持 spatie/laravel-feed 包的配置。

我们有两个方法可以用来生成 Event 模型的 Feed。

  1. 方法 toFeedItem(),用以支持 Spatie Feedable 接口
  2. 静态方法 getFeedItems(),用以获取全部 Feed 项目

首先,这是基于 app/Event.php 中的 Schema 实现的 toFeedItem() 方法:

<?php

namespace App;

use Spatie\Feed\Feedable;
use Spatie\Feed\FeedItem;
use Illuminate\Database\Eloquent\Model;

class Event extends Model implements Feedable
{
    public function toFeedItem()
    {
        return FeedItem::create()
            ->id($this->id)
            ->title($this->title)
            ->summary($this->description)
            ->updated($this->updated_at)
            ->link($this->link)
            ->author($this->author);
    }
}

暂时这个方法还不能正常运行,因为我们并没有 link 属性,然而,这已经足够使我们继续了。

Zhibin 翻译于 2周前

上面,我们正在把单一模型实例转换为一个可以生成最终 RSS 格式的 FeedItem 实例。

接下来,我们要在 Event.php 文件中添加静态方法 getFeedItems()

public static function getFeedItems()
{
   return static::all();
}

我们仅需要返回一个包含 FeedItem 实例的集合。

我们需要在模型中添加的最后一个方法是 $event->link 属性访问器:

public function getLinkAttribute()
{
    return route('events.show', $this);
}

我们使用隐式路由绑定,为 Event 模型创建了用在 RSS 项中的 link 属性。

Zhibin 翻译于 2周前

路由和 Events 控制器

我们需要做的最后一部分是建立一个控制器及一个路由,好让我们的 route('events.show', $this) 能正常执行。

首先,我们建立一个控制器:

php artisan make:controller EventsController
Controller created successfully.

EventsController 内,建立一个 show() 方法,该方法返回一个包含 Event model 的 JSON 回应。我们不会在这个教学中,将 EventsController@show 返回 HTML;我将那部分留给你:

<?php

namespace App\Http\Controllers;

use App\Event;
use Illuminate\Http\Request;

class EventsController extends Controller
{
    public function show(Request $request, Event $event)
    {
        return $event;
    }
}
leochien 翻译于 2周前
rayle 审阅

接下来,我们需要在之前我们发布生成的 config/feed.php 文件中注册 RSS 源路由:

<?php

return [
    'feeds' => [
        'main' => [
            'items' => 'App\Event@getFeedItems',

            /*
             * 这个 feed 将作用于此 url 。 
             */
            'url' => '/events.rss',

            'title' => 'Upcoming Events',
        ],
    ],
];

最后,我们需要将 RSS 路由 和  EventsController@show 路由添加到 routes/web.php 底部:

Route::get('/events/{event}', 'EventsController@show')
    ->name('events.show');

Route::feeds();

Route::feeds() 方法是一个路由宏,它定义了 config/feed.php 配置文件中必要的路由。我们使用 {event} 路由参数并利用之前使用的隐式路由模型绑定来从模型内部生成事件链接。

我们现在应该能在 /events.rss 找到 RSS 源了!

wilson_yang 翻译于 2周前

连结到 Feed

你也可以借由在视图的 <head> 中加入 @include('feed::links'),以在预设的欢迎页面加入一个 RSS 连结:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>
        @include('feed::links')
{{-- ... --}}

如果你访问专案的首页,你会得到如下的 link 标签:

<link
  rel="alternate"
  type="application/rss+xml"
  href="http://127.0.0.1:8000/events.rss"
  title="Upcoming Events"
>

几乎毫不费力的,我们建立了一个用于我们的模型资料的 RSS Feed,你可以想像你需要花多小的工,以在你现有的应用中对已存在的 Model 加入 RSS。

leochien 翻译于 2周前

了解更多

浏览 laravel-feed GitHub page 获取源码和软件包设置的相关内容。

昨天我在 优化 Laravel 路由小贴士 中写了一些有关路由宏的东西,并且 Laravel 数据填充包有一个非常棒的路由宏定义在 FeedServiceProvider 中,建议去看下。

wilson_yang 翻译于 2周前

原文地址:https://laravel-news.com/learn-to-create...

译文地址:https://laravel-china.org/topics/9484/cr...


本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

回复数量: 0
    暂无评论~~

      请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!