mirror of https://github.com/halo-dev/halo
🎨 修改rss/sitemap的渲染方式,新增html形式的sitemap
parent
1bb6b72cb3
commit
d68d7019f0
8
pom.xml
8
pom.xml
|
@ -34,7 +34,6 @@
|
|||
<oh-my-email.version>0.0.4</oh-my-email.version>
|
||||
<lombok.version>1.18.4</lombok.version>
|
||||
<ehcache.version>3.6.3</ehcache.version>
|
||||
<rome.version>1.0</rome.version>
|
||||
<hutool-all.version>4.4.2</hutool-all.version>
|
||||
<upyun-java-sdk.version>4.0.1</upyun-java-sdk.version>
|
||||
<qiniu-java-sdk.version>7.2.18</qiniu-java-sdk.version>
|
||||
|
@ -120,13 +119,6 @@
|
|||
<version>${ehcache.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- rss -->
|
||||
<dependency>
|
||||
<groupId>rome</groupId>
|
||||
<artifactId>rome</artifactId>
|
||||
<version>${rome.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- hutool工具包 -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
|
|
|
@ -83,8 +83,7 @@ public class WebMvcAutoConfiguration implements WebMvcConfigurer {
|
|||
registry.addResourceHandler("/static/**")
|
||||
.addResourceLocations("classpath:/static/");
|
||||
registry.addResourceHandler("/**")
|
||||
.addResourceLocations("classpath:/templates/themes/")
|
||||
.addResourceLocations("classpath:/robots.txt");
|
||||
.addResourceLocations("classpath:/templates/themes/");
|
||||
registry.addResourceHandler("/upload/**")
|
||||
.addResourceLocations("file:///" + System.getProperties().getProperty("user.home") + "/halo/upload/");
|
||||
registry.addResourceHandler("/favicon.ico")
|
||||
|
|
|
@ -248,22 +248,6 @@ public interface PostService {
|
|||
*/
|
||||
Integer getCountByStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 生成rss
|
||||
*
|
||||
* @param posts posts
|
||||
* @return String
|
||||
*/
|
||||
String buildRss(List<Post> posts);
|
||||
|
||||
/**
|
||||
* 生成sitemap
|
||||
*
|
||||
* @param posts posts
|
||||
* @return String
|
||||
*/
|
||||
String buildSiteMap(List<Post> posts);
|
||||
|
||||
/**
|
||||
* 缓存阅读数
|
||||
*
|
||||
|
|
|
@ -508,36 +508,6 @@ public class PostServiceImpl implements PostService {
|
|||
return postRepository.countAllByPostStatusAndPostType(status, PostTypeEnum.POST_TYPE_POST.getDesc());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成rss
|
||||
*
|
||||
* @param posts posts
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String buildRss(List<Post> posts) {
|
||||
String rss = "";
|
||||
try {
|
||||
rss = HaloUtils.getRss(posts);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return rss;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成sitemap
|
||||
*
|
||||
* @param posts posts
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@Override
|
||||
public String buildSiteMap(List<Post> posts) {
|
||||
return HaloUtils.getSiteMap(posts);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存阅读数
|
||||
*
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
package cc.ryanc.halo.utils;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.BackupDto;
|
||||
import cc.ryanc.halo.model.dto.Theme;
|
||||
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
|
||||
import cc.ryanc.halo.model.enums.CommonParamsEnum;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.text.StrBuilder;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.sun.syndication.feed.rss.Channel;
|
||||
import com.sun.syndication.feed.rss.Content;
|
||||
import com.sun.syndication.feed.rss.Item;
|
||||
import com.sun.syndication.io.FeedException;
|
||||
import com.sun.syndication.io.WireFeedOutput;
|
||||
import io.github.biezhi.ome.OhMyEmail;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.Assert;
|
||||
|
@ -32,8 +24,6 @@ import java.nio.file.attribute.BasicFileAttributeView;
|
|||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
|
||||
import static cc.ryanc.halo.model.dto.HaloConst.OPTIONS;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 常用工具
|
||||
|
@ -285,84 +275,6 @@ public class HaloUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成rss
|
||||
*
|
||||
* @param posts posts
|
||||
*
|
||||
* @return String
|
||||
*
|
||||
* @throws FeedException FeedException
|
||||
*/
|
||||
public static String getRss(List<Post> posts) throws FeedException {
|
||||
Assert.notEmpty(posts, "posts must not be empty");
|
||||
|
||||
final Channel channel = new Channel("rss_2.0");
|
||||
if (null == OPTIONS.get(BlogPropertiesEnum.BLOG_TITLE.getProp())) {
|
||||
channel.setTitle("");
|
||||
} else {
|
||||
channel.setTitle(OPTIONS.get(BlogPropertiesEnum.BLOG_TITLE.getProp()));
|
||||
}
|
||||
if (null == OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp())) {
|
||||
channel.setLink("");
|
||||
} else {
|
||||
channel.setLink(OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()));
|
||||
}
|
||||
if (null == OPTIONS.get(BlogPropertiesEnum.SEO_DESC.getProp())) {
|
||||
channel.setDescription("");
|
||||
} else {
|
||||
channel.setDescription(OPTIONS.get(BlogPropertiesEnum.SEO_DESC.getProp()));
|
||||
}
|
||||
channel.setLanguage("zh-CN");
|
||||
final List<Item> items = new ArrayList<>();
|
||||
for (Post post : posts) {
|
||||
final Item item = new Item();
|
||||
item.setTitle(post.getPostTitle());
|
||||
final Content content = new Content();
|
||||
String value = post.getPostContent();
|
||||
final char[] xmlChar = value.toCharArray();
|
||||
for (int i = 0; i < xmlChar.length; ++i) {
|
||||
if (xmlChar[i] > 0xFFFD) {
|
||||
xmlChar[i] = ' ';
|
||||
} else if (xmlChar[i] < 0x20 && xmlChar[i] != 't' & xmlChar[i] != 'n' & xmlChar[i] != 'r') {
|
||||
xmlChar[i] = ' ';
|
||||
}
|
||||
}
|
||||
value = new String(xmlChar);
|
||||
content.setValue(value);
|
||||
item.setContent(content);
|
||||
item.setLink(OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/" + post.getPostUrl());
|
||||
item.setPubDate(post.getPostDate());
|
||||
items.add(item);
|
||||
}
|
||||
channel.setItems(items);
|
||||
final WireFeedOutput out = new WireFeedOutput();
|
||||
return out.outputString(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sitemap
|
||||
*
|
||||
* @param posts posts
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String getSiteMap(List<Post> posts) {
|
||||
Assert.notEmpty(posts, "post mut not be empty");
|
||||
final StrBuilder head = new StrBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">");
|
||||
final StrBuilder urlBody = new StrBuilder();
|
||||
final String urlPath = OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/";
|
||||
for (Post post : posts) {
|
||||
urlBody.append("<url><loc>");
|
||||
urlBody.append(urlPath);
|
||||
urlBody.append(post.getPostUrl());
|
||||
urlBody.append("</loc><lastmod>");
|
||||
urlBody.append(DateUtil.format(post.getPostDate(), "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"));
|
||||
urlBody.append("</lastmod></url>");
|
||||
}
|
||||
return head.append(urlBody).append("</urlset>").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置邮件
|
||||
*
|
||||
|
|
|
@ -1,23 +1,28 @@
|
|||
package cc.ryanc.halo.web.controller.front;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
|
||||
import cc.ryanc.halo.model.enums.PostTypeEnum;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import freemarker.template.Template;
|
||||
import freemarker.template.TemplateException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static cc.ryanc.halo.model.dto.HaloConst.*;
|
||||
import static cc.ryanc.halo.model.dto.HaloConst.OPTIONS;
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
|
@ -33,51 +38,102 @@ public class FrontOthersController {
|
|||
@Autowired
|
||||
private PostService postService;
|
||||
|
||||
@Autowired
|
||||
private FreeMarkerConfigurer freeMarker;
|
||||
|
||||
/**
|
||||
* 获取文章rss
|
||||
*
|
||||
* @return rss
|
||||
* @param model model
|
||||
*
|
||||
* @return String
|
||||
*
|
||||
* @throws IOException IOException
|
||||
* @throws TemplateException TemplateException
|
||||
*/
|
||||
@GetMapping(value = {"feed", "feed.xml", "atom", "atom.xml"}, produces = "application/xml;charset=UTF-8")
|
||||
@ResponseBody
|
||||
public String feed() {
|
||||
public String feed(Model model) throws IOException, TemplateException {
|
||||
String rssPosts = OPTIONS.get(BlogPropertiesEnum.RSS_POSTS.getProp());
|
||||
if (StrUtil.isBlank(rssPosts)) {
|
||||
rssPosts = "20";
|
||||
}
|
||||
//获取文章列表并根据时间排序
|
||||
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
|
||||
final Pageable pageable = PageRequest.of(0, Integer.parseInt(rssPosts), sort);
|
||||
final Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), pageable).map(post -> {
|
||||
if(StrUtil.isNotEmpty(post.getPostPassword())){
|
||||
if (StrUtil.isNotEmpty(post.getPostPassword())) {
|
||||
post.setPostContent("该文章为加密文章");
|
||||
post.setPostSummary("该文章为加密文章");
|
||||
}
|
||||
return post;
|
||||
});
|
||||
final List<Post> posts = postsPage.getContent();
|
||||
return postService.buildRss(posts);
|
||||
model.addAttribute("posts", posts);
|
||||
final Template template = freeMarker.getConfiguration().getTemplate("common/web/rss.ftl");
|
||||
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取sitemap
|
||||
* 获取 XML 格式的站点地图
|
||||
*
|
||||
* @return sitemap
|
||||
* @param model model
|
||||
*
|
||||
* @return String
|
||||
*
|
||||
* @throws IOException IOException
|
||||
* @throws TemplateException TemplateException
|
||||
*/
|
||||
@GetMapping(value = {"sitemap", "sitemap.xml"}, produces = "application/xml;charset=UTF-8")
|
||||
@ResponseBody
|
||||
public String siteMap() {
|
||||
//获取文章列表并根据时间排序
|
||||
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
|
||||
final Pageable pageable = PageRequest.of(0, 999, sort);
|
||||
final Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), pageable).map(post -> {
|
||||
if(StrUtil.isNotEmpty(post.getPostPassword())){
|
||||
public String sitemapXml(Model model) throws IOException, TemplateException {
|
||||
final Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), null).map(post -> {
|
||||
if (StrUtil.isNotEmpty(post.getPostPassword())) {
|
||||
post.setPostContent("该文章为加密文章");
|
||||
post.setPostSummary("该文章为加密文章");
|
||||
}
|
||||
return post;
|
||||
});
|
||||
final List<Post> posts = postsPage.getContent();
|
||||
return postService.buildSiteMap(posts);
|
||||
model.addAttribute("posts", posts);
|
||||
final Template template = freeMarker.getConfiguration().getTemplate("common/web/sitemap_xml.ftl");
|
||||
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 HTML 格式的站点地图
|
||||
*
|
||||
* @param model model
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping(value = "sitemap.html", produces = {"text/html"})
|
||||
public String sitemapHtml(Model model) {
|
||||
final Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), null).map(post -> {
|
||||
if (StrUtil.isNotEmpty(post.getPostPassword())) {
|
||||
post.setPostContent("该文章为加密文章");
|
||||
post.setPostSummary("该文章为加密文章");
|
||||
}
|
||||
return post;
|
||||
});
|
||||
final List<Post> posts = postsPage.getContent();
|
||||
model.addAttribute("posts", posts);
|
||||
return "common/web/sitemap_html";
|
||||
}
|
||||
|
||||
/**
|
||||
* robots
|
||||
*
|
||||
* @param model model
|
||||
*
|
||||
* @return String
|
||||
*
|
||||
* @throws IOException IOException
|
||||
* @throws TemplateException TemplateException
|
||||
*/
|
||||
@GetMapping(value = "robots.txt", produces = {"text/plain"})
|
||||
@ResponseBody
|
||||
public String robots(Model model) throws IOException, TemplateException {
|
||||
final Template template = freeMarker.getConfiguration().getTemplate("common/web/robots.ftl");
|
||||
return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
User-agent: *
|
||||
Disallow: /admin/
|
||||
Sitemap: /sitemap.xml
|
|
@ -0,0 +1,4 @@
|
|||
User-agent: *
|
||||
Disallow: /admin/
|
||||
Sitemap: ${options.blog_url!}/sitemap.xml
|
||||
Sitemap: ${options.blog_url!}/sitemap.html
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
|
||||
<channel>
|
||||
<title>${options.blog_title!}</title>
|
||||
<link>${options.blog_url!}</link>
|
||||
<#if user.userDesc??>
|
||||
<description>${user.userDesc!}</description>
|
||||
</#if>
|
||||
<language>zh-CN</language>
|
||||
<#if posts?? && posts?size gt 0>
|
||||
<#list posts as post>
|
||||
<item>
|
||||
<title>${post.postTitle!}</title>
|
||||
<link>${options.blog_url}/archives/${post.postUrl!}</link>
|
||||
<content:encoded>${post.postContent!}</content:encoded>
|
||||
<pubDate>${post.postDate}</pubDate>
|
||||
</item>
|
||||
</#list>
|
||||
</#if>
|
||||
</channel>
|
||||
</rss>
|
|
@ -0,0 +1,201 @@
|
|||
<#--
|
||||
see https://gitee.com/yadong.zhang/DBlog/blob/master/blog-web/src/main/java/com/zyd/blog/controller/RestWebSiteController.java
|
||||
-->
|
||||
<#compress >
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>${options.blog_title!} 网站地图</title>
|
||||
<meta name="robots" content="index,follow"/>
|
||||
<style type="text/css">
|
||||
body {
|
||||
color: #000000;
|
||||
background: #ffffff;
|
||||
margin: 20px;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#myTable {
|
||||
list-style: none;
|
||||
margin: 10px 0px 10px 0px;
|
||||
padding: 0px;
|
||||
width: 100%;
|
||||
min-width: 804px;
|
||||
}
|
||||
|
||||
#myTable li {
|
||||
list-style-type: none;
|
||||
width: 100%;
|
||||
min-width: 404px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.pull-left{
|
||||
float: left!important;
|
||||
}
|
||||
.pull-right{
|
||||
float: right!important;
|
||||
}
|
||||
|
||||
#myTable li .T1-h {
|
||||
font-weight: bold;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
#myTable li .T2-h {
|
||||
width: 200px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#myTable li .T3-h {
|
||||
width: 200px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#myTable li .T4-h {
|
||||
width: 100px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#myTable li .T1 {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
#myTable li .T2 {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#myTable li .T3 {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
#myTable li .T4 {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
#footer {
|
||||
padding: 2px;
|
||||
margin: 0px;
|
||||
font-size: 8pt;
|
||||
color: gray;
|
||||
min-width: 900px;
|
||||
}
|
||||
|
||||
#footer a {
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.myClear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#nav, #content, #footer {
|
||||
padding: 8px;
|
||||
border: 1px solid #EEEEEE;
|
||||
clear: both;
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* 窗口缩小到768px以下时 */
|
||||
@media (max-width: 768px) {
|
||||
.T2-h, .T3-h, .T4-h, .T2, .T3, .T4 {
|
||||
display: none;
|
||||
}
|
||||
#myTable, #footer, #myTable li .T1, #myTable li, #myTable li .T1-h, #myTable li .T1 {
|
||||
max-width: 100%;
|
||||
min-width: auto;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* 窗口放大到768px以上时 */
|
||||
@media (min-width: 768px) {
|
||||
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2 style="text-align: center; margin-top: 20px">${options.blog_title!} 网站地图 </h2>
|
||||
<div id="nav"><a href="${options.blog_url!}"><strong>${options.blog_title!}</strong></a> » <a href="${options.blog_url!}/sitemap.html">站点地图</a></div>
|
||||
<div id="content">
|
||||
<h3>最新文章</h3>
|
||||
<ul id="myTable">
|
||||
<li>
|
||||
<div class="T1-h pull-left">URL</div>
|
||||
<div class="T2-h pull-right">Last Change</div>
|
||||
<div class="T3-h pull-right">Change Frequency</div>
|
||||
<div class="T4-h pull-right">Priority</div>
|
||||
</li>
|
||||
<div class="myClear"></div>
|
||||
<li>
|
||||
<div class="T1 pull-left"><a href="${options.blog_url!}" title="${options.blog_title!}">${options.blog_title!}</a></div>
|
||||
<div class="T2 pull-right">${options.blog_start!}</div>
|
||||
<div class="T3 pull-right">daily</div>
|
||||
<div class="T4 pull-right">1</div>
|
||||
</li>
|
||||
<div class="myClear"></div>
|
||||
<#if posts?? && posts?size gt 0>
|
||||
<#list posts as post>
|
||||
<li>
|
||||
<div class="T1 pull-left"><a href="${options.blog_url!}/archives/${post.postUrl!}" title="${post.postTitle!}">${post.postTitle!} | ${options.blog_title!}</a></div>
|
||||
<div class="T2 pull-right">${post.postDate?string('yyyy-MM-dd')}</div>
|
||||
<div class="T3 pull-right">daily</div>
|
||||
<div class="T4 pull-right">0.6</div>
|
||||
</li>
|
||||
<div class="myClear"></div>
|
||||
</#list>
|
||||
</#if>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h3>分类目录</h3>
|
||||
<ul id="myTable">
|
||||
<@commonTag method="categories">
|
||||
<#if categories?? && categories?size gt 0>
|
||||
<#list categories as cate>
|
||||
<li>
|
||||
<div class="T1 pull-left"><a href="${options.blog_url}/categories/${cate.cateUrl!}" title="前端编程">${cate.cateName} | ${options.blog_title!}</a></div>
|
||||
<div class="T2 pull-right">${options.blog_start!}</div>
|
||||
<div class="T3 pull-right">daily</div>
|
||||
<div class="T4 pull-right">0.6</div>
|
||||
</li>
|
||||
<div class="myClear"></div>
|
||||
</#list>
|
||||
</#if>
|
||||
</@commonTag>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="content">
|
||||
<h3>标签目录</h3>
|
||||
<ul id="myTable">
|
||||
<@commonTag method="tags">
|
||||
<#if tags?? && tags?size gt 0>
|
||||
<#list tags as tag>
|
||||
<li>
|
||||
<div class="T1 pull-left"><a href="${options.blog_url}/tags/${tag.tagUrl!}" title="前端编程">${tag.tagName} | ${options.blog_title!}</a></div>
|
||||
<div class="T2 pull-right">${options.blog_start!}</div>
|
||||
<div class="T3 pull-right">daily</div>
|
||||
<div class="T4 pull-right">0.6</div>
|
||||
</li>
|
||||
<div class="myClear"></div>
|
||||
</#list>
|
||||
</#if>
|
||||
</@commonTag>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="footer">
|
||||
该文件由<a href="${options.blog_url!}" title="${options.blog_title!}">${options.blog_title!}</a>网站自动生成。
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</#compress>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<#if posts?? && posts?size gt 0>
|
||||
<#list posts as post>
|
||||
<url>
|
||||
<loc>${options.blog_url!}/archives/${post.postUrl!}</loc>
|
||||
<lastmod>${post.postDate?iso_local}</lastmod>
|
||||
</url>
|
||||
</#list>
|
||||
</#if>
|
||||
</urlset>
|
Loading…
Reference in New Issue