mirror of https://github.com/halo-dev/halo
1.修复了使用Freemarker自定义标签后不能保存系统设置的问题,2.优化部分重复代码,3.Anatole主题即将适配完毕
parent
ec92b35f2f
commit
fcdb55f7d8
|
@ -1,13 +1,9 @@
|
|||
package cc.ryanc.halo.config;
|
||||
|
||||
import cc.ryanc.halo.security.XssFilter;
|
||||
import cc.ryanc.halo.web.interceptor.InstallInterceptor;
|
||||
import cc.ryanc.halo.web.interceptor.LoginInterceptor;
|
||||
import com.google.common.collect.Maps;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
@ -16,8 +12,6 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
|||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2018/1/2
|
||||
|
@ -69,21 +63,4 @@ public class MvcConfig implements WebMvcConfigurer {
|
|||
registry.addResourceHandler("/upload/**")
|
||||
.addResourceLocations("classpath:/upload/");
|
||||
}
|
||||
|
||||
/**
|
||||
* xss过滤拦截器
|
||||
*/
|
||||
@Bean
|
||||
public FilterRegistrationBean xssFilterRegistrationBean() {
|
||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
||||
filterRegistrationBean.setFilter(new XssFilter());
|
||||
filterRegistrationBean.setOrder(1);
|
||||
filterRegistrationBean.setEnabled(true);
|
||||
filterRegistrationBean.addUrlPatterns("/*");
|
||||
Map<String, String> initParameters = Maps.newHashMap();
|
||||
initParameters.put("excludes", "/static/*,/upload/*");
|
||||
initParameters.put("isIncludeRichText", "true");
|
||||
filterRegistrationBean.setInitParameters(initParameters);
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,12 @@ public class ArticleTagDirective implements TemplateDirectiveModel {
|
|||
case "postsCount":
|
||||
environment.setVariable("postsCount",builder.build().wrap(postService.findAllPosts().size()));
|
||||
break;
|
||||
case "archives":
|
||||
environment.setVariable("archives",builder.build().wrap(postService.findPostGroupByYearAndMonth()));
|
||||
break;
|
||||
case "archivesLess":
|
||||
environment.setVariable("archivesLess",builder.build().wrap(postService.findPostGroupByYear()));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package cc.ryanc.halo.model.tag;
|
||||
|
||||
import cc.ryanc.halo.service.CategoryService;
|
||||
import cc.ryanc.halo.service.CommentService;
|
||||
import cc.ryanc.halo.service.MenuService;
|
||||
import freemarker.core.Environment;
|
||||
import freemarker.template.*;
|
||||
|
@ -26,6 +27,9 @@ public class CommonTagDirective implements TemplateDirectiveModel {
|
|||
@Autowired
|
||||
private CategoryService categoryService;
|
||||
|
||||
@Autowired
|
||||
private CommentService commentService;
|
||||
|
||||
@Override
|
||||
public void execute(Environment environment, Map map, TemplateModel[] templateModels, TemplateDirectiveBody templateDirectiveBody) throws TemplateException, IOException {
|
||||
DefaultObjectWrapperBuilder builder = new DefaultObjectWrapperBuilder(Configuration.VERSION_2_3_25);
|
||||
|
@ -38,6 +42,9 @@ public class CommonTagDirective implements TemplateDirectiveModel {
|
|||
case "categories":
|
||||
environment.setVariable("categories",builder.build().wrap(categoryService.findAllCategories()));
|
||||
break;
|
||||
case "newComments":
|
||||
environment.setVariable("newComments",builder.build().wrap(commentService.findAllComments(1)));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -18,14 +18,22 @@ import java.util.List;
|
|||
public interface CommentRepository extends JpaRepository<Comment,Long> {
|
||||
|
||||
/**
|
||||
* 根据评论状态查询所有评论
|
||||
* 根据评论状态查询所有评论 分页
|
||||
*
|
||||
* @param status Status 文章状态
|
||||
* @param pageable pageable 分页信息
|
||||
* @param status 文章状态
|
||||
* @param pageable 分页信息
|
||||
* @return page
|
||||
*/
|
||||
Page<Comment> findCommentsByCommentStatus(Integer status, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据评论状态查询所有评论 不分页
|
||||
*
|
||||
* @param status 文章状态
|
||||
* @return list
|
||||
*/
|
||||
List<Comment> findCommentsByCommentStatus(Integer status);
|
||||
|
||||
/**
|
||||
* 根据文章查询评论
|
||||
*
|
||||
|
|
|
@ -112,7 +112,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
|
|||
* @param month month
|
||||
* @return list
|
||||
*/
|
||||
@Query(value = "select *,year(post_date) as year,month(post_date) as month from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month order by post_date",nativeQuery = true)
|
||||
@Query(value = "select *,year(post_date) as year,month(post_date) as month from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month order by post_date desc",nativeQuery = true)
|
||||
List<Post> findPostByYearAndMonth(@Param("year") String year,@Param("month") String month);
|
||||
|
||||
/**
|
||||
|
@ -121,7 +121,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
|
|||
* @param year year
|
||||
* @return list
|
||||
*/
|
||||
@Query(value = "select *,year(post_date) as year from halo_post where post_status=0 and year(post_date)=:year order by post_date",nativeQuery = true)
|
||||
@Query(value = "select *,year(post_date) as year from halo_post where post_status=0 and year(post_date)=:year order by post_date desc",nativeQuery = true)
|
||||
List<Post> findPostByYear(@Param("year") String year);
|
||||
|
||||
/**
|
||||
|
@ -132,7 +132,7 @@ public interface PostRepository extends JpaRepository<Post,Long>{
|
|||
* @param pageable pageable
|
||||
* @return page
|
||||
*/
|
||||
@Query(value = "select * from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month order by ?#{#pageable}",countQuery = "select count(*) from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month",nativeQuery = true)
|
||||
@Query(value = "select * from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month order by post_date desc",countQuery = "select count(*) from halo_post where post_status=0 and year(post_date)=:year and month(post_date)=:month",nativeQuery = true)
|
||||
Page<Post> findPostByYearAndMonth(@Param("year") String year,@Param("month") String month,Pageable pageable);
|
||||
|
||||
List<Post> findPostByCategories(Category category);
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
package cc.ryanc.halo.security;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.safety.Whitelist;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2018/4/25
|
||||
*/
|
||||
public class JsoupUtil {
|
||||
/**
|
||||
* 使用自带的basicWithImages 白名单
|
||||
* 允许的便签有a,b,blockquote,br,cite,code,dd,dl,dt,em,i,li,ol,p,pre,q,small,span,
|
||||
* strike,strong,sub,sup,u,ul,img
|
||||
* 以及a标签的href,img标签的src,align,alt,height,width,title属性
|
||||
*/
|
||||
private static final Whitelist whitelist = Whitelist.basicWithImages();
|
||||
/** 配置过滤化参数,不对代码进行格式化 */
|
||||
private static final Document.OutputSettings outputSettings = new Document.OutputSettings().prettyPrint(false);
|
||||
static {
|
||||
// 富文本编辑时一些样式是使用style来进行实现的
|
||||
// 比如红色字体 style="color:red;"
|
||||
// 所以需要给所有标签添加style属性
|
||||
whitelist.addAttributes(":all", "style");
|
||||
}
|
||||
|
||||
public static String clean(String content) {
|
||||
return Jsoup.clean(content, "", whitelist, outputSettings);
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
package cc.ryanc.halo.security;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2018/4/25
|
||||
*/
|
||||
@Slf4j
|
||||
public class XssFilter implements Filter {
|
||||
|
||||
private static boolean IS_INCLUDE_RICH_TEXT = false;
|
||||
|
||||
public List<String> excludes = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException,ServletException {
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug("xss filter is open");
|
||||
}
|
||||
|
||||
HttpServletRequest req = (HttpServletRequest) request;
|
||||
HttpServletResponse resp = (HttpServletResponse) response;
|
||||
if(handleExcludeURL(req, resp)){
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request,IS_INCLUDE_RICH_TEXT);
|
||||
filterChain.doFilter(xssRequest, response);
|
||||
}
|
||||
|
||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
if (excludes == null || excludes.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String url = request.getServletPath();
|
||||
for (String pattern : excludes) {
|
||||
Pattern p = Pattern.compile("^" + pattern);
|
||||
Matcher m = p.matcher(url);
|
||||
if (m.find()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
if(log.isDebugEnabled()){
|
||||
log.debug("xss filter init~~~~~~~~~~~~");
|
||||
}
|
||||
String isIncludeRichText = filterConfig.getInitParameter("isIncludeRichText");
|
||||
if(StringUtils.isNotBlank(isIncludeRichText)){
|
||||
IS_INCLUDE_RICH_TEXT = BooleanUtils.toBoolean(isIncludeRichText);
|
||||
}
|
||||
|
||||
String temp = filterConfig.getInitParameter("excludes");
|
||||
if (temp != null) {
|
||||
String[] url = temp.split(",");
|
||||
for (int i = 0; url != null && i < url.length; i++) {
|
||||
excludes.add(url[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {}
|
||||
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
package cc.ryanc.halo.security;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @version : 1.0
|
||||
* @date : 2018/4/25
|
||||
*/
|
||||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
HttpServletRequest orgRequest = null;
|
||||
private boolean isIncludeRichText = false;
|
||||
|
||||
public XssHttpServletRequestWrapper(HttpServletRequest request, boolean isIncludeRichText) {
|
||||
super(request);
|
||||
orgRequest = request;
|
||||
this.isIncludeRichText = isIncludeRichText;
|
||||
}
|
||||
|
||||
/**
|
||||
* 覆盖getParameter方法,将参数名和参数值都做xss过滤。<br/>
|
||||
* 如果需要获得原始的值,则通过super.getParameterValues(name)来获取<br/>
|
||||
* getParameterNames,getParameterValues和getParameterMap也可能需要覆盖
|
||||
*/
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
if(("content".equals(name) || name.endsWith("WithHtml")) && !isIncludeRichText){
|
||||
return super.getParameter(name);
|
||||
}
|
||||
name = JsoupUtil.clean(name);
|
||||
String value = super.getParameter(name);
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
value = JsoupUtil.clean(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
String[] arr = super.getParameterValues(name);
|
||||
if(arr != null){
|
||||
for (int i=0;i<arr.length;i++) {
|
||||
arr[i] = JsoupUtil.clean(arr[i]);
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 覆盖getHeader方法,将参数名和参数值都做xss过滤。<br/>
|
||||
* 如果需要获得原始的值,则通过super.getHeaders(name)来获取<br/>
|
||||
* getHeaderNames 也可能需要覆盖
|
||||
*/
|
||||
@Override
|
||||
public String getHeader(String name) {
|
||||
name = JsoupUtil.clean(name);
|
||||
String value = super.getHeader(name);
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
value = JsoupUtil.clean(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最原始的request
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public HttpServletRequest getOrgRequest() {
|
||||
return orgRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最原始的request的静态方法
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static HttpServletRequest getOrgRequest(HttpServletRequest req) {
|
||||
if (req instanceof XssHttpServletRequestWrapper) {
|
||||
return ((XssHttpServletRequestWrapper) req).getOrgRequest();
|
||||
}
|
||||
return req;
|
||||
}
|
||||
}
|
|
@ -40,6 +40,13 @@ public interface CommentService {
|
|||
*/
|
||||
Page<Comment> findAllComments(Integer status, Pageable pageable);
|
||||
|
||||
/**
|
||||
* 根据评论状态查询评论
|
||||
*
|
||||
* @param status 评论状态
|
||||
* @return list
|
||||
*/
|
||||
List<Comment> findAllComments(Integer status);
|
||||
|
||||
/**
|
||||
* 查询所有评论,不分页
|
||||
|
|
|
@ -58,6 +58,17 @@ public class CommentServiceImpl implements CommentService {
|
|||
return commentRepository.findCommentsByCommentStatus(status,pageable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据评论状态查询评论
|
||||
*
|
||||
* @param status 评论状态
|
||||
* @return list
|
||||
*/
|
||||
@Override
|
||||
public List<Comment> findAllComments(Integer status) {
|
||||
return commentRepository.findCommentsByCommentStatus(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有评论,不分页
|
||||
*
|
||||
|
|
|
@ -5,8 +5,6 @@ import cc.ryanc.halo.repository.OptionsRepository;
|
|||
import cc.ryanc.halo.service.OptionsService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
|
|
@ -278,7 +278,7 @@ public class PostServiceImpl implements PostService {
|
|||
*/
|
||||
@Override
|
||||
public Page<Post> findPostByYearAndMonth(String year, String month, Pageable pageable) {
|
||||
return postRepository.findPostByYearAndMonth(year,month,pageable);
|
||||
return postRepository.findPostByYearAndMonth(year,month,null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,8 +3,6 @@ package cc.ryanc.halo.util;
|
|||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.Theme;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.sun.syndication.feed.rss.Channel;
|
||||
import com.sun.syndication.feed.rss.Content;
|
||||
import com.sun.syndication.feed.rss.Item;
|
||||
|
@ -12,7 +10,6 @@ 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.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
@ -261,19 +258,15 @@ public class HaloUtil {
|
|||
File[] moduleFiles = modulePath.listFiles();
|
||||
if(null!=moduleFiles) {
|
||||
for (File file : moduleFiles) {
|
||||
if (file.isFile()) {
|
||||
if (file.getName().endsWith(".ftl")) {
|
||||
tpls.add("module/" + file.getName());
|
||||
}
|
||||
if (file.isFile() && file.getName().endsWith(".ftl")) {
|
||||
tpls.add("module/" + file.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
if(null!=baseFiles){
|
||||
for (File file:baseFiles){
|
||||
if(file.isFile()) {
|
||||
if (file.getName().endsWith(".ftl")) {
|
||||
tpls.add(file.getName());
|
||||
}
|
||||
if(file.isFile() && file.getName().endsWith(".ftl")) {
|
||||
tpls.add(file.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,7 @@ import cc.ryanc.halo.model.domain.Post;
|
|||
import cc.ryanc.halo.model.domain.User;
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.model.dto.LogsRecord;
|
||||
import cc.ryanc.halo.service.CommentService;
|
||||
import cc.ryanc.halo.service.LogsService;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import cc.ryanc.halo.service.*;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -85,8 +82,6 @@ public class AdminController extends BaseController{
|
|||
model.addAttribute("comments",comments);
|
||||
|
||||
model.addAttribute("mediaCount",HaloConst.ATTACHMENTS.size());
|
||||
|
||||
this.getNewComments(session);
|
||||
return "admin/admin_index";
|
||||
}
|
||||
|
||||
|
@ -164,9 +159,9 @@ public class AdminController extends BaseController{
|
|||
@GetMapping(value = "/logOut")
|
||||
public String logOut(HttpSession session){
|
||||
User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY);
|
||||
log.info("用户["+user.getUserName()+"]退出登录");
|
||||
logsService.saveByLogs(new Logs(LogsRecord.LOGOUT,user.getUserName(),HaloUtil.getIpAddr(request),HaloUtil.getDate()));
|
||||
session.invalidate();
|
||||
log.info("用户["+user.getUserName()+"]退出登录");
|
||||
return "redirect:/admin/login";
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,6 @@ public class CommentController extends BaseController{
|
|||
HttpSession session){
|
||||
try {
|
||||
commentService.updateCommentStatus(commentId,2);
|
||||
this.getNewComments(session);
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:{0}",e.getMessage());
|
||||
}
|
||||
|
@ -132,7 +131,6 @@ public class CommentController extends BaseController{
|
|||
log.error("邮件服务器未配置:{0}",e.getMessage());
|
||||
}
|
||||
}
|
||||
this.getNewComments(session);
|
||||
return "redirect:/admin/comments?status="+status;
|
||||
}
|
||||
|
||||
|
@ -150,7 +148,6 @@ public class CommentController extends BaseController{
|
|||
HttpSession session){
|
||||
try{
|
||||
commentService.removeByCommentId(commentId);
|
||||
this.getNewComments(session);
|
||||
}catch (Exception e){
|
||||
log.error("删除评论失败:{0}",e.getMessage());
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package cc.ryanc.halo.web.controller.admin;
|
||||
|
||||
import cc.ryanc.halo.model.dto.HaloConst;
|
||||
import cc.ryanc.halo.service.OptionsService;
|
||||
import freemarker.template.Configuration;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
|
@ -22,6 +23,9 @@ public class OptionController {
|
|||
@Autowired
|
||||
private OptionsService optionsService;
|
||||
|
||||
@Autowired
|
||||
private Configuration configuration;
|
||||
|
||||
/**
|
||||
* 请求跳转到option页面并完成渲染
|
||||
*
|
||||
|
@ -43,8 +47,8 @@ public class OptionController {
|
|||
public boolean saveOptions(@RequestParam Map<String,String> options){
|
||||
try {
|
||||
optionsService.saveOptions(options);
|
||||
HaloConst.OPTIONS.clear();
|
||||
HaloConst.OPTIONS = optionsService.findAllOptions();
|
||||
//刷新options
|
||||
configuration.setSharedVariable("options",optionsService.findAllOptions());
|
||||
log.info("所保存的设置选项列表:"+options);
|
||||
return true;
|
||||
}catch (Exception e){
|
||||
|
|
|
@ -122,15 +122,11 @@ public class PostController extends BaseController{
|
|||
*/
|
||||
@GetMapping(value = "/new")
|
||||
public String newPost(Model model){
|
||||
try {
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
List<Tag> tags = tagService.findAllTags();
|
||||
model.addAttribute("categories",categories);
|
||||
model.addAttribute("tags",tags);
|
||||
model.addAttribute("btnPush","发布");
|
||||
}catch (Exception e){
|
||||
log.error("未知错误:{0}",e.getMessage());
|
||||
}
|
||||
List<Category> categories = categoryService.findAllCategories();
|
||||
List<Tag> tags = tagService.findAllTags();
|
||||
model.addAttribute("categories",categories);
|
||||
model.addAttribute("tags",tags);
|
||||
model.addAttribute("btnPush","发布");
|
||||
return "admin/admin_editor";
|
||||
}
|
||||
|
||||
|
@ -161,7 +157,7 @@ public class PostController extends BaseController{
|
|||
post.setUser(user);
|
||||
List<Category> categories = categoryService.strListToCateList(cateList);
|
||||
post.setCategories(categories);
|
||||
List<Tag> tags = tagService.strListToTagList(tagList);
|
||||
List<Tag> tags = tagService.strListToTagList(tagList.replaceAll(" ",""));
|
||||
post.setTags(tags);
|
||||
postService.saveByPost(post);
|
||||
log.info("已发表新文章:"+post.getPostTitle());
|
||||
|
|
|
@ -67,7 +67,7 @@ public class ThemeController extends BaseController{
|
|||
public boolean activeTheme(@PathParam("siteTheme") String siteTheme,
|
||||
HttpServletRequest request){
|
||||
try {
|
||||
//保存主题设置项在数据库
|
||||
//保存主题设置项
|
||||
optionsService.saveOption("theme",siteTheme);
|
||||
//设置主题
|
||||
BaseController.THEME = siteTheme;
|
||||
|
@ -77,7 +77,7 @@ public class ThemeController extends BaseController{
|
|||
);
|
||||
return true;
|
||||
}catch (Exception e){
|
||||
log.error("主题设置失败,当前主题为:"+BaseController.THEME);
|
||||
log.error("主题设置失败,当前主题为:"+siteTheme);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ package cc.ryanc.halo.web.controller.admin;
|
|||
import cc.ryanc.halo.model.domain.User;
|
||||
import cc.ryanc.halo.service.UserService;
|
||||
import cc.ryanc.halo.util.HaloUtil;
|
||||
import freemarker.template.Configuration;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
@ -25,6 +25,9 @@ public class UserController {
|
|||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private Configuration configuration;
|
||||
|
||||
/**
|
||||
* 获取用户信息并跳转
|
||||
*
|
||||
|
@ -48,6 +51,7 @@ public class UserController {
|
|||
try{
|
||||
if(null!=user){
|
||||
userService.saveByUser(user);
|
||||
configuration.setSharedVariable("user",userService.findUser());
|
||||
session.invalidate();
|
||||
}else{
|
||||
return false;
|
||||
|
|
|
@ -1,14 +1,5 @@
|
|||
package cc.ryanc.halo.web.controller.core;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Comment;
|
||||
import cc.ryanc.halo.service.CommentService;
|
||||
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 javax.servlet.http.HttpSession;
|
||||
|
||||
/**
|
||||
* @author : RYAN0UP
|
||||
* @date : 2017/12/15
|
||||
|
@ -22,9 +13,6 @@ public abstract class BaseController {
|
|||
*/
|
||||
public static String THEME = "halo";
|
||||
|
||||
@Autowired
|
||||
private CommentService commentService;
|
||||
|
||||
/**
|
||||
* 根据主题名称渲染页面
|
||||
*
|
||||
|
@ -37,17 +25,4 @@ public abstract class BaseController {
|
|||
themeStr.append("/");
|
||||
return themeStr.append(pageName).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取新评论
|
||||
*
|
||||
* @param session session
|
||||
*/
|
||||
protected void getNewComments(HttpSession session){
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"commentDate");
|
||||
Pageable pageable = new PageRequest(0,999,sort);
|
||||
Page<Comment> comments = commentService.findAllComments(1,pageable);
|
||||
session.removeAttribute("newComments");
|
||||
session.setAttribute("newComments",comments.getContent());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package cc.ryanc.halo.web.controller.front;
|
||||
|
||||
import cc.ryanc.halo.model.domain.Post;
|
||||
import cc.ryanc.halo.model.dto.Archive;
|
||||
import cc.ryanc.halo.service.PostService;
|
||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -60,20 +59,6 @@ public class ArchivesController extends BaseController {
|
|||
Pageable pageable = new PageRequest(page-1,5,sort);
|
||||
Page<Post> posts = postService.findPostByStatus(0,pageable);
|
||||
model.addAttribute("posts",posts);
|
||||
|
||||
model.addAttribute("is_archives",true);
|
||||
|
||||
//包含[List<Post>,year,month,count]
|
||||
List<Archive> archives = postService.findPostGroupByYearAndMonth();
|
||||
model.addAttribute("archives",archives);
|
||||
|
||||
//包含[List<Post>,year,count]
|
||||
List<Archive> archivesLess = postService.findPostGroupByYear();
|
||||
model.addAttribute("archivesLess",archivesLess);
|
||||
|
||||
//是否是归档页,用于判断输出链接
|
||||
model.addAttribute("isArchives","true");
|
||||
|
||||
return this.render("archives");
|
||||
}
|
||||
|
||||
|
@ -92,19 +77,9 @@ public class ArchivesController extends BaseController {
|
|||
log.info(year);
|
||||
log.info(month);
|
||||
|
||||
//根据年月查出的文章数据,分页
|
||||
Sort sort = new Sort(Sort.Direction.DESC,"post_date");
|
||||
Pageable pageable = new PageRequest(0,5,sort);
|
||||
Page<Post> posts = postService.findPostByYearAndMonth(year,month,pageable);
|
||||
Page<Post> posts = postService.findPostByYearAndMonth(year,month,null);
|
||||
model.addAttribute("posts",posts);
|
||||
|
||||
//归档数据,包含[year,month,count,List<Post>]
|
||||
List<Archive> archives = postService.findPostGroupByYearAndMonth();
|
||||
model.addAttribute("archives",archives);
|
||||
|
||||
//是否是归档页,用于判断输出链接
|
||||
model.addAttribute("isArchives","true");
|
||||
|
||||
return this.render("archives");
|
||||
}
|
||||
|
||||
|
@ -138,11 +113,6 @@ public class ArchivesController extends BaseController {
|
|||
}
|
||||
model.addAttribute("post",post);
|
||||
|
||||
//归档数据,包含[year,month,count,List<Post>]
|
||||
List<Archive> archives = postService.findPostGroupByYearAndMonth();
|
||||
|
||||
model.addAttribute("archives",archives);
|
||||
|
||||
return this.render("post");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,12 +69,6 @@ public class IndexController extends BaseController {
|
|||
Page<Post> posts = postService.findPostByStatus(0,pageable);
|
||||
model.addAttribute("posts",posts);
|
||||
|
||||
model.addAttribute("is_home",true);
|
||||
|
||||
//归档数据,包含[year,month,count,List<Post>]
|
||||
List<Archive> archives = postService.findPostGroupByYearAndMonth();
|
||||
model.addAttribute("archives",archives);
|
||||
|
||||
return this.render("index");
|
||||
}
|
||||
|
||||
|
|
|
@ -53,9 +53,6 @@ public class PagesController extends BaseController {
|
|||
public String gallery(Model model){
|
||||
List<Gallery> galleries = galleryService.findAllGalleries();
|
||||
model.addAttribute("galleries",galleries);
|
||||
|
||||
model.addAttribute("is_gallery",true);
|
||||
|
||||
return this.render("gallery");
|
||||
}
|
||||
|
||||
|
@ -67,17 +64,9 @@ public class PagesController extends BaseController {
|
|||
*/
|
||||
@GetMapping(value = "/links")
|
||||
public String links(Model model){
|
||||
|
||||
//所有友情链接
|
||||
List<Link> links = linkService.findAllLinks();
|
||||
model.addAttribute("links",links);
|
||||
|
||||
model.addAttribute("is_links",true);
|
||||
|
||||
//归档数据,包含[year,month,count,List<Post>]
|
||||
List<Archive> archives = postService.findPostGroupByYearAndMonth();
|
||||
model.addAttribute("archives",archives);
|
||||
|
||||
return this.render("links");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,11 +47,6 @@ public class TagsController extends BaseController {
|
|||
//所有标签
|
||||
List<Tag> tags = tagService.findAllTags();
|
||||
model.addAttribute("tags",tags);
|
||||
|
||||
//归档数据,包含[year,month,count,List<Post>]
|
||||
List<Archive> archives = postService.findPostGroupByYearAndMonth();
|
||||
model.addAttribute("archives",archives);
|
||||
|
||||
return this.render("tags");
|
||||
}
|
||||
|
||||
|
@ -88,6 +83,7 @@ public class TagsController extends BaseController {
|
|||
Pageable pageable = new PageRequest(page-1,size,sort);
|
||||
Page<Post> posts = postService.findPostsByTags(tag,pageable);
|
||||
model.addAttribute("posts",posts);
|
||||
model.addAttribute("tag",tag);
|
||||
return this.render("index");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary btn-sm ">确定${statusName}</button>
|
||||
<a data-pjax="true" href="/admin/category" class="btn btn-info btn-sm ">返回添加</a>
|
||||
</div>
|
||||
</form>
|
||||
<#else >
|
||||
|
|
|
@ -72,6 +72,9 @@
|
|||
</#if>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary btn-sm ">确定${statusName}</button>
|
||||
<#if updateMenu??>
|
||||
<a data-pjax="true" href="/admin/menus" class="btn btn-info btn-sm ">返回添加</a>
|
||||
</#if>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -219,13 +219,13 @@
|
|||
</label>
|
||||
<div class="col-sm-4">
|
||||
<select class="form-control" id="nativeCommentAvatar" name="native_comment_avatar">
|
||||
<option value="default" ${((options.native_comment_avatar?default('default'))=='default')?string('selected','')}>神秘人</option>
|
||||
<option value="gravatar" ${((options.native_comment_avatar?default('default'))=='gravatar')?string('selected','')}>Gravatar标志</option>
|
||||
<option value="mm" ${((options.native_comment_avatar?default('default'))=='mm')?string('selected','')}>默认</option>
|
||||
<option value="identicon" ${((options.native_comment_avatar?default('default'))=='identicon')?string('selected','')}>抽象几何图形</option>
|
||||
<option value="monsterid" ${((options.native_comment_avatar?default('default'))=='monsterid')?string('selected','')}>小怪物</option>
|
||||
<option value="wavatar" ${((options.native_comment_avatar?default('default'))=='wavatar')?string('selected','')}>Wavatar</option>
|
||||
<option value="retro" ${((options.native_comment_avatar?default('default'))=='retro')?string('selected','')}>复古</option>
|
||||
<option value="hide" ${((options.native_comment_avatar?default('default'))=='hide')?string('selected','')}>不显示头像</option>
|
||||
<option value="robohash" ${((options.native_comment_avatar?default('default'))=='robohash')?string('selected','')}>机器人</option>
|
||||
<option value="blank" ${((options.native_comment_avatar?default('default'))=='blank')?string('selected','')}>不显示头像</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -47,7 +47,10 @@
|
|||
<small>*网站的描述,部分主题可显示</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer"><button type="submit" class="btn btn-primary btn-sm ">确定${statusName}</button></div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary btn-sm ">确定${statusName}</button>
|
||||
<a data-pjax="true" href="/admin/page/links" class="btn btn-info btn-sm ">返回添加</a>
|
||||
</div>
|
||||
</form>
|
||||
<#else>
|
||||
<form action="/admin/page/links/save" method="post" role="form" onsubmit="return isNull()">
|
||||
|
@ -73,7 +76,9 @@
|
|||
<small>*网站的描述,部分主题可显示</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer"><button type="submit" class="btn btn-primary btn-sm ">确定${statusName}</button></div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary btn-sm ">确定${statusName}</button>
|
||||
</div>
|
||||
</form>
|
||||
</#if>
|
||||
</div>
|
||||
|
|
|
@ -175,6 +175,7 @@
|
|||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="submit" class="btn btn-primary btn-sm ">确定${statusName}</button>
|
||||
<a data-pjax="true" href="/admin/tag" class="btn btn-info btn-sm ">返回添加</a>
|
||||
<#if updateTag.posts?size = 0>
|
||||
<a data-pjax="true" href="/admin/tag/remove?tagId=${updateTag.tagId}" class="btn btn-danger btn-sm pull-right">删除</a>
|
||||
</#if>
|
||||
|
|
|
@ -10,33 +10,42 @@
|
|||
<div class="navbar-custom-menu">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="/" title="跳转到前台" target="_blank"><i class="fa fa-location-arrow"></i></a></li>
|
||||
<@commonTag method="newComments">
|
||||
<li class="dropdown messages-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<i class="fa fa-envelope-o"></i>
|
||||
<#if newComments?size gt 0>
|
||||
<span class="label label-success">${newComments?size}</span>
|
||||
<span class="label label-success">${newComments?size}</span>
|
||||
</#if>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li class="header">你有${newComments?size}条新评论</li>
|
||||
<li>
|
||||
<ul class="menu">
|
||||
<#list newComments! as comment>
|
||||
<#if newComments?size gt 0>
|
||||
<#assign x=0>
|
||||
<#list newComments?sort_by("commentDate")?reverse as comment>
|
||||
<#assign x = x+1>
|
||||
<li>
|
||||
<a href="/admin/comments?status=1">
|
||||
<div class="pull-left">
|
||||
<img src="http://www.gravatar.com/avatar/${comment.commentAuthorAvatarMd5?if_exists}?s=256&d=gravatar" class="img-circle" alt="User Image">
|
||||
<img src="http://www.gravatar.com/avatar/${comment.commentAuthorAvatarMd5?default("hash")}?s=256&d=${options.native_comment_avatar?default("mm")}" class="img-circle" alt="User Image">
|
||||
</div>
|
||||
<h5>${comment.commentAuthor}<small> ${comment.commentDate}</small></h5>
|
||||
<p>${comment.commentContent}</p>
|
||||
</a>
|
||||
</li>
|
||||
<#if x==10>
|
||||
<#break >
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="footer"><a href="/admin/comments">查看所有评论</a></li>
|
||||
<li class="footer"><a href="/admin/comments?status=1">查看所有评论</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</@commonTag>
|
||||
<li class="dropdown user user-menu">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<img src="<#if user_session.userAvatar?if_exists!="">${user_session.userAvatar}<#else >/static/images/default.png</#if>" class="user-image" alt="User Image">
|
||||
|
|
|
@ -7,21 +7,23 @@
|
|||
<div class="content">
|
||||
<div class="archive animated fadeInDown">
|
||||
<ul class="list-with-title">
|
||||
<#list archivesLess as archive>
|
||||
<div class="listing-title">${archive.year}</div>
|
||||
<ul class="listing">
|
||||
<#list archive.posts?sort_by("postDate")?reverse as post>
|
||||
<div class="listing-item">
|
||||
<div class="listing-post">
|
||||
<a href="/archives/${post.postUrl}" title="${post.postTitle}">${post.postTitle}</a>
|
||||
<div class="post-time">
|
||||
<span class="date">${post.postDate?string("yyyy-MM-dd")}</span>
|
||||
<@articleTag method="archivesLess">
|
||||
<#list archivesLess as archive>
|
||||
<div class="listing-title">${archive.year}</div>
|
||||
<ul class="listing">
|
||||
<#list archive.posts?sort_by("postDate")?reverse as post>
|
||||
<div class="listing-item">
|
||||
<div class="listing-post">
|
||||
<a href="/archives/${post.postUrl}" title="${post.postTitle}">${post.postTitle}</a>
|
||||
<div class="post-time">
|
||||
<span class="date">${post.postDate?string("yyyy-MM-dd")}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</#list>
|
||||
</ul>
|
||||
</#list>
|
||||
</#list>
|
||||
</ul>
|
||||
</#list>
|
||||
</@articleTag>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<#include "module/macro.ftl">
|
||||
<@head title="${options.blog_title?default('Anatole')}" keywords="${options.seo_keywords?default('Anatole')}" description="${options.seo_desc?default('Anatole')}"></@head>
|
||||
<#if tag??>
|
||||
<@head title="${tag.tagName} · ${options.blog_title?default('Anatole')}" keywords="${options.seo_keywords?default('Anatole')}" description="${options.seo_desc?default('Anatole')}"></@head>
|
||||
<#else>
|
||||
<@head title="${options.blog_title?default('Anatole')}" keywords="${options.seo_keywords?default('Anatole')}" description="${options.seo_desc?default('Anatole')}"></@head>
|
||||
</#if>
|
||||
<#include "module/sidebar.ftl">
|
||||
<div class="main">
|
||||
<#include "module/page-top.ftl">
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
<li class="active">
|
||||
<a href="#sns" data-toggle="tab">社交资料</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#style" data-toggle="tab">样式设置</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#about" data-toggle="tab">关于</a>
|
||||
</li>
|
||||
|
@ -86,6 +89,38 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!--样式设置-->
|
||||
<div class="tab-pane" id="style">
|
||||
<form method="post" class="form-horizontal" id="anatoleStyleOptions">
|
||||
<div class="box-body">
|
||||
<div class="form-group">
|
||||
<label for="anatoleStyleFavicon" class="col-sm-4 control-label">Favicon:</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="anatoleStyleFavicon" name="anatole_style_favicon" value="${options.anatole_style_favicon?default("/anatole/source/images/favicon.png")}" >
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default btn-flat" type="button" onclick="openAttach('anatoleStyleFavicon')">选择</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="anatoleStyleHitokoto" class="col-sm-4 control-label">博客描述开启一言:</label>
|
||||
<div class="col-sm-8">
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="anatole_style_hitokoto" id="anatoleStyleHitokoto" value="true" ${((options.anatole_style_hitokoto?if_exists)=='true')?string('checked','')}> 开启
|
||||
</label>
|
||||
<label class="radio-inline">
|
||||
<input type="radio" name="anatole_style_hitokoto" id="anatoleStyleHitokoto" value="false" ${((options.anatole_style_hitokoto?default('false'))=='false')?string('checked','')}> 关闭
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="button" class="btn btn-primary btn-sm pull-right" onclick="saveThemeOptions('anatoleStyleOptions')">保存设置</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<!-- 关于该主题 -->
|
||||
<div class="tab-pane" id="about">
|
||||
<div class="box box-widget widget-user-2">
|
||||
|
@ -127,5 +162,16 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
function openAttach(id) {
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '所有附件',
|
||||
shadeClose: true,
|
||||
shade: 0.5,
|
||||
area: ['90%', '90%'],
|
||||
content: '/admin/attachments/select?id='+id,
|
||||
scrollbar: false
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</html>
|
|
@ -20,12 +20,12 @@
|
|||
<span class="date">${post.postDate?string("yyyy-MM-dd")}</span>
|
||||
<i class="fa fa-comment-o"></i>
|
||||
<a href="/archives/${post.postUrl}#comment_widget">Comments</a>
|
||||
<if post.tags??>
|
||||
<#if post.tags?size gt 0>
|
||||
<i class="fa fa-tag"></i>
|
||||
<#list post.tags as tag>
|
||||
<a href="/tags/${tag.tagUrl}" class="tag"> ${tag.tagName}</a>
|
||||
</#list>
|
||||
</if>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
<a href="/">${options.blog_title?default("ANATOLE")}</a>
|
||||
</h3>
|
||||
<div class="description">
|
||||
<p>${user.userDesc?default("A other Halo theme")}</p>
|
||||
<#if options.anatole_style_hitokoto?default("false")=="true">
|
||||
<p id="yiyan">获取中...</p>
|
||||
<#else >
|
||||
<p>${user.userDesc?default("A other Halo theme")}</p>
|
||||
</#if>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
class="fa fa-weibo"></a>
|
||||
</div>
|
||||
<div class="twitter">
|
||||
<a href="http://twitter.com/home?status=http://anatole.cai-cai.me/post/2015-05-22 ,Anatole,更轻量的Evernote第三方客户端-Alternote!,;"
|
||||
<a href="http://twitter.com/home?status=${options.blog_url}/archives/${post.postUrl} ,${options.blog_title?if_exists},${post.postTitle},;"
|
||||
class="fa fa-twitter"></a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,18 +4,20 @@
|
|||
<#include "module/header.ftl">
|
||||
<div class="main-content">
|
||||
<section class="container">
|
||||
<#if archives ??>
|
||||
<#list archives as archive>
|
||||
<@articleTag method="archives">
|
||||
<#if archives ??>
|
||||
<#list archives as archive>
|
||||
<h1 class="animated fadeInDown">${archive.year}年${archive.month}月 (${archive.count})</h1>
|
||||
<ul>
|
||||
<#list archive.posts as post>
|
||||
<li class="animated fadeInDown">
|
||||
<a href="/article/${post.postUrl}">${post.postTitle}</a>
|
||||
<a href="/archives/${post.postUrl}">${post.postTitle}</a>
|
||||
</li>
|
||||
</#list>
|
||||
</ul>
|
||||
</#list>
|
||||
</#if>
|
||||
</#list>
|
||||
</#if>
|
||||
</@articleTag>
|
||||
</section>
|
||||
</div>
|
||||
<@footer></@footer>
|
|
@ -53,7 +53,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<#include "module/comment.ftl">
|
||||
</section>
|
||||
</div>
|
||||
<@footer></@footer>
|
|
@ -8,11 +8,13 @@
|
|||
</div>
|
||||
<div class="navbar-menu pull-right hidden-xs">
|
||||
<ul>
|
||||
<#list menus?sort_by('menuSort') as menu>
|
||||
<li>
|
||||
<a href="${menu.menuUrl}">${menu.menuName}</a>
|
||||
</li>
|
||||
</#list>
|
||||
<@commonTag method="menus">
|
||||
<#list menus?sort_by('menuSort') as menu>
|
||||
<li>
|
||||
<a href="${menu.menuUrl}">${menu.menuName}</a>
|
||||
</li>
|
||||
</#list>
|
||||
</@commonTag>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -28,13 +28,15 @@
|
|||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<#if archives??>
|
||||
<#list archives?sort_by("year")?reverse as archive>
|
||||
<li>
|
||||
<a class="sidebar_archives-link" href="/archives/${archive.year}/${archive.month}/">${archive.month}月 ${archive.year}<span class="sidebar_archives-count">${archive.count}</span></a>
|
||||
</li>
|
||||
</#list>
|
||||
</#if>
|
||||
<@articleTag method="archives">
|
||||
<#if archives??>
|
||||
<#list archives?sort_by("year")?reverse as archive>
|
||||
<li>
|
||||
<a class="sidebar_archives-link" href="/archives/${archive.year}/${archive.month}/">${archive.month}月 ${archive.year}<span class="sidebar_archives-count">${archive.count}</span></a>
|
||||
</li>
|
||||
</#list>
|
||||
</#if>
|
||||
</@articleTag>
|
||||
</ul>
|
||||
</li>
|
||||
</#if>
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
|
||||
<title>${title?default("Anatole")}</title>
|
||||
<meta content="yes" name="apple-mobile-web-app-capable" />
|
||||
<meta content="black" name="apple-mobile-web-app-status-bar-style" />
|
||||
<meta content="telephone=no" name="format-detection" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="author" content="" />
|
||||
<meta name="author" content="${user.userDisplayName?if_exists}" />
|
||||
<meta name="keywords" content="${keywords?default("Anatole")}"/>
|
||||
<meta name="description" content="${description?default("Anatole")}" />
|
||||
<link rel="shortcut icon" href="/anatole/source/images/favicon.png" type="image/x-icon" />
|
||||
<link rel="shortcut icon" href="${options.anatole_style_favicon?default("/anatole/source/images/favicon.png")}" type="image/x-icon" />
|
||||
<link href="/anatole/source/css/font-awesome.min.css" type="text/css" rel="stylesheet"/>
|
||||
<link rel="stylesheet" href="/anatole/source/css/blog_basic.css?version=88107691fe">
|
||||
<link href="/anatole/source/css/style.css" type="text/css" rel="stylesheet" />
|
||||
|
@ -38,6 +38,19 @@
|
|||
if (!urlstatus) {
|
||||
$(".nav li a").eq(0).addClass('current');
|
||||
}
|
||||
|
||||
<#if options.anatole_style_hitokoto?default("false")=="true">
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('get', 'https://v1.hitokoto.cn');
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
var data = JSON.parse(xhr.responseText);
|
||||
var yiyan = document.getElementById('yiyan');
|
||||
yiyan.innerText = data.hitokoto+" -「"+data.from+"」";
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
</#if>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue