为 Laravel 博客添加 SiteMap 和 RSS 订阅
原文地址:为 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.sitemap', 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 文件,高亮显示文件】
到此大功告成,就是这么简单。。。。 顺便还用了缓存, view
的 render()
方法是 xml
解析后的 string
字符串,注意直接的 view
对象不能被缓存,因为 view
对象不支持序列化。直接缓存 string
,顺便也把解析过程 “缓存”’(节省解析时间)了。
当然,博客简单,只写了和 Post
相关的内容,但是原理大家已经明白,可以随意添加自己的逻辑(Xblog 使用了此方法实现 RSS 和 SiteMap),而且,简单的博客真的不需要第三方库来实现吧。。。
支持一下。。。。
路飞 66
怎么不写个 Package
加个RSS,就直接订阅了