posts) {
- return HaloUtils.getSiteMap(posts);
- }
-
/**
* 缓存阅读数
*
diff --git a/src/main/java/cc/ryanc/halo/utils/HaloUtils.java b/src/main/java/cc/ryanc/halo/utils/HaloUtils.java
index a2d31b04f..381df8fe2 100755
--- a/src/main/java/cc/ryanc/halo/utils/HaloUtils.java
+++ b/src/main/java/cc/ryanc/halo/utils/HaloUtils.java
@@ -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;
-
/**
*
* 常用工具
@@ -285,84 +275,6 @@ public class HaloUtils {
}
}
- /**
- * 生成rss
- *
- * @param posts posts
- *
- * @return String
- *
- * @throws FeedException FeedException
- */
- public static String getRss(List 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- 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 posts) {
- Assert.notEmpty(posts, "post mut not be empty");
- final StrBuilder head = new StrBuilder("\n");
- final StrBuilder urlBody = new StrBuilder();
- final String urlPath = OPTIONS.get(BlogPropertiesEnum.BLOG_URL.getProp()) + "/archives/";
- for (Post post : posts) {
- urlBody.append("");
- urlBody.append(urlPath);
- urlBody.append(post.getPostUrl());
- urlBody.append("");
- urlBody.append(DateUtil.format(post.getPostDate(), "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"));
- urlBody.append("");
- }
- return head.append(urlBody).append("").toString();
- }
-
/**
* 配置邮件
*
diff --git a/src/main/java/cc/ryanc/halo/web/controller/front/FrontOthersController.java b/src/main/java/cc/ryanc/halo/web/controller/front/FrontOthersController.java
index 474ba865d..956914b9f 100644
--- a/src/main/java/cc/ryanc/halo/web/controller/front/FrontOthersController.java
+++ b/src/main/java/cc/ryanc/halo/web/controller/front/FrontOthersController.java
@@ -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;
/**
*
@@ -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 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 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 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 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 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 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 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);
}
}
diff --git a/src/main/resources/robots.txt b/src/main/resources/robots.txt
deleted file mode 100644
index f9b88f793..000000000
--- a/src/main/resources/robots.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-User-agent: *
-Disallow: /admin/
-Sitemap: /sitemap.xml
\ No newline at end of file
diff --git a/src/main/resources/templates/common/web/robots.ftl b/src/main/resources/templates/common/web/robots.ftl
new file mode 100644
index 000000000..e7bfbaab7
--- /dev/null
+++ b/src/main/resources/templates/common/web/robots.ftl
@@ -0,0 +1,4 @@
+User-agent: *
+Disallow: /admin/
+Sitemap: ${options.blog_url!}/sitemap.xml
+Sitemap: ${options.blog_url!}/sitemap.html
\ No newline at end of file
diff --git a/src/main/resources/templates/common/web/rss.ftl b/src/main/resources/templates/common/web/rss.ftl
new file mode 100644
index 000000000..27e709958
--- /dev/null
+++ b/src/main/resources/templates/common/web/rss.ftl
@@ -0,0 +1,21 @@
+
+
+
+ ${options.blog_title!}
+ ${options.blog_url!}
+ <#if user.userDesc??>
+ ${user.userDesc!}
+ #if>
+ zh-CN
+ <#if posts?? && posts?size gt 0>
+ <#list posts as post>
+ -
+ ${post.postTitle!}
+ ${options.blog_url}/archives/${post.postUrl!}
+ ${post.postContent!}
+ ${post.postDate}
+
+ #list>
+ #if>
+
+
\ No newline at end of file
diff --git a/src/main/resources/templates/common/web/sitemap_html.ftl b/src/main/resources/templates/common/web/sitemap_html.ftl
new file mode 100644
index 000000000..7577bbf25
--- /dev/null
+++ b/src/main/resources/templates/common/web/sitemap_html.ftl
@@ -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 >
+
+
+
+
+
+ ${options.blog_title!} 网站地图
+
+
+
+
+${options.blog_title!} 网站地图
+
+
+
+
分类目录
+
+ <@commonTag method="categories">
+ <#if categories?? && categories?size gt 0>
+ <#list categories as cate>
+ -
+
+
${options.blog_start!}
+ daily
+ 0.6
+
+
+ #list>
+ #if>
+ @commonTag>
+
+
+
+
标签目录
+
+ <@commonTag method="tags">
+ <#if tags?? && tags?size gt 0>
+ <#list tags as tag>
+ -
+
+
${options.blog_start!}
+ daily
+ 0.6
+
+
+ #list>
+ #if>
+ @commonTag>
+
+
+
+
+
+#compress>
\ No newline at end of file
diff --git a/src/main/resources/templates/common/web/sitemap_xml.ftl b/src/main/resources/templates/common/web/sitemap_xml.ftl
new file mode 100644
index 000000000..732d7ed52
--- /dev/null
+++ b/src/main/resources/templates/common/web/sitemap_xml.ftl
@@ -0,0 +1,11 @@
+
+
+ <#if posts?? && posts?size gt 0>
+ <#list posts as post>
+
+ ${options.blog_url!}/archives/${post.postUrl!}
+ ${post.postDate?iso_local}
+
+ #list>
+ #if>
+
\ No newline at end of file