增加网页SEO属性title,keyword,description自定义配置

This commit is contained in:
xiongxiaoyang 2019-12-28 19:41:32 +08:00
parent a8b5aeca12
commit bfacdb5ad6
14 changed files with 141 additions and 56 deletions

View File

@ -0,0 +1,19 @@
package xyz.zinglizingli.books.core.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author 11797
*/
@Data
@Component
@ConfigurationProperties(prefix="website")
public class SeoConfig {
private Map<String,String> page;
}

View File

@ -3,9 +3,11 @@ package xyz.zinglizingli.books.core.listener;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import xyz.zinglizingli.books.core.config.SeoConfig;
import xyz.zinglizingli.books.core.crawl.BaseCrawlSource;
import xyz.zinglizingli.books.core.utils.Constants;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@ -23,13 +25,22 @@ public class StartListener implements ServletContextListener {
@Value("${crawl.book.new.enabled}")
private String crawlEnable;
@Value("${website.name}")
private String webSiteName;
@Value("${website.page.index.title}")
private String title;
@Value("${website.domain}")
private String webSiteDomain;
private final SeoConfig seoConfig;
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
servletContextEvent.getServletContext().setAttribute("websiteName",webSiteName);
ServletContext application = servletContextEvent.getServletContext();
application.setAttribute("webSiteDomain",webSiteDomain);
application.setAttribute(Constants.SEO_CONFIG_KEY,seoConfig);
if (!Constants.ENABLE_NEW_BOOK.equals(crawlEnable.trim())) {
log.info("程序启动");
new Thread(() -> {

View File

@ -100,4 +100,9 @@ public class Constants {
* 是否开启抓取新书
* */
public static final String ENABLE_NEW_BOOK = "true";
/**
* SEO配置保存的key
* */
public static final String SEO_CONFIG_KEY = "seoConfig";
}

View File

@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import xyz.zinglizingli.books.core.config.SeoConfig;
import xyz.zinglizingli.books.po.Book;
import xyz.zinglizingli.books.po.BookContent;
import xyz.zinglizingli.books.po.BookIndex;
@ -23,6 +24,7 @@ import xyz.zinglizingli.common.cache.CommonCacheUtil;
import xyz.zinglizingli.books.core.utils.CatUtil;
import xyz.zinglizingli.books.core.utils.Constants;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.OutputStream;
@ -48,6 +50,7 @@ public class BookController {
private final CommonCacheUtil commonCacheUtil;
/**
* 精品小说搜索页
*/
@ -180,7 +183,7 @@ public class BookController {
* 书籍详情页
*/
@RequestMapping("{bookId}.html")
public String detail(@PathVariable("bookId") Long bookId, @RequestParam(value = "token", required = false) String token, ModelMap modelMap) {
public String detail(@PathVariable("bookId") Long bookId, @RequestParam(value = "token", required = false) String token, HttpServletRequest req, ModelMap modelMap) {
String userId = commonCacheUtil.get(token);
if (org.apache.commons.lang3.StringUtils.isNotBlank(userId)) {
Integer indexNumber = userService.queryBookIndexNumber(userId, bookId);
@ -215,6 +218,12 @@ public class BookController {
modelMap.put("lastIndexName", indexList.get(0).getIndexName());
modelMap.put("lastIndexNum", indexList.get(0).getIndexNum());
}
SeoConfig seoConfig = (SeoConfig) req.getServletContext().getAttribute(Constants.SEO_CONFIG_KEY);
Map<String,String> page = seoConfig.getPage();
page.put("detail.title",page.get("detail.title").replaceAll("<bookName>",book.getBookName()));
page.put("detail.keyword",page.get("detail.keyword").replaceAll("<bookName>",book.getBookName()));
page.put("detail.description",page.get("detail.description").replaceAll("<bookName>",book.getBookName()));
return "books/book_detail";
}
@ -222,12 +231,17 @@ public class BookController {
* 书籍目录页
*/
@RequestMapping("{bookId}/index.html")
public String bookIndex(@PathVariable("bookId") Long bookId, ModelMap modelMap) {
public String bookIndex(@PathVariable("bookId") Long bookId,HttpServletRequest req, ModelMap modelMap) {
List<BookIndex> indexList = bookService.queryAllIndexList(bookId);
String bookName = bookService.queryBaseInfo(bookId).getBookName();
modelMap.put("indexList", indexList);
modelMap.put("bookName", bookName);
modelMap.put("bookId", bookId);
SeoConfig seoConfig = (SeoConfig) req.getServletContext().getAttribute(Constants.SEO_CONFIG_KEY);
Map<String,String> page = seoConfig.getPage();
page.put("catalog.title",page.get("catalog.title").replaceAll("<bookName>",bookName));
page.put("catalog.keyword",page.get("catalog.keyword").replaceAll("<bookName>",bookName));
page.put("catalog.description",page.get("catalog.description").replaceAll("<bookName>",bookName));
return "books/book_index";
}
@ -236,7 +250,7 @@ public class BookController {
* 书籍内容页
*/
@RequestMapping("{bookId}/{indexNum}.html")
public String bookContent(@PathVariable("bookId") Long bookId, @PathVariable("indexNum") Integer indexNum, ModelMap modelMap) {
public String bookContent(@PathVariable("bookId") Long bookId, @PathVariable("indexNum") Integer indexNum,HttpServletRequest req, ModelMap modelMap) {
BookContent bookContent = bookService.queryBookContent(bookId, indexNum);
String indexName;
if (bookContent == null) {
@ -263,6 +277,11 @@ public class BookController {
Integer catId = basicBook.getCatid();
modelMap.put("bookName", bookName);
modelMap.put("catId", catId);
SeoConfig seoConfig = (SeoConfig) req.getServletContext().getAttribute(Constants.SEO_CONFIG_KEY);
Map<String,String> page = seoConfig.getPage();
page.put("content.title",page.get("content.title").replaceAll("<bookName>",bookName).replaceAll("<indexName>",indexName));
page.put("content.keyword",page.get("content.keyword").replaceAll("<bookName>",bookName).replaceAll("<indexName>",indexName));
page.put("content.description",page.get("content.description").replaceAll("<bookName>",bookName).replaceAll("<indexName>",indexName));
return "books/book_content";
}

View File

@ -0,0 +1,43 @@
#网站配置
website:
#网站名
name: 笔趣阁新书门
#域名
domain: https://www.xinshumen.com
#页面配置
page:
#首页配置
index:
title: ${website.name}
keyword: ${website.name},精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说
description: ${website.name}是国内优秀的小说弹幕网站,${website.name}提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。
#小说列表页配置
book-search:
title: ${website.name}_列表
keyword: ${website.name},精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说
description: ${website.name}是国内优秀的小说弹幕网站,${website.name}提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。
#轻小说列表页配置
soft-search:
title: ${website.name}_轻小说专区
keyword: ${website.name},精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说
description: ${website.name}是国内优秀的小说弹幕网站,${website.name}提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。
#漫画列表页配置
mh-search:
title: ${website.name}_漫画专区
keyword: ${website.name},精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说
description: ${website.name}是国内优秀的小说弹幕网站,${website.name}提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。
#目录页配置
catalog:
title: <bookName>最新免费章节目录列表
keyword: <bookName>,<bookName>最新章节
description: <bookName>最新章节列表,<bookName>最新更新章节免费无广告无弹窗在线阅读TXT下载。
#书籍详情页配置
detail:
title: <bookName>小说最新章节免费阅读和下载
keyword: <bookName>,<bookName>最新章节,<bookName>免费阅读,<bookName>TXT下载
description: <bookName>最新章节列表,<bookName>最新更新章节免费无广告无弹窗在线阅读,<bookName>小说TXT免费下载。
#书籍内容页配置
content:
title: <bookName><indexName>
keyword: <bookName>,<indexName>
description: <bookName><indexName>最新更新章节免费在线阅读TXT下载

View File

@ -1,6 +1,3 @@
website:
name: 笔趣阁新书门
server:
port: 8080
@ -43,7 +40,7 @@ spring:
class: javax.net.ssl.SSLSocketFactory
fallback: false
profiles:
include: crawl
include: crawl,website

View File

@ -4,15 +4,16 @@
<meta charset="utf-8">
<meta th:if="${catId == 9}" name="viewport" content="width=device-width, initial-scale=0.5, maximum-scale=1">
<meta th:if="${catId != 9}" name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${bookName}+${indexName}"></title>
<title th:text="${application.seoConfig.page['content.title']}"></title>
<meta name="keywords" th:content="${application.seoConfig.page['content.keyword']}">
<meta name="keywords" th:attr="content=${bookName}+','+${indexName}">
<meta name="description"
th:attr="content=${bookName}+${indexName}+'最新更新章节免费在线阅读TXT下载'">
th:content="${application.seoConfig.page['content.description']}">
<meta property="og:type" content="novel_content"/>
<meta property="og:title" th:attr="content=${bookName}+${indexName}"/>
<meta property="og:description" th:attr="content=${bookName}+${indexName}+'最新更新章节免费在线阅读TXT下载'"/>
<meta property="og:title" th:attr="content=${application.seoConfig.page['content.title']}"/>
<meta property="og:description" th:attr="content=${application.seoConfig.page['content.description']}"/>
<div th:include="common/css :: css"></div>

View File

@ -3,24 +3,26 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${book.bookName}+'小说最新章节免费阅读和下载'"></title>
<meta name="keywords" th:attr="content=${book.bookName}+','+${book.bookName}+'最新章节,'+${book.bookName}+'免费阅读,'+${book.bookName}+'TXT下载'">
<title th:text="${application.seoConfig.page['detail.title']}"></title>
<meta name="keywords" th:content="${application.seoConfig.page['detail.keyword']}">
<meta name="description"
th:attr="content=${book.bookName}+'最新章节列表,'+${book.bookName}+'最新更新章节免费无广告无弹窗在线阅读,'+${book.bookName}+'小说TXT免费下载'">
th:content="${application.seoConfig.page['detail.description']}">
<meta property="og:type" content="novel"/>
<meta property="og:title" th:attr="content=${book.bookName}+'小说最新章节免费阅读和下载'"/>
<meta property="og:title" th:attr="content=${application.seoConfig.page['detail.title']}"/>
<meta property="og:description" th:attr="content=${book.bookDesc}"/>
<meta property="og:image" th:attr="content=${book.picUrl}"/>
<meta property="og:image" th:attr="content=${application.webSiteDomain}+${book.picUrl}"/>
<meta property="og:novel:category" th:attr="content=${book.cateName}"/>
<meta property="og:novel:author" th:attr="content=${book.author}"/>
<meta property="og:novel:book_name" th:attr="content=${book.bookName}"/>
<meta property="og:novel:read_url" th:attr="content='https://www.zinglizingli.xyz/book/'+${book.id}+'.html'"/>
<meta property="og:url" th:attr="content='https://www.zinglizingli.xyz/book/'+${book.id}+'.html'"/>
<meta property="og:novel:read_url" th:attr="content=${application.webSiteDomain}+'/book/'+${book.id}+'.html'"/>
<meta property="og:url" th:attr="content=${application.webSiteDomain}+'/book/'+${book.id}+'.html'"/>
<meta property="og:novel:status" th:attr="content=${book.bookStatus}"/>
<meta property="og:novel:update_time" th:attr="content=${#dates.format(book.updateTime, 'yy-MM-dd')}"/>
<meta property="og:novel:latest_chapter_name" th:attr="content=${lastIndexName}"/>
<meta property="og:novel:latest_chapter_url" th:attr="content='https://www.zinglizingli.xyz/book/'+${bookId}+'/'+${lastIndexNum}+'.html'"/>
<meta property="og:novel:latest_chapter_url" th:attr="content=${application.webSiteDomain}+'/book/'+${bookId}+'/'+${lastIndexNum}+'.html'"/>

View File

@ -5,14 +5,16 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${bookName}+'最新免费章节目录列表'"></title>
<meta name="keywords" th:attr="content=${bookName}+','+${bookName}+'最新章节'">
<title th:text="${application.seoConfig.page['catalog.title']}"></title>
<meta name="keywords" th:content="${application.seoConfig.page['catalog.keyword']}">
<meta name="description"
th:attr="content=${bookName}+'最新章节列表,'+${bookName}+'最新更新章节免费无广告无弹窗在线阅读TXT下载'">
th:content="${application.seoConfig.page['catalog.description']}">
<meta property="og:type" content="novel_chapter"/>
<meta property="og:title" th:attr="content=${bookName}+'最新免费章节目录列表'"/>
<meta property="og:description" th:attr="content=${bookName}+'最新章节列表,'+${bookName}+'最新更新章节免费无广告无弹窗在线阅读TXT下载'"/>
<meta property="og:title" th:attr="content=${application.seoConfig.page['catalog.title']}"/>
<meta property="og:description" th:attr="content=${application.seoConfig.page['catalog.description']}"/>
</div>

View File

@ -5,12 +5,12 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${application.websiteName}+'_小说列表'"></title>
<title th:text="${application.seoConfig.page['book-search.title']}"></title>
<meta name="keywords" th:content="${application.websiteName}+',精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说'">
<meta name="keywords" th:content="${application.seoConfig.page['book-search.keyword']}">
<meta name="description"
th:content="${application.websiteName}+'是国内优秀的小说弹幕网站,'+${application.websiteName}+'提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。'">
th:content="${application.seoConfig.page['book-search.description']}">
<div th:include="common/css :: css"></div>

View File

@ -5,17 +5,17 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${application.websiteName}"></title>
<title th:text="${application.seoConfig.page['index.title']}"></title>
<meta name="keywords" th:content="${application.websiteName}+',精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说'">
<meta name="keywords" th:content="${application.seoConfig.page['index.keyword']}">
<meta name="description"
th:content="${application.websiteName}+'是国内优秀的小说弹幕网站,'+${application.websiteName}+'提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。'">
th:content="${application.seoConfig.page['index.description']}">
<meta property="og:type" content="novel_index"/>
<meta property="og:title" th:content="${application.websiteName}"/>
<meta property="og:title" th:content="${application.seoConfig.page['index.title']}"/>
<meta property="og:description"
th:content="${application.websiteName}+'是国内优秀的小说弹幕网站,'+${application.websiteName}+'提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。'"/>
th:content="${application.seoConfig.page['index.description']}"/>
<div th:include="common/css :: css"></div>

View File

@ -5,18 +5,12 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${application.websiteName}+'_漫画专区'"></title>
<title th:text="${application.seoConfig.page['mh-search.title']}"></title>
<meta name="keywords" th:content="${application.websiteName}+',精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说'">
<meta name="keywords" th:content="${application.seoConfig.page['mh-search.keyword']}">
<meta name="description"
th:content="${application.websiteName}+'是国内优秀的小说弹幕网站,'+${application.websiteName}+'提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。'">
<meta property="og:type" content="mh_novel_index"/>
<meta property="og:title" th:content="${application.websiteName}+'_漫画专区'"/>
<meta property="og:description"
th:content="${application.websiteName}+'是国内优秀的小说弹幕网站,'+${application.websiteName}+'提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。'"/>
th:content="${application.seoConfig.page['mh-search.description']}">
<div th:include="common/css :: css"></div>

View File

@ -5,18 +5,12 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title th:text="${application.websiteName}+'_轻小说专区'"></title>
<title th:text="${application.seoConfig.page['soft-search.title']}"></title>
<meta name="keywords" th:content="${application.websiteName}+',精品小说,弹幕网站,弹幕,弹幕小说网站,免费小说,小说阅读,小说排行,轻小说,txt小说下载,电子书下载,动漫轻小说,日本轻小说'">
<meta name="keywords" th:content="${application.seoConfig.page['soft-search.keyword']}">
<meta name="description"
th:content="${application.websiteName}+'是国内优秀的小说弹幕网站,'+${application.websiteName}+'提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。'">
<meta property="og:type" content="soft_novel_index"/>
<meta property="og:title" th:content="${application.websiteName}+'_轻小说专区'"/>
<meta property="og:description"
th:content="${application.websiteName}+'是国内优秀的小说弹幕网站,'+${application.websiteName}+'提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。'"/>
th:content="${application.seoConfig.page['soft-search.description']}">
<div th:include="common/css :: css"></div>

View File

@ -6,8 +6,6 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>登录|注册</title>
<meta name="description"
th:content="${application.websiteName}+'是国内优秀的小说弹幕网站,'+${application.websiteName}+'提供海量热门网络小说,日本轻小说,国产轻小说,动漫小说,轻小说在线阅读和TXT小说下载,致力于网络精品小说的收集,智能计算小说评分,打造小说精品排行榜,致力于无广告无弹窗的小说阅读环境。'">
<div th:include="common/css :: css"></div>