Stay Hungry.Stay Foolish.

为 Laravel 博客添加 SiteMap 和 RSS 订阅

如何不用第三方框架,利用 Laravel 自身 Blade 引擎为 Laravel 博客添加 SiteMap 和 RSS 订阅。真的很简单!

科普

1. 什么是 SiteMap ?

SiteMap(站点地图) 是一个列出你网站网页的文件,来告知 Google 和其他搜索引擎您网站内容的组织情况。 Googlebot 等搜索引擎网络抓取工具读取此文件,以更智能地抓取您的网站。

此外,SiteMap 可以提供与网页相关联的有价值的元数据:元数据是有关网页的信息,例如上次更新网页的时间,网页更改的频率,以及网页相对于其他网页的重要性。标准的 SiteMap 协议在这里:https://www.sitemaps.org/protocol.html

XML 标签定义:

标签 描述
<urlset> 必须 包裹整个文件,声明协议
<url> 必须 包裹整个 URL 实体的父节点
<loc> 必须 网址
<lastmod> 可选 文件最后修改一次时间,格式为 W3C Datetime ,如 YYYY-MM-DD
<changefreq> 可选 文件更新频率,可选值: always, hourly, daily, weekly, monthly, yearly, never
<priority> 可选 相对你网站其他地址的权重,默认值为 0.5

XML 格式 Sitemap 样例:

<?xml version="1.0" encoding="UTF-8"?>

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

   <url>
      <loc>http://www.example.com/</loc>
      <lastmod>2005-01-01</lastmod>
      <changefreq>monthly</changefreq>
      <priority>0.8</priority>
   </url>
   <url>
      ...
   </url>
</urlset> 

详细定义参看:https://www.sitemaps.org/protocol.html

对于新建的博客来说,SiteMap 对于 SEO 优化很重要。

2. 什么是 RSS ?

RSS(简易信息聚合)是一种消息来源格式规范,用以聚合经常发布更新数据的网站,例如博客文章、新闻、音频或视频的网摘。RSS文件(或称做摘要、网络摘要、或频更新,提供到频道)包含全文或是节录的文字,再加上发布者所订阅之网摘数据和授权的元数据。

Really Simple Syndication “聚合真的很简单” 就是RSS的英文原意。把新闻标题、摘要(Feed)、内容按照用户的要求,“送”到用户的桌面就是 RSS 的目的。RSS一词有时候大体上意为社会性书签,包括各种 RSS 的不同格式。例如,Blogspace 对使用网摘于一集成器内之动作标为 RSS info 和 RSS reader。虽然它的第一个句子就包含明确的 Atom 格式:“RSS 和 Atom 文件能够用简单的格式从网站更新消息至你的电脑!”

一个 RSS 样例(详细定义看这里:维基百科):

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
 <title>RSS Title</title>
 <description>This is an example of an RSS feed</description>
 <link>http://www.example.com/main.html</link>
 <lastBuildDate>Mon, 06 Sep 2010 00:01:00 +0000 </lastBuildDate>
 <pubDate>Sun, 06 Sep 2009 16:20:00 +0000</pubDate>
 <ttl>1800</ttl>

 <item>
  <title>Example entry</title>
  <description>Here is some text containing an interesting description.</description>
  <link>http://www.example.com/blog/post/1</link>
  <guid isPermaLink="true">7bd204c6-1655-4c27-aeee-53f933c5395f</guid>
  <pubDate>Sun, 06 Sep 2009 16:20:00 +0000</pubDate>
 </item>

 <item>
   ...
 </item>

</channel>
</rss>

用 Laravel 实现你博客的 SiteMap 和 RSS

Laravel 的 Blade 模板引擎实质解析的是 XML 文件,因为 HTML 文档也是一种 XML 文件,所以 Blade 可以解析 HTML 文件。而 SiteMap 和 RSS 通常为 XML 文件,因此用 Blade 生成 SiteMap 和 RSS 就很简单了。

为什么不使用第三方库?Laravel 有很多第三方库来实现 SiteMap 和 RSS ,但是因为为自己的博客实现 SiteMap 和 RSS 太简单了,依赖一个第三方库在性能和灵活性上总有不妥之处。

首先注册路由:

// SiteMap
Route::get('sitemap', 'GeneratedController@siteMap');
Route::get('sitemap.xml', 'GeneratedController@siteMap');

// RSS Feed
Route::get('feed.xml', 'GeneratedController@feed');

GeneratedController:

public function siteMap()
{
    $view = chche()->remember('generated.sitemap', function () {
        $posts = Post:all();
        // return generated xml (string) , cache whole file
        return view('generated.sitemap', compact('posts'))->render();
    });
    return response($view)->header('Content-Type', 'text/xml');
}

public function feed()
{
    $view = chche()->remember('generated.feed', function () {
        $posts = Post:all(); 
        // return generated xml (string) , cache whole file
        return view('generated.feed', compact('posts'))->render(); 
    });
    return response($view)->header('Content-Type', 'text/xml');
}

generated\sitemap.blade.php:

<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>{{ route('index') }}</loc>
        <changefreq>weekly</changefreq>
        <priority>1.0</priority>
    </url>
    @foreach ($posts as $post)
        <url>
            <loc>{{ route('post.show',$post->slug) }}</loc>
            <lastmod>{{ $post->updated_at->tz('UTC')->toAtomString() }}</lastmod>
            <changefreq>daily</changefreq>
            <priority>0.9</priority>
        </url>
    @endforeach
</urlset>

generated\feed.blade.php:

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>{{ $site_title or 'Xblog' }}</title>
        <description>{{ $description or 'Description' }}</description>
        <link>{{ url('/') }}</link>
        <atom:link href="{{ url('/feed.xml') }}" rel="self" type="application/rss+xml"/>
        <?php
        $date = !empty($posts) ? $posts[0]->updated_at->format('D, d M Y H:i:s O') : date("D, d M Y H:i:s O", time())
        ?>
        <pubDate>{{ $date }}</pubDate>
        <lastBuildDate>{{ $date }}</lastBuildDate>
        <generator>lufficc</generator>
        @foreach ($posts as $post)
            <item>
                <title>{{ $post->title }}</title>
                <link>{{ route('post.show',$post->slug) }}</link>
                <description>{{ $post->description }}</description>
                <pubDate>{{ $post->created_at->format('D, d M Y H:i:s T') }}</pubDate>
                <author>{{ $post->user->email }} ({{$post->user->name}})</author>
                <guid>{{ route('post.show',$post->slug) }}</guid>
                <category>{{ $post->category->name }}</category>
            </item>
        @endforeach
    </channel>
</rss>

然后订阅地址就为:

 <a href="{{ url('feed.xml') }}" rel="feed" type="application/rss+xml" title="Feed">RSS</a>

你还可以在这里验证你的 RSS 是否规范:https://validator.w3.org/feed/ ,你可以试试我的订阅地址是否规范:https://lufficc.com/feed.xml (囧,当然规范了,因为我验证过了。。。。。。。)【注意header('Content-Type', 'text/xml'),这样在浏览器中查看会识别出 是 XML 文件,高亮显示文件】

到此大功告成,就是这么简单。。。。 顺便还用了缓存, viewrender() 方法是 xml 解析后的 string 字符串,注意直接的 view 对象不能被缓存,因为 view 对象不支持序列化。直接缓存 string ,顺便也把解析过程 “缓存”’(节省解析时间)了。

当然,博客简单,只写了和 Post 相关的内容,但是原理大家已经明白,可以随意添加自己的逻辑(Xblog 使用了此方法实现 RSS 和 SiteMap),而且,简单的博客真的不需要第三方库来实现吧。。。

⬆️

写的不错,帮助到了您,赞助一下主机费~

扫一扫,用支付宝赞赏
扫一扫,用微信赞赏
如何安装Xblog 2016-09-22
2017-02-11 09:47

第一个评论。。。支持一下

2017-02-15 13:59

wow amazing

2017-02-16 11:15

@atc 测试下

2017-03-25 02:23

测试

2018-10-18 15:31

正学习,谢谢你。