mirror of https://github.com/halo-dev/halo
Refactor and beauty codes
parent
f87dc413e3
commit
468a0323b4
|
@ -17,7 +17,6 @@ import run.halo.app.model.params.UserParam;
|
||||||
import run.halo.app.model.properties.BlogProperties;
|
import run.halo.app.model.properties.BlogProperties;
|
||||||
import run.halo.app.model.properties.PrimaryProperties;
|
import run.halo.app.model.properties.PrimaryProperties;
|
||||||
import run.halo.app.model.support.HaloConst;
|
import run.halo.app.model.support.HaloConst;
|
||||||
import run.halo.app.model.support.Theme;
|
|
||||||
import run.halo.app.service.OptionService;
|
import run.halo.app.service.OptionService;
|
||||||
import run.halo.app.service.ThemeService;
|
import run.halo.app.service.ThemeService;
|
||||||
import run.halo.app.service.UserService;
|
import run.halo.app.service.UserService;
|
||||||
|
@ -63,7 +62,6 @@ public class StartedListener implements ApplicationListener<ApplicationStartedEv
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(ApplicationStartedEvent event) {
|
public void onApplicationEvent(ApplicationStartedEvent event) {
|
||||||
// save halo version to database
|
// save halo version to database
|
||||||
this.cacheThemes();
|
|
||||||
this.cacheOwo();
|
this.cacheOwo();
|
||||||
this.cacheActiveTheme();
|
this.cacheActiveTheme();
|
||||||
this.printStartInfo();
|
this.printStartInfo();
|
||||||
|
@ -96,22 +94,12 @@ public class StartedListener implements ApplicationListener<ApplicationStartedEv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Cache themes to map
|
|
||||||
*/
|
|
||||||
private void cacheThemes() {
|
|
||||||
final List<Theme> themes = themeService.getThemes();
|
|
||||||
if (null != themes) {
|
|
||||||
HaloConst.THEMES = themes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get active theme
|
* Get active theme
|
||||||
*/
|
*/
|
||||||
private void cacheActiveTheme() {
|
private void cacheActiveTheme() {
|
||||||
try {
|
try {
|
||||||
configuration.setSharedVariable("themeName", themeService.getTheme());
|
configuration.setSharedVariable("themeName", themeService.getActivatedTheme());
|
||||||
} catch (TemplateModelException e) {
|
} catch (TemplateModelException e) {
|
||||||
log.error("", e);
|
log.error("", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,16 +23,23 @@ import javax.persistence.*;
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class ThemeSetting extends BaseEntity {
|
public class ThemeSetting extends BaseEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme id as id.
|
||||||
|
*/
|
||||||
@Id
|
@Id
|
||||||
|
@Column(name = "id", columnDefinition = "varchar(255) not null")
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
private Integer id;
|
private String id;
|
||||||
|
|
||||||
@Column(name = "theme", columnDefinition = "varchar(255) not null")
|
|
||||||
private String theme;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting key.
|
||||||
|
*/
|
||||||
@Column(name = "setting_key", columnDefinition = "varchar(255) not null")
|
@Column(name = "setting_key", columnDefinition = "varchar(255) not null")
|
||||||
private String key;
|
private String key;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting value
|
||||||
|
*/
|
||||||
@Column(name = "setting_value", columnDefinition = "varchar(10239) not null")
|
@Column(name = "setting_value", columnDefinition = "varchar(10239) not null")
|
||||||
private String value;
|
private String value;
|
||||||
|
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package run.halo.app.model.enums;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Option source.
|
|
||||||
*
|
|
||||||
* @author johnniang
|
|
||||||
* @date 4/1/19
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public enum OptionSource implements ValueEnum<Integer> {
|
|
||||||
|
|
||||||
SYSTEM(0),
|
|
||||||
THEME(1);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
OptionSource(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getValue() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package run.halo.app.model.enums.converter;
|
|
||||||
|
|
||||||
import run.halo.app.model.enums.OptionSource;
|
|
||||||
|
|
||||||
import javax.persistence.Converter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OptionSource converter.
|
|
||||||
*
|
|
||||||
* @author johnniang
|
|
||||||
* @date 4/1/19
|
|
||||||
*/
|
|
||||||
@Converter(autoApply = true)
|
|
||||||
public class OptionSourceConverter extends AbstractConverter<OptionSource, Integer> {
|
|
||||||
|
|
||||||
public OptionSourceConverter() {
|
|
||||||
super(OptionSource.class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -11,6 +11,7 @@ import java.io.Serializable;
|
||||||
* @date : 2018/1/3
|
* @date : 2018/1/3
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@Deprecated
|
||||||
public class Theme implements Serializable {
|
public class Theme implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
@ -28,5 +29,5 @@ public class Theme implements Serializable {
|
||||||
/**
|
/**
|
||||||
* Theme properties
|
* Theme properties
|
||||||
*/
|
*/
|
||||||
private ThemeProperties properties;
|
private ThemeProperty properties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
package run.halo.app.model.support;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author : RYAN0UP
|
|
||||||
* @date : 2019-03-22
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class ThemeProperties {
|
|
||||||
|
|
||||||
private String id;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private String website;
|
|
||||||
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
private String logo;
|
|
||||||
|
|
||||||
private String version;
|
|
||||||
|
|
||||||
private String author;
|
|
||||||
|
|
||||||
private String authorWebsite;
|
|
||||||
}
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package run.halo.app.model.support;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : RYAN0UP
|
||||||
|
* @date : 2019-03-22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ThemeProperty {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme id.
|
||||||
|
*/
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme name.
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme website.
|
||||||
|
*/
|
||||||
|
private String website;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme description.
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme logo.
|
||||||
|
*/
|
||||||
|
private String logo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme version.
|
||||||
|
*/
|
||||||
|
private String version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme author.
|
||||||
|
*/
|
||||||
|
private String author;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme author website.
|
||||||
|
*/
|
||||||
|
private String authorWebsite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Folder name.
|
||||||
|
*/
|
||||||
|
private String folderName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has options.
|
||||||
|
*/
|
||||||
|
private Boolean hasOptions;
|
||||||
|
}
|
|
@ -2,9 +2,8 @@ package run.halo.app.service;
|
||||||
|
|
||||||
import org.springframework.lang.NonNull;
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
import run.halo.app.model.support.Theme;
|
|
||||||
import run.halo.app.model.support.ThemeFile;
|
import run.halo.app.model.support.ThemeFile;
|
||||||
import run.halo.app.model.support.ThemeProperties;
|
import run.halo.app.model.support.ThemeProperty;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
@ -21,7 +20,7 @@ public interface ThemeService {
|
||||||
*
|
*
|
||||||
* @return list of themes
|
* @return list of themes
|
||||||
*/
|
*/
|
||||||
List<Theme> getThemes();
|
List<ThemeProperty> getThemes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists theme folder by absolute path.
|
* Lists theme folder by absolute path.
|
||||||
|
@ -78,14 +77,6 @@ public interface ThemeService {
|
||||||
*/
|
*/
|
||||||
Path getBasePath();
|
Path getBasePath();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get theme Properties.
|
|
||||||
*
|
|
||||||
* @param path path
|
|
||||||
* @return ThemeProperties
|
|
||||||
*/
|
|
||||||
ThemeProperties getProperties(@NonNull File path);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get template content by template absolute path.
|
* Get template content by template absolute path.
|
||||||
*
|
*
|
||||||
|
@ -130,11 +121,17 @@ public interface ThemeService {
|
||||||
String render(@NonNull String pageName);
|
String render(@NonNull String pageName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets current theme name.
|
* Gets current theme id.
|
||||||
*
|
*
|
||||||
* @return current theme name
|
* @return current theme id
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
String getTheme();
|
String getActivatedTheme();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actives a theme.
|
||||||
|
*
|
||||||
|
* @param themeId theme id must not be blank
|
||||||
|
*/
|
||||||
|
void activeTheme(@NonNull String themeId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,27 +9,30 @@ import cn.hutool.setting.dialect.Props;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import run.halo.app.cache.StringCacheStore;
|
||||||
import run.halo.app.config.properties.HaloProperties;
|
import run.halo.app.config.properties.HaloProperties;
|
||||||
import run.halo.app.exception.NotFoundException;
|
import run.halo.app.exception.NotFoundException;
|
||||||
|
import run.halo.app.exception.ServiceException;
|
||||||
import run.halo.app.model.properties.PrimaryProperties;
|
import run.halo.app.model.properties.PrimaryProperties;
|
||||||
import run.halo.app.model.support.HaloConst;
|
import run.halo.app.model.support.HaloConst;
|
||||||
import run.halo.app.model.support.Theme;
|
|
||||||
import run.halo.app.model.support.ThemeFile;
|
import run.halo.app.model.support.ThemeFile;
|
||||||
import run.halo.app.model.support.ThemeProperties;
|
import run.halo.app.model.support.ThemeProperty;
|
||||||
import run.halo.app.service.OptionService;
|
import run.halo.app.service.OptionService;
|
||||||
import run.halo.app.service.ThemeService;
|
import run.halo.app.service.ThemeService;
|
||||||
import run.halo.app.utils.FilenameUtils;
|
import run.halo.app.utils.FilenameUtils;
|
||||||
|
import run.halo.app.utils.JsonUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Comparator;
|
import java.util.stream.Collectors;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static run.halo.app.model.support.HaloConst.DEFAULT_THEME_NAME;
|
import static run.halo.app.model.support.HaloConst.DEFAULT_THEME_NAME;
|
||||||
|
|
||||||
|
@ -42,39 +45,52 @@ import static run.halo.app.model.support.HaloConst.DEFAULT_THEME_NAME;
|
||||||
public class ThemeServiceImpl implements ThemeService {
|
public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of file that can be modified.
|
* Theme property file name.
|
||||||
*/
|
*/
|
||||||
private static String[] CAN_EDIT_SUFFIX = {"ftl", "css", "js"};
|
private final static String THEME_PROPERTY_FILE_NAME = "theme.properties";
|
||||||
|
|
||||||
/**
|
|
||||||
* These file names cannot be displayed.
|
|
||||||
*/
|
|
||||||
private static String[] FILTER_FILES = {".git", ".DS_Store", "theme.properties"};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Theme folder location.
|
|
||||||
*/
|
|
||||||
private final static String THEME_FOLDER = "templates/themes";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration file name.
|
* Configuration file name.
|
||||||
*/
|
*/
|
||||||
private final static String[] OPTIONS_NAMES = {"options.yaml", "options.yml"};
|
private final static String[] OPTIONS_NAMES = {"options.yaml", "options.yml"};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of file that can be modified.
|
||||||
|
*/
|
||||||
|
private static String[] CAN_EDIT_SUFFIX = {"ftl", "css", "js"};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These file names cannot be displayed.
|
||||||
|
*/
|
||||||
|
private static String[] FILTER_FILES = {".git", ".DS_Store", THEME_PROPERTY_FILE_NAME, "options.yaml", "option.yml"};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Theme folder location.
|
||||||
|
*/
|
||||||
|
private final static String THEME_FOLDER = "templates/themes";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render template.
|
* Render template.
|
||||||
*/
|
*/
|
||||||
private final static String RENDER_TEMPLATE = "themes/%s/%s";
|
private final static String RENDER_TEMPLATE = "themes/%s/%s";
|
||||||
|
|
||||||
|
private final static String THEMES_CACHE_KEY = "themes";
|
||||||
|
|
||||||
private final Path workDir;
|
private final Path workDir;
|
||||||
|
|
||||||
private final ObjectMapper yamlMapper;
|
private final ObjectMapper yamlMapper;
|
||||||
|
|
||||||
private final OptionService optionService;
|
private final OptionService optionService;
|
||||||
|
|
||||||
|
private final StringCacheStore cacheStore;
|
||||||
|
|
||||||
public ThemeServiceImpl(HaloProperties haloProperties,
|
public ThemeServiceImpl(HaloProperties haloProperties,
|
||||||
OptionService optionService) {
|
OptionService optionService,
|
||||||
|
StringCacheStore cacheStore) {
|
||||||
this.optionService = optionService;
|
this.optionService = optionService;
|
||||||
|
this.cacheStore = cacheStore;
|
||||||
yamlMapper = new ObjectMapper(new YAMLFactory());
|
yamlMapper = new ObjectMapper(new YAMLFactory());
|
||||||
workDir = Paths.get(haloProperties.getWorkDir(), THEME_FOLDER);
|
workDir = Paths.get(haloProperties.getWorkDir(), THEME_FOLDER);
|
||||||
}
|
}
|
||||||
|
@ -85,36 +101,37 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
* @return list of themes
|
* @return list of themes
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Theme> getThemes() {
|
public List<ThemeProperty> getThemes() {
|
||||||
final List<Theme> themes = new ArrayList<>();
|
// Fetch themes from cache
|
||||||
final File[] files = getThemeBasePath().listFiles();
|
return cacheStore.get(THEMES_CACHE_KEY).map(themesCache -> {
|
||||||
try {
|
try {
|
||||||
if (null != files) {
|
@SuppressWarnings("unchecked")
|
||||||
Theme theme;
|
List<ThemeProperty> themes = JsonUtils.jsonToObject(themesCache, LinkedList.class);
|
||||||
for (File file : files) {
|
return themes;
|
||||||
if (!file.isDirectory()) {
|
} catch (IOException e) {
|
||||||
continue;
|
throw new ServiceException("Failed to parse json", e);
|
||||||
}
|
|
||||||
theme = new Theme();
|
|
||||||
theme.setKey(file.getName());
|
|
||||||
theme.setHasOptions(false);
|
|
||||||
for (String optionsName : OPTIONS_NAMES) {
|
|
||||||
// Resolve the options path
|
|
||||||
Path optionsPath = workDir.resolve(file.getName()).resolve(optionsName);
|
|
||||||
|
|
||||||
if (!Files.exists(optionsPath)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
theme.setHasOptions(true);
|
|
||||||
}
|
|
||||||
theme.setProperties(getProperties(new File(getThemeBasePath(), file.getName())));
|
|
||||||
themes.add(theme);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
}).orElseGet(() -> {
|
||||||
throw new RuntimeException("Themes scan failed", e);
|
try {
|
||||||
}
|
|
||||||
return themes;
|
// List and filter sub folders
|
||||||
|
List<Path> themePaths = Files.list(getBasePath()).filter(path -> Files.isDirectory(path)).collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(themePaths)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get theme properties
|
||||||
|
List<ThemeProperty> themes = themePaths.stream().map(this::getProperty).collect(Collectors.toList());
|
||||||
|
|
||||||
|
// Cache the themes
|
||||||
|
cacheStore.put(THEMES_CACHE_KEY, JsonUtils.objectToJson(themes));
|
||||||
|
|
||||||
|
return themes;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new ServiceException("Themes scan failed", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,7 +225,7 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean isTemplateExist(String template) {
|
public boolean isTemplateExist(String template) {
|
||||||
StrBuilder templatePath = new StrBuilder(getTheme());
|
StrBuilder templatePath = new StrBuilder(getActivatedTheme());
|
||||||
templatePath.append("/");
|
templatePath.append("/");
|
||||||
templatePath.append(template);
|
templatePath.append(template);
|
||||||
File file = new File(getThemeBasePath(), templatePath.toString());
|
File file = new File(getThemeBasePath(), templatePath.toString());
|
||||||
|
@ -242,30 +259,6 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
return workDir;
|
return workDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get theme Properties.
|
|
||||||
*
|
|
||||||
* @param path path
|
|
||||||
* @return ThemeProperties
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public ThemeProperties getProperties(File path) {
|
|
||||||
File propertiesFile = new File(path, "theme.properties");
|
|
||||||
ThemeProperties properties = new ThemeProperties();
|
|
||||||
if (propertiesFile.exists()) {
|
|
||||||
Props props = new Props(propertiesFile);
|
|
||||||
properties.setId(props.getStr("theme.id"));
|
|
||||||
properties.setName(props.getStr("theme.name"));
|
|
||||||
properties.setWebsite(props.getStr("theme.website"));
|
|
||||||
properties.setDescription(props.getStr("theme.description"));
|
|
||||||
properties.setLogo(props.getStr("theme.logo"));
|
|
||||||
properties.setVersion(props.getStr("theme.version"));
|
|
||||||
properties.setAuthor(props.getStr("theme.author"));
|
|
||||||
properties.setAuthorWebsite(props.getStr("theme.author.website"));
|
|
||||||
}
|
|
||||||
return properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get template content by template absolute path.
|
* Get template content by template absolute path.
|
||||||
*
|
*
|
||||||
|
@ -297,12 +290,13 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void deleteTheme(String key) {
|
public void deleteTheme(String key) {
|
||||||
if (!this.isThemeExist(key)) {
|
if (!isThemeExist(key)) {
|
||||||
throw new NotFoundException("该主题不存在!").setErrorData(key);
|
throw new NotFoundException("该主题不存在!").setErrorData(key);
|
||||||
}
|
}
|
||||||
File file = new File(this.getThemeBasePath(), key);
|
File file = new File(this.getThemeBasePath(), key);
|
||||||
FileUtil.del(file);
|
FileUtil.del(file);
|
||||||
HaloConst.THEMES = this.getThemes();
|
|
||||||
|
cacheStore.delete(THEMES_CACHE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -334,12 +328,99 @@ public class ThemeServiceImpl implements ThemeService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String render(String pageName) {
|
public String render(String pageName) {
|
||||||
return String.format(RENDER_TEMPLATE, getTheme(), pageName);
|
return String.format(RENDER_TEMPLATE, getActivatedTheme(), pageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTheme() {
|
public String getActivatedTheme() {
|
||||||
return optionService.getByProperty(PrimaryProperties.THEME).orElse(DEFAULT_THEME_NAME);
|
return optionService.getByProperty(PrimaryProperties.THEME).orElse(DEFAULT_THEME_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void activeTheme(String themeId) {
|
||||||
|
// TODO Check existence of the theme
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets theme property.
|
||||||
|
*
|
||||||
|
* @param themePath must not be null
|
||||||
|
* @return theme property
|
||||||
|
*/
|
||||||
|
private ThemeProperty getProperty(@NonNull Path themePath) {
|
||||||
|
Assert.notNull(themePath, "Theme path must not be null");
|
||||||
|
|
||||||
|
Path propertyPath = themePath.resolve(THEME_PROPERTY_FILE_NAME);
|
||||||
|
if (!Files.exists(propertyPath)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
File propertyFile = propertyPath.toFile();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(new java.io.FileReader(propertyFile));
|
||||||
|
|
||||||
|
ThemeProperty themeProperty = new ThemeProperty();
|
||||||
|
themeProperty.setId(properties.getProperty("theme.id"));
|
||||||
|
themeProperty.setName(properties.getProperty("theme.name"));
|
||||||
|
themeProperty.setWebsite(properties.getProperty("theme.website"));
|
||||||
|
themeProperty.setDescription(properties.getProperty("theme.description"));
|
||||||
|
themeProperty.setLogo(properties.getProperty("theme.logo"));
|
||||||
|
themeProperty.setVersion(properties.getProperty("theme.version"));
|
||||||
|
themeProperty.setAuthor(properties.getProperty("theme.author"));
|
||||||
|
themeProperty.setAuthorWebsite(properties.getProperty("theme.author.website"));
|
||||||
|
themeProperty.setFolderName(propertyFile.getName());
|
||||||
|
themeProperty.setHasOptions(hasOptions(propertyPath));
|
||||||
|
|
||||||
|
return themeProperty;
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Consider Ignore this error, then return null
|
||||||
|
throw new ServiceException("Failed to load: " + themePath.toString(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets theme Properties.
|
||||||
|
*
|
||||||
|
* @param path path
|
||||||
|
* @return ThemeProperty
|
||||||
|
*/
|
||||||
|
private ThemeProperty getProperties(File path) {
|
||||||
|
File propertiesFile = new File(path, "theme.properties");
|
||||||
|
ThemeProperty properties = new ThemeProperty();
|
||||||
|
if (propertiesFile.exists()) {
|
||||||
|
Props props = new Props(propertiesFile);
|
||||||
|
properties.setId(props.getStr("theme.id"));
|
||||||
|
properties.setName(props.getStr("theme.name"));
|
||||||
|
properties.setWebsite(props.getStr("theme.website"));
|
||||||
|
properties.setDescription(props.getStr("theme.description"));
|
||||||
|
properties.setLogo(props.getStr("theme.logo"));
|
||||||
|
properties.setVersion(props.getStr("theme.version"));
|
||||||
|
properties.setAuthor(props.getStr("theme.author"));
|
||||||
|
properties.setAuthorWebsite(props.getStr("theme.author.website"));
|
||||||
|
properties.setFolderName(path.getName());
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check existence of the options.
|
||||||
|
*
|
||||||
|
* @param themePath theme path must not be null
|
||||||
|
* @return true if it has options; false otherwise
|
||||||
|
*/
|
||||||
|
private boolean hasOptions(@NonNull Path themePath) {
|
||||||
|
Assert.notNull(themePath, "Path must not be null");
|
||||||
|
|
||||||
|
for (String optionsName : OPTIONS_NAMES) {
|
||||||
|
// Resolve the options path
|
||||||
|
Path optionsPath = themePath.resolve(optionsName);
|
||||||
|
|
||||||
|
if (Files.exists(optionsPath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,5 +22,4 @@ public class ThemeSettingServiceImpl extends AbstractCrudService<ThemeSetting, I
|
||||||
this.themeSettingRepository = themeSettingRepository;
|
this.themeSettingRepository = themeSettingRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
package run.halo.app.web.controller.admin.api;
|
package run.halo.app.web.controller.admin.api;
|
||||||
|
|
||||||
import run.halo.app.model.dto.OptionOutputDTO;
|
import run.halo.app.model.dto.OptionOutputDTO;
|
||||||
import run.halo.app.model.enums.OptionSource;
|
|
||||||
import run.halo.app.model.params.OptionParam;
|
import run.halo.app.model.params.OptionParam;
|
||||||
import run.halo.app.service.OptionService;
|
import run.halo.app.service.OptionService;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import run.halo.app.model.dto.OptionOutputDTO;
|
|
||||||
import run.halo.app.model.enums.OptionSource;
|
|
||||||
import run.halo.app.model.params.OptionParam;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
|
@ -6,8 +6,8 @@ import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import run.halo.app.model.properties.PrimaryProperties;
|
import run.halo.app.model.properties.PrimaryProperties;
|
||||||
import run.halo.app.model.support.BaseResponse;
|
import run.halo.app.model.support.BaseResponse;
|
||||||
import run.halo.app.model.support.Theme;
|
|
||||||
import run.halo.app.model.support.ThemeFile;
|
import run.halo.app.model.support.ThemeFile;
|
||||||
|
import run.halo.app.model.support.ThemeProperty;
|
||||||
import run.halo.app.service.OptionService;
|
import run.halo.app.service.OptionService;
|
||||||
import run.halo.app.service.ThemeService;
|
import run.halo.app.service.ThemeService;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ public class ThemeController {
|
||||||
*/
|
*/
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@ApiOperation("List all themes")
|
@ApiOperation("List all themes")
|
||||||
public List<Theme> listAll() {
|
public List<ThemeProperty> listAll() {
|
||||||
return themeService.getThemes();
|
return themeService.getThemes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public class ThemeController {
|
||||||
*/
|
*/
|
||||||
@GetMapping("files")
|
@GetMapping("files")
|
||||||
public List<ThemeFile> listFiles() {
|
public List<ThemeFile> listFiles() {
|
||||||
return themeService.listThemeFolderBy(themeService.getTheme());
|
return themeService.listThemeFolderBy(themeService.getActivatedTheme());
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("files/content")
|
@GetMapping("files/content")
|
||||||
|
@ -71,19 +71,21 @@ public class ThemeController {
|
||||||
|
|
||||||
@GetMapping("files/custom")
|
@GetMapping("files/custom")
|
||||||
public List<String> customTemplate() {
|
public List<String> customTemplate() {
|
||||||
return themeService.getCustomTpl(themeService.getTheme());
|
return themeService.getCustomTpl(themeService.getActivatedTheme());
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("active")
|
@PostMapping("{themeId}/activate")
|
||||||
@ApiOperation("Active a theme")
|
@ApiOperation("Active a theme")
|
||||||
public void active(String theme) throws TemplateModelException {
|
public void active(@RequestParam("themeId") String themeId) throws TemplateModelException {
|
||||||
|
themeService.activeTheme(themeId);
|
||||||
|
|
||||||
// TODO Check existence of the theme
|
// TODO Check existence of the theme
|
||||||
optionService.saveProperty(PrimaryProperties.THEME, theme);
|
optionService.saveProperty(PrimaryProperties.THEME, themeId);
|
||||||
configuration.setSharedVariable("themeName", theme);
|
configuration.setSharedVariable("themeName", themeId);
|
||||||
configuration.setSharedVariable("options", optionService.listOptions());
|
configuration.setSharedVariable("options", optionService.listOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("{key}")
|
@DeleteMapping("key/{key}")
|
||||||
@ApiOperation("Deletes a theme")
|
@ApiOperation("Deletes a theme")
|
||||||
public void deleteBy(@PathVariable("key") String key) {
|
public void deleteBy(@PathVariable("key") String key) {
|
||||||
themeService.deleteTheme(key);
|
themeService.deleteTheme(key);
|
||||||
|
@ -92,6 +94,6 @@ public class ThemeController {
|
||||||
@GetMapping("configurations")
|
@GetMapping("configurations")
|
||||||
@ApiOperation("Fetches theme configuration")
|
@ApiOperation("Fetches theme configuration")
|
||||||
public BaseResponse<Object> fetchConfig() {
|
public BaseResponse<Object> fetchConfig() {
|
||||||
return BaseResponse.ok(themeService.fetchConfig(themeService.getTheme()));
|
return BaseResponse.ok(themeService.fetchConfig(themeService.getActivatedTheme()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ public class CommonController implements ErrorController {
|
||||||
return "common/error/404";
|
return "common/error/404";
|
||||||
}
|
}
|
||||||
StrBuilder path = new StrBuilder("themes/");
|
StrBuilder path = new StrBuilder("themes/");
|
||||||
path.append(themeService.getTheme());
|
path.append(themeService.getActivatedTheme());
|
||||||
path.append("/404");
|
path.append("/404");
|
||||||
return path.toString();
|
return path.toString();
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ public class CommonController implements ErrorController {
|
||||||
return "common/error/500";
|
return "common/error/500";
|
||||||
}
|
}
|
||||||
StrBuilder path = new StrBuilder("themes/");
|
StrBuilder path = new StrBuilder("themes/");
|
||||||
path.append(themeService.getTheme());
|
path.append(themeService.getActivatedTheme());
|
||||||
path.append("/500");
|
path.append("/500");
|
||||||
return path.toString();
|
return path.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import run.halo.app.exception.BadRequestException;
|
import run.halo.app.exception.BadRequestException;
|
||||||
import run.halo.app.model.entity.*;
|
import run.halo.app.model.entity.*;
|
||||||
import run.halo.app.model.enums.AttachmentType;
|
import run.halo.app.model.enums.AttachmentType;
|
||||||
import run.halo.app.model.enums.OptionSource;
|
|
||||||
import run.halo.app.model.params.InstallParam;
|
import run.halo.app.model.params.InstallParam;
|
||||||
import run.halo.app.model.properties.*;
|
import run.halo.app.model.properties.*;
|
||||||
import run.halo.app.model.support.BaseResponse;
|
import run.halo.app.model.support.BaseResponse;
|
||||||
|
|
Loading…
Reference in New Issue