mykemeynell/laravel-syndication

为 Laravel 提供的 RSS 和 Atom 订阅源

v1.2.1 2023-02-21 11:47 UTC

This package is auto-updated.

Last update: 2024-09-21 15:12:06 UTC


README

一个用于 Laravel 的简单 RSS 和 Atom 订阅源包。可以为指定的模型生成 RSS、Atom 或两者都生成。

安装

composer require mykemeynell/laravel-syndication

使用自动发现

服务提供者已经注册,因此您可以继续下一步。

不使用自动发现

LaravelSyndicationServiceProvider 添加到您的 config/app.php 文件。

    'providers' => [
        // ...
        LaravelSyndication\LaravelSyndicationServiceProvider::class,
        // ...    
    ],

发布配置

这将创建一个新配置文件在 config/syndication.php

php artisan vendor:publish --tag=laravel-syndication

配置

订阅源

/*
 * Feeds that can be used for syndication are defined here. This should be
 * done using a key-value pair -- where the key is the identifier
 * of the feed, adn the value is the feed object.
 *
 * For example:
 *  'posts' => App\Feeds\Posts::class
 */
'feeds' => [],

路由

'routing' => [
    /*
     *  Sets the prefix of any generated feeds.
     * default is 'feeds'.
     */
    'prefix' => 'feeds',
    
    /*
     * If you'd like to serve your feeds from a separate domain
     * or subdomain - you can specify the domain here.
     */ 
    'domain' => null,
],

编码

/*
 * Encoding for the generated files, it will default to utf8 if there is no
 * other value specified -- so if you'd like a simpler config
 * file, then feel free to remove this key.
 */
'encoding' => 'utf-8',

缓存

设置所有订阅源的默认缓存值。如果设置为 false,则不会缓存任何内容,并且不会读取当前缓存的值。

'cache_feeds' => true,

指定要使用的缓存存储。使用 null 将默认使用默认缓存存储。

'cache_store' => null,

缓存有效的时间(以分钟为单位)。

'cache_ttl' => 1440,

如果您想为不同的订阅源指定不同的 TTL,则可以在这里进行操作。应该使用与 feeds 键数组中定义的相同键进行索引,并附加订阅源类型,例如;'podcasts.atom''podcasts.rss'

要禁用特定订阅源的缓存,请将值设置为 false

要禁用所有订阅源的缓存(除指定的订阅源外),请将 cache_feeds 设置为 false,并在 caching 中指定一个大于 0 的值。

'caching' => [
    'posts.atom' => 10080
],

用法

创建新的订阅源

使用 artisan 创建新的订阅源类。

例如,如果您想为播客创建订阅源;

php artisan make:feed Postcasts

这将输出一个位于 app/Feeds/Postcasts.php 的订阅源类对象。

将订阅源类添加到 config/syndication.php

feeds 键下,添加您刚刚创建的订阅源的完全限定名称。

'feeds' => [
    // ...
    'podcasts' => App\Feeds\Postcasts::class
    // ...
],

配置 Feed

订阅源类型

使用以下基类来确定可以生成的订阅源类型,以及 setUp() 方法中可用的方法。

配置方法

setUp() 方法中完成对订阅源对象的全部配置。

例如

namespace App\Feeds;

class Podcast extends RssAndAtomFeed
{
  public function setUp(): void
  {
    $this->model(\App\Models\Podcast::class)
      ->title("Awesome Podcast")
      ->description("An amazing podcast.")
      ->url(url('/podcasts'))
      ->language("en")
      ->updated($this->lastCachedAt());
  }
}

配置订阅源模型

一旦您创建了订阅源对象并指定了在生成订阅源内容时希望使用的模型和过滤器,您需要将 LaravelSyndication\Contracts\Models\IsSyndicationItem 接口添加到您的模型中。

IsSyndicationItem 接口指定了一个方法 toFeedItem,该方法期望返回一个 LaravelSyndication\Feeds\FeedItem 实例。

例如

function toFeedItem(): FeedItem
{
    return (new FeedItem())
        ->title($this->title)
        ->description($this->excerpt)
        ->url(route('postcast.listen', $this->slug));
}

如果您更喜欢使用关联数组创建订阅源项,可以将它作为参数传递给 FeedItem 构造函数。例如

function toFeedItem(): FeedItem
{
    return new FeedItem([
        'title' => $this->title,
        'description' => $this->excerpt,
        'url' => route('podcast.listen', $this->slug)    
    ]);
}

创建订阅源项时也有其他选项可用

/**
 * Will specify the URL for comments.  
 */
FeedItem::comments(string $commentsUrl)
/**
 * The email address of the feed item author.
 *
 * Can be specified as an array or Collection of \LaravelSyndication\Feeds\Structure\Atom\Person objects,
 * or a single LaravelSyndication\Feeds\Structure\Atom\Person object.
 */
