complate theme system

pull/137/head
ruibaby 2019-03-17 15:15:35 +08:00
parent cfb261eb4f
commit fe1204f441
7 changed files with 90 additions and 125 deletions

View File

@ -5,9 +5,7 @@ import lombok.Data;
import java.io.Serializable;
/**
* <pre>
*
* </pre>
* Theme DTO
*
* @author : RYAN0UP
* @date : 2018/1/3
@ -18,17 +16,22 @@ public class Theme implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
* theme name
*/
private String themeName;
/**
*
* is support setting options
*/
private boolean hasOptions;
/**
*
* is support update
*/
private boolean hasUpdate;
/**
* is internal theme
*/
private boolean isInternal;
}

View File

@ -1,6 +1,9 @@
package cc.ryanc.halo.utils;
import cc.ryanc.halo.model.support.HaloConst;
import cc.ryanc.halo.model.support.Theme;
import cc.ryanc.halo.web.controller.core.BaseContentController;
import cn.hutool.core.text.StrBuilder;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ResourceUtils;
@ -27,8 +30,8 @@ public class ThemeUtils {
public static List<Theme> getThemes() {
final List<Theme> themes = new ArrayList<>();
try {
themes.addAll(getThemesByPath(getInternalThemesPath()));
themes.addAll(getThemesByPath(getUsersThemesPath()));
themes.addAll(getThemesByPath(getInternalThemesPath(), true));
themes.addAll(getThemesByPath(getUsersThemesPath(), false));
} catch (Exception e) {
log.error("Themes scan failed", e);
}
@ -41,7 +44,7 @@ public class ThemeUtils {
* @param file file
* @return List<Theme>
*/
private static List<Theme> getThemesByPath(File themesPath) {
private static List<Theme> getThemesByPath(File themesPath, boolean isInternal) {
final List<Theme> themes = new ArrayList<>();
try {
final File[] files = themesPath.listFiles();
@ -67,6 +70,7 @@ public class ThemeUtils {
} else {
theme.setHasUpdate(false);
}
theme.setInternal(isInternal);
themes.add(theme);
}
}
@ -78,7 +82,7 @@ public class ThemeUtils {
}
/**
* Get internal themes
* Get internal themes path
*
* @return File
* @throws FileNotFoundException FileNotFoundException
@ -88,7 +92,7 @@ public class ThemeUtils {
}
/**
* Get user's themes
* Get user's themes path
*
* @return File
*/
@ -96,6 +100,20 @@ public class ThemeUtils {
return new File(System.getProperties().getProperty("user.home"), "halo/templates/themes");
}
/**
* Get themes path by theme name
*
* @param themeName themeName
* @return File
*/
public static File getThemesPath(String themeName) throws FileNotFoundException {
if (isInternal(themeName)) {
return getInternalThemesPath();
} else {
return getUsersThemesPath();
}
}
/**
* Get theme templates
*
@ -105,7 +123,7 @@ public class ThemeUtils {
public static List<String> getTplName(String theme) {
final List<String> templates = new ArrayList<>();
try {
final File themesPath = new File(getUsersThemesPath(), "templates/themes/" + theme);
final File themesPath = new File(getThemesPath(theme), theme);
final File modulePath = new File(themesPath.getAbsolutePath(), "module");
final File[] baseFiles = themesPath.listFiles();
final File[] moduleFiles = modulePath.listFiles();
@ -134,9 +152,9 @@ public class ThemeUtils {
*
* @return List
*/
public static List<String> getCustomTpl(String theme) {
public static List<String> getCustomTpl(String theme) throws FileNotFoundException {
final List<String> templates = new ArrayList<>();
final File themePath = new File(getUsersThemesPath(), "templates/themes/" + theme);
final File themePath = new File(getThemesPath(theme), theme);
final File[] themeFiles = themePath.listFiles();
if (null != themeFiles && themeFiles.length > 0) {
for (File file : themeFiles) {
@ -148,4 +166,41 @@ public class ThemeUtils {
}
return templates;
}
/**
* Judging whether template exists under the specified theme
*
* @param template template
* @return boolean
*/
public static boolean isTemplateExist(String template) throws FileNotFoundException {
boolean result = false;
StrBuilder templatePath = new StrBuilder(BaseContentController.THEME);
templatePath.append("/");
templatePath.append(template);
File file = new File(getThemesPath(BaseContentController.THEME), templatePath.toString());
if (file.exists()) {
result = true;
}
return result;
}
/**
* Judging whether the theme is a internal theme or not
*
* @param themeName themeName
* @return boolean
*/
public static boolean isInternal(String themeName) {
boolean result = false;
List<Theme> themes = HaloConst.THEMES;
for (Theme theme : themes) {
if (theme.getThemeName().equals(themeName) && theme.isInternal()) {
result = true;
break;
}
}
return result;
}
}

View File

@ -129,7 +129,7 @@ public class ThemeController extends BaseController {
@GetMapping(value = "/remove")
public String removeTheme(@RequestParam("themeName") String themeName) {
try {
final File themePath = new File(ThemeUtils.getUsersThemesPath(), themeName);
final File themePath = new File(ThemeUtils.getThemesPath(themeName), themeName);
FileUtil.del(themePath);
} catch (Exception e) {
log.error("Delete theme failed: {}", e.getMessage());
@ -244,7 +244,7 @@ public class ThemeController extends BaseController {
public String getTplContent(@RequestParam("tplName") String tplName) {
String tplContent = "";
try {
final StrBuilder themePath = new StrBuilder(ThemeUtils.getUsersThemesPath().getAbsolutePath());
final StrBuilder themePath = new StrBuilder(ThemeUtils.getThemesPath(BaseContentController.THEME).getAbsolutePath());
themePath.append(BaseContentController.THEME);
themePath.append("/");
themePath.append(tplName);
@ -272,7 +272,7 @@ public class ThemeController extends BaseController {
return new JsonResult(0, localeMessage("code.admin.theme.edit.no-content"));
}
try {
final StrBuilder themePath = new StrBuilder(ThemeUtils.getUsersThemesPath().getAbsolutePath());
final StrBuilder themePath = new StrBuilder(ThemeUtils.getThemesPath(BaseContentController.THEME).getAbsolutePath());
themePath.append(BaseContentController.THEME);
themePath.append("/");
themePath.append(tplName);

View File

@ -3,6 +3,7 @@ package cc.ryanc.halo.web.controller.core;
import cc.ryanc.halo.logging.Logger;
import cc.ryanc.halo.model.entity.User;
import cc.ryanc.halo.model.support.HaloConst;
import cc.ryanc.halo.utils.ThemeUtils;
import cn.hutool.core.text.StrBuilder;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
@ -11,6 +12,7 @@ import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.FileNotFoundException;
/**
* <pre>
@ -92,7 +94,10 @@ public class CommonController implements ErrorController {
* @return String
*/
@GetMapping(value = "/404")
public String contentNotFround() {
public String contentNotFround() throws FileNotFoundException {
if(ThemeUtils.isTemplateExist("404.ftl")){
return "common/error/404";
}
StrBuilder path = new StrBuilder("themes/");
path.append(BaseContentController.THEME);
path.append("/404");
@ -105,7 +110,10 @@ public class CommonController implements ErrorController {
* @return template path:
*/
@GetMapping(value = "/500")
public String contentInternalError() {
public String contentInternalError() throws FileNotFoundException {
if(ThemeUtils.isTemplateExist("500.ftl")){
return "common/error/404";
}
StrBuilder path = new StrBuilder("themes/");
path.append(BaseContentController.THEME);
path.append("/500");

View File

@ -2,6 +2,7 @@ package cc.ryanc.halo.web.controller.core;
import cc.ryanc.halo.model.entity.*;
import cc.ryanc.halo.model.enums.CommentStatus;
import cc.ryanc.halo.model.enums.PostStatus;
import cc.ryanc.halo.model.support.JsonResult;
import cc.ryanc.halo.service.*;
import cc.ryanc.halo.utils.MarkdownUtils;
@ -133,9 +134,9 @@ public class InstallController {
"欢迎使用Halo进行创作删除这篇文章后赶紧开始吧。");
post.setFormatContent(MarkdownUtils.renderMarkdown(post.getOriginalContent()));
post.setSummary("欢迎使用Halo进行创作删除这篇文章后赶紧开始吧。");
post.setStatus(0);
post.setStatus(PostStatus.PUBLISHED);
post.setUrl("hello-halo");
post.setDisallowComment(1);
post.setDisallowComment(true);
post.setThumbnail("/static/halo-frontend/images/thumbnail/thumbnail-" + RandomUtil.randomInt(1, 11) + ".jpg");
postService.create(post);

View File

@ -1,52 +1 @@
<#compress>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>404 Not Found</title>
<link href="//cdnjs.loli.net/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="//cdnjs.loli.net/ajax/libs/animate.css/3.7.0/animate.min.css" rel="stylesheet">
<style type="text/css" rel="stylesheet">
body{margin:0}*{box-sizing:border-box}h1,h2{margin:0}a{color:#fff;text-decoration:none}body,html{font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.fullscreen{background-position:50% 50%;background-size:cover}.fullscreen,.fullscreen .backColor{position:absolute;top:0;left:0;width:100%;height:100%}.fullscreen .backColor{background-color:rgba(0,0,0,.1)}.infos{display:flex;text-align:center;align-items:center;justify-content:center}.infos,.main-content{position:absolute;top:0;left:0;width:100%;height:100%;color:#fff}.main-content{background: #833ab4;background: -webkit-linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);background: linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);}.errorPage{position:relative;width:100vw;height:100vh}.infos-h1{margin:0;font-size:5em;line-height:1}.infos-h1 h1{font-weight:200}.footer{position:absolute;right:1rem;bottom:1rem;left:1rem;z-index:9999;font-size:14px}.infos-h2{font-size:24px}.infos-h2 a:hover{color:#7a8d85}
</style>
</head>
<body>
<div class="container">
<div class="errorPage">
<div class="main-content ">
<div class="fullscreen">
<div class="backColor"></div>
</div>
<div class="infos">
<div class="infos-main">
<div class="infos-h1"><h1>404</h1></div>
<div class="infos-h2">
<a href="javascript:window.history.back()" title="返回上一页">
<i class="fa fa-chevron-left"></i>
</a>
<a href="/" title="返回到主页">
<i class="fa fa-home"></i>
</a>
</div>
</div>
</div>
<div class="footer">
<span>Copyright © 2018</span>
<a href="${options.blog_url!}">${options.blog_title!'Halo'}</a>
<span style="float: right">
Background image from <a href="https://cn.bing.com/" target="_blank">Bing</a>.
</span>
</div>
</div>
</div>
</div>
</body>
<script src="//cdnjs.loli.net/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('$.o(\'m://q.8.n/?1=4%y%z%B.5.9%d.e%f%g%h%i%j%k\',l(b){6 a=b.p[0].1;6 c=$(\'.r\');c.t("u-v","1(4://s.w.5.x"+a+")");c.2(\'3 A\');$(\'.7-C\').2(\'3 D\');$(\'.7-E\').2(\'3 F\')});',42,42,'|url|addClass|animated|http|bing|var|infos|afeld|com||||2FHPImageArchive|aspx|3Fformat|3Djs|26idx|3D0|26n|3D1|function|https|me|get|images|jsonp|fullscreen||css|background|image|cn|net|3A|2F|fadeIn|2Fcn|h1|shake|h2|fadeInDown'.split('|'),0,{}))
</script>
</html>
</#compress>
404 Not Found

View File

@ -1,52 +1 @@
<#compress>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>500 Error Page</title>
<link href="//cdnjs.loli.net/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<link href="//cdnjs.loli.net/ajax/libs/animate.css/3.7.0/animate.min.css" rel="stylesheet">
<style type="text/css" rel="stylesheet">
body{margin:0}*{box-sizing:border-box}h1,h2{margin:0}a{color:#fff;text-decoration:none}body,html{font-family:-apple-system,system-ui,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.fullscreen{background-position:50% 50%;background-size:cover}.fullscreen,.fullscreen .backColor{position:absolute;top:0;left:0;width:100%;height:100%}.fullscreen .backColor{background-color:rgba(0,0,0,.1)}.infos{display:flex;text-align:center;align-items:center;justify-content:center}.infos,.main-content{position:absolute;top:0;left:0;width:100%;height:100%;color:#fff}.main-content{background: #833ab4;background: -webkit-linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);background: linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);}.errorPage{position:relative;width:100vw;height:100vh}.infos-h1{margin:0;font-size:5em;line-height:1}.infos-h1 h1{font-weight:200}.footer{position:absolute;right:1rem;bottom:1rem;left:1rem;z-index:9999;font-size:14px}.infos-h2{font-size:24px}.infos-h2 a:hover{color:#7a8d85}
</style>
</head>
<body>
<div class="container">
<div class="errorPage">
<div class="main-content ">
<div class="fullscreen">
<div class="backColor"></div>
</div>
<div class="infos">
<div class="infos-main">
<div class="infos-h1"><h1>500</h1></div>
<div class="infos-h2">
<a href="javascript:window.history.back()" title="返回上一页">
<i class="fa fa-chevron-left"></i>
</a>
<a href="/" title="返回到主页">
<i class="fa fa-home"></i>
</a>
</div>
</div>
</div>
<div class="footer">
<span>Copyright © 2018</span>
<a href="${options.blog_title!}">${options.blog_title!'Halo'}</a>
<span style="float: right">
Background image from <a href="https://cn.bing.com/" target="_blank">Bing</a>.
</span>
</div>
</div>
</div>
</div>
</body>
<script src="//cdnjs.loli.net/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('$.o(\'m://q.8.n/?1=4%y%z%B.5.9%d.e%f%g%h%i%j%k\',l(b){6 a=b.p[0].1;6 c=$(\'.r\');c.t("u-v","1(4://s.w.5.x"+a+")");c.2(\'3 A\');$(\'.7-C\').2(\'3 D\');$(\'.7-E\').2(\'3 F\')});',42,42,'|url|addClass|animated|http|bing|var|infos|afeld|com||||2FHPImageArchive|aspx|3Fformat|3Djs|26idx|3D0|26n|3D1|function|https|me|get|images|jsonp|fullscreen||css|background|image|cn|net|3A|2F|fadeIn|2Fcn|h1|shake|h2|fadeInDown'.split('|'),0,{}))
</script>
</html>
</#compress>
500 Internal Error