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>
|
<oh-my-email.version>0.0.4</oh-my-email.version>
|
||||||
<lombok.version>1.18.4</lombok.version>
|
<lombok.version>1.18.4</lombok.version>
|
||||||
<ehcache.version>3.6.3</ehcache.version>
|
<ehcache.version>3.6.3</ehcache.version>
|
||||||
<rome.version>1.0</rome.version>
|
|
||||||
<hutool-all.version>4.4.2</hutool-all.version>
|
<hutool-all.version>4.4.2</hutool-all.version>
|
||||||
<upyun-java-sdk.version>4.0.1</upyun-java-sdk.version>
|
<upyun-java-sdk.version>4.0.1</upyun-java-sdk.version>
|
||||||
<qiniu-java-sdk.version>7.2.18</qiniu-java-sdk.version>
|
<qiniu-java-sdk.version>7.2.18</qiniu-java-sdk.version>
|
||||||
|
@ -120,13 +119,6 @@
|
||||||
<version>${ehcache.version}</version>
|
<version>${ehcache.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- rss -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>rome</groupId>
|
|
||||||
<artifactId>rome</artifactId>
|
|
||||||
<version>${rome.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- hutool工具包 -->
|
<!-- hutool工具包 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
|
|
|
@ -83,8 +83,7 @@ public class WebMvcAutoConfiguration implements WebMvcConfigurer {
|
||||||
registry.addResourceHandler("/static/**")
|
registry.addResourceHandler("/static/**")
|
||||||
.addResourceLocations("classpath:/static/");
|
.addResourceLocations("classpath:/static/");
|
||||||
registry.addResourceHandler("/**")
|
registry.addResourceHandler("/**")
|
||||||
.addResourceLocations("classpath:/templates/themes/")
|
.addResourceLocations("classpath:/templates/themes/");
|
||||||
.addResourceLocations("classpath:/robots.txt");
|
|
||||||
registry.addResourceHandler("/upload/**")
|
registry.addResourceHandler("/upload/**")
|
||||||
.addResourceLocations("file:///" + System.getProperties().getProperty("user.home") + "/halo/upload/");
|
.addResourceLocations("file:///" + System.getProperties().getProperty("user.home") + "/halo/upload/");
|
||||||
registry.addResourceHandler("/favicon.ico")
|
registry.addResourceHandler("/favicon.ico")
|
||||||
|
|
|
@ -248,22 +248,6 @@ public interface PostService {
|
||||||
*/
|
*/
|
||||||
Integer getCountByStatus(Integer status);
|
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());
|
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;
|
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.BackupDto;
|
||||||
import cc.ryanc.halo.model.dto.Theme;
|
import cc.ryanc.halo.model.dto.Theme;
|
||||||
import cc.ryanc.halo.model.enums.BlogPropertiesEnum;
|
|
||||||
import cc.ryanc.halo.model.enums.CommonParamsEnum;
|
import cc.ryanc.halo.model.enums.CommonParamsEnum;
|
||||||
import cn.hutool.core.date.DateUtil;
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.text.StrBuilder;
|
import cn.hutool.core.text.StrBuilder;
|
||||||
import cn.hutool.core.util.StrUtil;
|
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 io.github.biezhi.ome.OhMyEmail;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
@ -32,8 +24,6 @@ import java.nio.file.attribute.BasicFileAttributeView;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static cc.ryanc.halo.model.dto.HaloConst.OPTIONS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <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;
|
package cc.ryanc.halo.web.controller.front;
|
||||||
|
|
||||||
import cc.ryanc.halo.model.domain.Post;
|
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.BlogPropertiesEnum;
|
||||||
import cc.ryanc.halo.model.enums.PostTypeEnum;
|
import cc.ryanc.halo.model.enums.PostTypeEnum;
|
||||||
import cc.ryanc.halo.service.PostService;
|
import cc.ryanc.halo.service.PostService;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import freemarker.template.Template;
|
||||||
|
import freemarker.template.TemplateException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
import org.springframework.stereotype.Controller;
|
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.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static cc.ryanc.halo.model.dto.HaloConst.*;
|
import static cc.ryanc.halo.model.dto.HaloConst.OPTIONS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
|
@ -33,51 +38,102 @@ public class FrontOthersController {
|
||||||
@Autowired
|
@Autowired
|
||||||
private PostService postService;
|
private PostService postService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private FreeMarkerConfigurer freeMarker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文章rss
|
* 获取文章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")
|
@GetMapping(value = {"feed", "feed.xml", "atom", "atom.xml"}, produces = "application/xml;charset=UTF-8")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String feed() {
|
public String feed(Model model) throws IOException, TemplateException {
|
||||||
String rssPosts = OPTIONS.get(BlogPropertiesEnum.RSS_POSTS.getProp());
|
String rssPosts = OPTIONS.get(BlogPropertiesEnum.RSS_POSTS.getProp());
|
||||||
if (StrUtil.isBlank(rssPosts)) {
|
if (StrUtil.isBlank(rssPosts)) {
|
||||||
rssPosts = "20";
|
rssPosts = "20";
|
||||||
}
|
}
|
||||||
//获取文章列表并根据时间排序
|
|
||||||
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
|
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
|
||||||
final Pageable pageable = PageRequest.of(0, Integer.parseInt(rssPosts), sort);
|
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 -> {
|
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.setPostContent("该文章为加密文章");
|
||||||
post.setPostSummary("该文章为加密文章");
|
post.setPostSummary("该文章为加密文章");
|
||||||
}
|
}
|
||||||
return post;
|
return post;
|
||||||
});
|
});
|
||||||
final List<Post> posts = postsPage.getContent();
|
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")
|
@GetMapping(value = {"sitemap", "sitemap.xml"}, produces = "application/xml;charset=UTF-8")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public String siteMap() {
|
public String sitemapXml(Model model) throws IOException, TemplateException {
|
||||||
//获取文章列表并根据时间排序
|
final Page<Post> postsPage = postService.findPostByStatus(0, PostTypeEnum.POST_TYPE_POST.getDesc(), null).map(post -> {
|
||||||
final Sort sort = new Sort(Sort.Direction.DESC, "postDate");
|
if (StrUtil.isNotEmpty(post.getPostPassword())) {
|
||||||
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())){
|
|
||||||
post.setPostContent("该文章为加密文章");
|
post.setPostContent("该文章为加密文章");
|
||||||
post.setPostSummary("该文章为加密文章");
|
post.setPostSummary("该文章为加密文章");
|
||||||
}
|
}
|
||||||
return post;
|
return post;
|
||||||
});
|
});
|
||||||
final List<Post> posts = postsPage.getContent();
|
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