FeedItem::author(array|Collection|Person $author)
/**
 * Includes a media file to be included with an item.
 * 
 * The enclosure method accepts either 2, or 4 arguments, depending on what data you pass:
 * 
 * @param string      $url      The public URL to the enclosure item.
 * @param int|null    $length   Filesize in bytes -- if omitted, then an attempt to read the file is made.
 * @param string|null $type     MIME type of the enclosure -- required if $filename is null.
 * @param string|null $filename Optional, can be left blank if $length and $type are specified.
 */
FeedItem::enclosure(string $url, ?string $type = null, ?string $filename = null, ?int $length = null)
/**
 * Specifies the value of the <id> tag on an <entry>.
 * 
 * If a Uuid instance of string is passed, then it is prepended with 'urn:uuid:'
 * before being output. Otherwise, it is output as it is passed.
 * 
 * This method can be omitted, and the value of the url() method will be used. 
 * 
 * Atom only. 
 */
FeedItem::id(int|\Ramsey\Uuid\Uuid|string $idUri)
/**
 * Specifies the <content> tag of the <entry>.
 * 
 * Atom only. 
 */
FeedItem::content(null|string|\LaravelSyndication\Feeds\Structure\Atom\Content $content)
/**
 * When specified, the value of FeedItem::content() is ignored and content is 
 * generated from a passed enclosure instead.
 * 
 * Note: If used, this should be called after FeedItem::enclosure().
 * 
 * Atom only. 
 */
FeedItem::contentFromEnclosure()
/**
 * Sets the <updated> tag on an entry.
 *
 * Atom only. 
 */
FeedItem::updated(\Carbon\Carbon $updated)
/**
 * Atom: Sets the <published> tag on an entry.
 * RSS: Sets the <pubDate> tag on an item. 
 */
FeedItem::published(\Carbon\Carbon $published)
/**
 * Sets the <rights> attribute on an entry.
 * 
 * Atom only. 
 */
FeedItem::copyright(string $copyright)
/**
 * Sets the value of the <category> tag on an <entry>.
 *
 * Atom only. 
 */
FeedItem::category(string $term)
/**
 * Used to specify the <source> tag of an <entry>, for example if the <entry>
 * is a copy, or references another source. 
 */
FeedItem::source(\LaravelSyndication\Feeds\Structure\Items\Atom\Source $source)

以下是如何配置源的示例

FeedItem::source(
  new Source(
    id: route('podcast.listen', $this->getKey()),
    title: $this->title,
    updated: $this->updated_at,
    author: new Person(name: $this->author->name, email: $this->author->email)
  )
)

完全配置的模型示例

function toFeedItem(): FeedItem
{
  return (new FeedItem())
    // Using the ID method assumes that the model is making use of UUID
    // primary keys.
    ->id($this->getKey()) 
    
    // These are the common fields between Atom and RSS fields.
    ->title($this->seo_title ?? $this->title)
    ->description($this->meta_description ?? $this->excerpt ?? $this->title)
    ->url(route('podcast.listen', $this->getKey()))
    
    // The URL for comments.
    // This is only used in RSS feeds and is not output as part of Atom.
    ->comments(route('podcast.single', $this->slug . '#comments'))
    
    // Atom feeds will output specific <author> tags, whereas RSS
    // will output a comma-separated list of email addresses.
    ->author([
        new Person(name: $this->authorId->name, email: $this->authorId->email),
        new Person(name: $this->authorId->name, email: $this->authorId->email),
    ])
    
    // Specifies the data to be used in the <enclosure> tag in an RSS feed.
    // can be used in conjunction with FeedItem::contentFromEnclosure() to 
    // create the appropriate <content> tag on an Atom feed.
    ->enclosure(
        url: route('post.read', $this->slug), 
        filename: storage_path('podcasts/' . $this->podcast_file_location)
    )
    
    // ... Like this.
    ->contentFromEnclosure()
    
    // Sets the value of the <updated> tag. Only used as part of Atom feeds.
    ->updated($this->updated_at)
    
    // Sets the value of the <published> or <pubDate> tag in Atom and RSS
    // feeds respectively.
    ->published($this->published_at)
    
    // Copyright information relating specifically to an entry on an Atom feed
    // <entry> item.
    ->copyright("Copyright 2022 Acme Inc.")
    
    // Copyright information relating specifically to an entry on an Atom feed
    // <entry> item.
    ->category("Tech")
    
    // Builds the value of the <source> tag.
    // Statically typed here -- but you get the idea of what it does.
    ->source(
        new Source(
            id: 'https://example.com/some-unqiue-url-that-wont-change',
            title: 'The Title of The Source',
            updated: now(),
            author: new Person(name: "John Doe", email: "john@example.com", uri: "https://example.com/authors/john")
        )
    );
}

输出元标签到视图

将以下代码添加到您的 blade 视图中以输出已注册订阅源的元标签。

这些使用外观的别名为:LaravelSyndication\Facades\Syndicate

输出所有已注册订阅源的元标签

<head>
{!! LaravelSyndication::meta() !!}
</head>

输出特定订阅源的元标签

<head>
{!! LaravelSyndication::meta('podcasts', 'blog') !!}
</head>