Yii实现Sitemap的自动生成

我根据自己博客的性质,进行了自己网站的Sitemap的开发。实现过程比较简单,效果还是比较令我满意的。关键是格式比较重要,还有在生成的过程中,有个在查看的时候,能够有个比较好的ui效果的设置。下面把我的Sitemap的生成代码记录如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php
class Sitemap extends CController{
protected $webSiteTitle = '';
protected $changefreq = '';
protected $content = '';
protected $priority = '';
protected $blogItems = array();
protected $tagItems = array();
protected $categoryItems = array();
protected $items = array();
/**
* 添加基本信息
* @param string $title
* @param string $link
* @param string $description
*/
public function __construct() {
$this->webSiteTitle = 'http://'.$_SERVER['SERVER_NAME'];
$this->changefreq = 'daily';//always hourly daily weekly monthly yearly never
$this->priority = 0.5;
}

/**
* 分类
*/
private function categorySitemap(){
$criteria = new CDbCriteria();
$criteria->condition = 'category=:category';
$criteria->params = array(':category'=>'blog');
$criteria->order = 'create_date DESC';
$result = Type::model()->findAll($criteria);

foreach($result as $k=>$v){
$this->categoryItems[] = array(
'url'=>$this->webSiteTitle.'/category/'.urlencode($v->name),
'date'=>date(DATE_W3C, strtotime($v->update_date))
);
}
}

/**
* 文章
*/
private function blogSitemap(){
$criteria = new CDbCriteria();
$criteria->condition = 'is_lock=0 and is_delete=0';
$criteria->select = 'id, tag, update_date';
$criteria->order = 'create_date DESC';
$model = Blog::model()->findAll($criteria);
foreach($model as $k=>$v){
$this->blogItems[] = array(
'url'=>$this->webSiteTitle.'/blog/'.$v->id,
'date'=>date(DATE_W3C, strtotime($v->update_date))
);

$tagArr = preg_split('#,|,#i', $v->tag);

if(!empty($tagArr)){
foreach($tagArr as $k=>$v){
if(!in_array($v,$this->tagItems)){
$this->tagItems[] = $v;
}
}
}
}

//创建临时函数数组
$tmp = array();
$tmp = $this->tagItems;
$this->tagItems = array();
foreach($tmp as $k=>$v){
$this->tagItems[] = array(
'url'=>$this->webSiteTitle.'/tag/'.urlencode($v),
'date'=>date(DATE_W3C, time())
);
}
unset($tmp);
}


/**
* 构建xml元素
*/
public function buildSitemap() {
$blogitem = '';
foreach($this->blogItems as $k=>$v){
$blogitem .= <<<BLOG
<url>\r\n
<loc>{$v['url']}</loc>\r\n
<lastmod>{$v['date']}</lastmod>\r\n
<changefreq>{$this->changefreq}</changefreq>\r\n
<priority>{$this->priority}</priority>\r\n
</url>\r\n
BLOG;

}

$categoryitem = '';
foreach($this->categoryItems as $k=>$v){
$categoryitem .= <<<BLOG
<url>\r\n
<loc>{$v['url']}</loc>\r\n
<lastmod>{$v['date']}</lastmod>\r\n
<changefreq>{$this->changefreq}</changefreq>\r\n
<priority>{$this->priority}</priority>\r\n
</url>\r\n
BLOG;

}
$tagitem = '';
foreach($this->tagItems as $k=>$v){
$tagitem .= <<<BLOG
<url>\r\n
<loc>{$v['url']}</loc>\r\n
<lastmod>{$v['date']}</lastmod>\r\n
<changefreq>{$this->changefreq}</changefreq>\r\n
<priority>{$this->priority}</priority>\r\n
</url>\r\n
BLOG;

}


$this->content = <<<SITEMAP
<?xml version='1.0' encoding='UTF-8'?>\r\n
<?xml-stylesheet type="text/xsl" href="{$this->webSiteTitle}/sitemap.xsl"?>
<!-- generator="GoWhich/1.0" -->
<!-- sitemap-generator-url="{$this->webSiteTitle}" sitemap-generator-version="1.0.0" -->
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r\n
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"\r\n
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\r\n
{$blogitem}
{$categoryitem}
{$tagitem}
</urlset>\r\n
SITEMAP;
}

/**
* 输出sitemap内容
*/
function show() {
$this->blogSitemap();
$this->categorySitemap();
if (empty($this->content)) {
$this->buildSitemap();
}
return $this->content;
}


/**
* 将rss保存为文件
* @param String $fname
* @return boolean
*/
function saveToFile($fname) {
$handle = fopen($fname, 'wb');
if ($handle === false){
return false;
}
fwrite($handle, $this->content);
fclose($handle);
}

/**
* 获取文件的内容
* @param String $fname
* @return boolean
*/
function getFile($fname) {
$handle = fopen($fname, 'r');
if ($handle === false){
return false;
}
while(!feof($handle)){
echo fgets($handle);
}
fclose($handle);
}
}
?>

Controller中我建立了两个action

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* sitemap列表
*/
public function actionSitemap(){

//rss创建
$obj = new Sitemap();

$this->render('sitemap',array('rss'=>$obj->show()));
}

public function actionSitemapXsl(){
$this->render('sitemapxsl');
}

View的两个文件的代码如下

sitemap.php

1
2
3
4
5
6
<?php
/* @var $this FeedController */
header("Content-Type: text/xml; charset=utf-8");
echo $rss;
exit;
?>

sitemapxsl.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
header("Content-Type: text/xml; charset=utf-8");
?>
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XML Sitemap</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
font-family:"Lucida Grande","Lucida Sans Unicode",Tahoma,Verdana;
font-size:13px;
}

#intro {
background-color:#CFEBF7;
border:1px #2580B2 solid;
padding:5px 13px 5px 13px;
margin:10px;
}

#intro p {
line-height: 16.8667px;
}

td {
font-size:11px;
}

th {
text-align:left;
padding-right:30px;
font-size:11px;
}

tr.high {
background-color:whitesmoke;
}

#footer {
padding:2px;
margin:10px;
font-size:8pt;
color:gray;
}

#footer a {
color:gray;
}

a {
color:black;
}
</style>
</head>
<body>
<h1>XML Sitemap</h1>
<div id="intro">
<p>
This is a XML Sitemap which is supposed to be processed by search engines like <a href="http://www.google.com">Google</a>, <a href="http://search.msn.com">MSN Search</a> and <a href="http://www.yahoo.com">YAHOO</a>.<br />
It was generated using the Blogging-Software <a href="http://gowhich.com/">GoWhich</a> and the <a href="http://www.gowhich.com/sitemap.xml" title="Google Sitemap Generator Plugin for GoWhich">Google Sitemap Generator Plugin</a> by <a href="http://www.gowhich.com/">GoWhich</a>.<br />
You can find more information about XML sitemaps on <a href="http://sitemaps.org">sitemaps.org</a> and Google's <a href="http://code.google.com/sm_thirdparty.html">list of sitemap programs</a>.
</p>
</div>
<div id="content">
<table cellpadding="5">
<tr style="border-bottom:1px black solid;">
<th>URL</th>
<th>Priority</th>
<th>Change Frequency</th>
<th>LastChange (GMT)</th>
</tr>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<xsl:if test="position() mod 2 != 1">
<xsl:attribute name="class">high</xsl:attribute>
</xsl:if>
<td>
<xsl:variable name="itemURL">
<xsl:value-of select="sitemap:loc"/>
</xsl:variable>
<a href="{\$itemURL}">
<xsl:value-of select="sitemap:loc"/>
</a>
</td>
<td>
<xsl:value-of select="concat(sitemap:priority*100,'%')"/>
</td>
<td>
<xsl:value-of select="concat(translate(substring(sitemap:changefreq, 1, 1),concat(\$lower, \$upper),concat(\$upper, \$lower)),substring(sitemap:changefreq, 2))"/>
</td>
<td>
<xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))"/>
</td>
</tr>
</xsl:for-each>
</table>
</div>
<div id="footer">
Generated with <a href="http://www.gowhich.com/sitemap.xml" title="Google Sitemap Generator Plugin for GoWhich">Google Sitemap Generator Plugin for GoWhich</a> by <a href="http://www.gowhich.com/">GoWhich</a>. This XSLT template is released under GPL.
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XML;
echo $xml;
exit;
?>

为了使得url看起来好看一点。

我做了一下路由设置

1
2
'sitemap.xsl'=>'site/sitemapxsl',
'sitemap.xml'=>'site/sitemap',