Commit 05026a22 authored by Liang Ding's avatar Liang Ding

Merge branch '3.3.0-dev'

parents 9a83a8fd 01b99fec
......@@ -5,7 +5,7 @@
<meta name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1" media="(device-height: 568px)">
<title>Solo Change Logs</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="apple-touch-icon" href="/favicon.png">
<link rel="apple-touch-icon" href="https://static.b3log.org/images/brand/solo-32.png">
<style>
a {
color: #4285f4;
......
......@@ -22,11 +22,16 @@ package org.b3log.solo.model;
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="https://hacpai.com/member/e">Dongxu Wang</a>
* @version 1.7.0.3, Feb 27, 2019
* @version 1.7.0.4, Mar 17, 2019
* @since 0.3.1
*/
public final class Common {
/**
* Key of favicon URL.
*/
public static final String FAVICON_URL = "faviconURL";
/**
* Key of URL.
*/
......
......@@ -26,7 +26,7 @@ import org.json.JSONObject;
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="https://github.com/hzchendou">hzchendou</a>
* @version 1.5.0.4, Mar 3, 2019
* @version 1.5.0.5, Mar 17, 2019
* @since 0.6.0
*/
public final class Option {
......@@ -52,6 +52,11 @@ public final class Option {
public static final String OPTION_CATEGORY = "optionCategory";
// oId constants
/**
* Key of favicon URL.
*/
public static final String ID_C_FAVICON_URL = "faviconURL";
/**
* Key of custom vars.
*/
......@@ -269,11 +274,16 @@ public final class Option {
* Default preference.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 2.2.0.1, Feb 17, 2019
* @version 2.2.0.2, Mar 17, 2019
* @since 0.3.1
*/
public static final class DefaultPreference {
/**
* Default favicon URL.
*/
public static final String DEFAULT_FAVICON_URL = "https://static.b3log.org/images/brand/solo-32.png";
/**
* Default custom vars.
*/
......
......@@ -224,6 +224,7 @@ public class ArticleProcessor {
Keys.fillRuntime(dataModel);
dataModelService.fillMinified(dataModel);
dataModelService.fillFaviconURL(dataModel, preference);
}
/**
......@@ -623,6 +624,7 @@ public class ArticleProcessor {
prepareShowAuthorArticles(pageNums, dataModel, pageCount, currentPageNum, articles, author);
final HttpServletResponse response = context.getResponse();
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
Skins.fillLangs(preference.optString(Option.ID_C_LOCALE_STRING), (String) context.attr(Keys.TEMAPLTE_DIR_NAME), dataModel);
statisticMgmtService.incBlogViewCount(context, response);
......@@ -678,6 +680,7 @@ public class ArticleProcessor {
prepareShowArchiveArticles(preference, dataModel, articles, currentPageNum, pageCount, archiveDateString, archiveDate);
final HttpServletResponse response = context.getResponse();
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
statisticMgmtService.incBlogViewCount(context, response);
} catch (final Exception e) {
......@@ -751,6 +754,7 @@ public class ArticleProcessor {
final HttpServletResponse response = context.getResponse();
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
Skins.fillLangs(preference.optString(Option.ID_C_LOCALE_STRING), (String) context.attr(Keys.TEMAPLTE_DIR_NAME), dataModel);
if (!StatisticMgmtService.hasBeenServed(context, response)) {
......
......@@ -151,6 +151,7 @@ public class CategoryProcessor {
dataModel.put(Common.PATH, "/category/" + URLs.encode(categoryURI));
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
statisticMgmtService.incBlogViewCount(context, response);
} catch (final ServiceException | JSONException e) {
......
......@@ -101,6 +101,7 @@ public class ErrorProcessor {
dataModel.putAll(langs);
final JSONObject preference = optionQueryService.getPreference();
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
final String msg = (String) context.attr(Keys.MSG);
dataModel.put(Keys.MSG, msg);
dataModel.put(Common.LOGIN_URL, userQueryService.getLoginURL(Common.ADMIN_INDEX_URI));
......
......@@ -129,6 +129,7 @@ public class IndexProcessor {
dataModelService.fillIndexArticles(context, dataModel, currentPageNum, preference);
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
dataModel.put(Pagination.PAGINATION_CURRENT_PAGE_NUM, currentPageNum);
final int previousPageNum = currentPageNum > 1 ? currentPageNum - 1 : 0;
......@@ -176,7 +177,7 @@ public class IndexProcessor {
dataModel.put(Common.REFERER, referer);
Keys.fillRuntime(dataModel);
dataModelService.fillMinified(dataModel);
dataModelService.fillFaviconURL(dataModel, optionQueryService.getPreference());
Solos.addGoogleNoIndex(context);
}
......@@ -210,6 +211,7 @@ public class IndexProcessor {
dataModel.putAll(langs);
final JSONObject preference = optionQueryService.getPreference();
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
Keys.fillServer(dataModel);
Keys.fillRuntime(dataModel);
dataModelService.fillMinified(dataModel);
......
......@@ -136,6 +136,7 @@ public class PageProcessor {
Stopwatchs.end();
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
statisticMgmtService.incBlogViewCount(context, response);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
......
......@@ -148,6 +148,7 @@ public class SearchProcessor {
final JSONObject preference = optionQueryService.getPreference();
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
dataModelService.setArticlesExProperties(context, articles, preference);
dataModel.put(Article.ARTICLES, articles);
......
......@@ -148,6 +148,7 @@ public class TagProcessor {
dataModel.put(Keys.OBJECT_ID, tagId);
dataModel.put(Tag.TAG, tag);
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
statisticMgmtService.incBlogViewCount(context, response);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
......
......@@ -111,6 +111,7 @@ public class UserTemplateProcessor {
dataModel.putAll(langs);
final JSONObject preference = optionQueryService.getPreference();
dataModelService.fillCommon(context, dataModel, preference);
dataModelService.fillFaviconURL(dataModel, preference);
dataModelService.fillUserTemplate(context, template, dataModel, preference);
Skins.fillLangs(preference.optString(Option.ID_C_LOCALE_STRING), (String) context.attr(Keys.TEMAPLTE_DIR_NAME), dataModel);
statisticMgmtService.incBlogViewCount(context, response);
......
......@@ -41,7 +41,10 @@ import org.b3log.latke.servlet.renderer.AbstractFreeMarkerRenderer;
import org.b3log.latke.util.Execs;
import org.b3log.latke.util.Strings;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.*;
import org.b3log.solo.model.Common;
import org.b3log.solo.model.Option;
import org.b3log.solo.model.Skin;
import org.b3log.solo.model.UserExt;
import org.b3log.solo.service.DataModelService;
import org.b3log.solo.service.ExportService;
import org.b3log.solo.service.OptionQueryService;
......@@ -142,7 +145,6 @@ public class AdminConsole {
dataModel.put(Common.YEAR, String.valueOf(Calendar.getInstance().get(Calendar.YEAR)));
dataModel.put(Option.ID_C_ARTICLE_LIST_DISPLAY_COUNT, preference.getInt(Option.ID_C_ARTICLE_LIST_DISPLAY_COUNT));
dataModel.put(Option.ID_C_ARTICLE_LIST_PAGINATION_WINDOW_SIZE, preference.getInt(Option.ID_C_ARTICLE_LIST_PAGINATION_WINDOW_SIZE));
dataModel.put(Option.ID_C_LOCALE_STRING, preference.getString(Option.ID_C_LOCALE_STRING));
dataModel.put(Skin.SKIN_DIR_NAME, preference.getString(Skin.SKIN_DIR_NAME));
Keys.fillRuntime(dataModel);
dataModelService.fillMinified(dataModel);
......@@ -158,6 +160,7 @@ public class AdminConsole {
dataModel.put(Common.UPLOAD_URL, upload.optString(Common.UPLOAD_URL));
dataModel.put(Common.UPLOAD_MSG, upload.optString(Common.UPLOAD_MSG));
}
dataModelService.fillFaviconURL(dataModel, preference);
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Admin index render failed", e);
}
......
......@@ -44,7 +44,7 @@ import javax.servlet.http.HttpServletResponse;
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="https://github.com/hzchendou">hzchendou</a>
* @version 1.2.0.21, Feb 8, 2019
* @version 1.2.0.22, Mar 17, 2019
* @since 0.4.0
*/
@RequestProcessor
......@@ -167,6 +167,7 @@ public class PreferenceConsole {
* "commentable": boolean,
* "feedOutputMode: "" // Optional values: "abstract"/"full"
* "feedOutputCnt": int,
* "faviconURL": "",
* "customVars" "", // 支持配置自定义参数 https://github.com/b3log/solo/issues/12535
* }
* }
......@@ -244,6 +245,7 @@ public class PreferenceConsole {
* "commentable": boolean,
* "feedOutputMode: "",
* "feedOutputCnt": int,
* "faviconURL": "",
* "customVars" "", // 支持配置自定义参数 https://github.com/b3log/solo/issues/12535
* }
* }
......
......@@ -59,7 +59,7 @@ import static org.b3log.solo.model.Article.ARTICLE_CONTENT;
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @version 1.7.0.5, Feb 27, 2019
* @version 1.7.0.6, Mar 17, 2019
* @since 0.3.1
*/
@Service
......@@ -537,6 +537,20 @@ public class DataModelService {
}
}
/**
* Fills favicon URL. 可配置 favicon 图标路径 https://github.com/b3log/solo/issues/12706
*
* @param dataModel the specified data model
* @param preference the specified preference
*/
public void fillFaviconURL(final Map<String, Object> dataModel, final JSONObject preference) {
if (null == preference) {
dataModel.put(Common.FAVICON_URL, Option.DefaultPreference.DEFAULT_FAVICON_URL);
} else {
dataModel.put(Common.FAVICON_URL, preference.optString(Option.ID_C_FAVICON_URL));
}
}
/**
* Fills common parts (header, side and footer).
*
......@@ -545,8 +559,7 @@ public class DataModelService {
* @param preference the specified preference
* @throws ServiceException service exception
*/
public void fillCommon(final RequestContext context, final Map<String, Object> dataModel, final JSONObject preference)
throws ServiceException {
public void fillCommon(final RequestContext context, final Map<String, Object> dataModel, final JSONObject preference) throws ServiceException {
fillSide(context, dataModel, preference);
fillBlogHeader(context, dataModel, preference);
fillBlogFooter(context, dataModel, preference);
......
......@@ -475,6 +475,12 @@ public class InitService {
private void initPreference(final JSONObject requestJSONObject) throws Exception {
LOGGER.debug("Initializing preference....");
final JSONObject faviconURLOpt = new JSONObject();
faviconURLOpt.put(Keys.OBJECT_ID, Option.ID_C_FAVICON_URL);
faviconURLOpt.put(Option.OPTION_CATEGORY, Option.CATEGORY_C_PREFERENCE);
faviconURLOpt.put(Option.OPTION_VALUE, DefaultPreference.DEFAULT_FAVICON_URL);
optionRepository.add(faviconURLOpt);
final JSONObject customVarsOpt = new JSONObject();
customVarsOpt.put(Keys.OBJECT_ID, Option.ID_C_CUSTOM_VARS);
customVarsOpt.put(Option.OPTION_CATEGORY, Option.CATEGORY_C_PREFERENCE);
......
......@@ -307,6 +307,10 @@ public class PreferenceMgmtService {
versionOpt.put(Option.OPTION_VALUE, preference.optString(Option.ID_C_VERSION));
optionRepository.update(Option.ID_C_VERSION, versionOpt);
final JSONObject faviconURLOpt = optionRepository.get(Option.ID_C_FAVICON_URL);
faviconURLOpt.put(Option.OPTION_VALUE, preference.optString(Option.ID_C_FAVICON_URL));
optionRepository.update(Option.ID_C_FAVICON_URL, faviconURLOpt);
final JSONObject customVarsOpt = optionRepository.get(Option.ID_C_CUSTOM_VARS);
customVarsOpt.put(Option.OPTION_VALUE, preference.optString(Option.ID_C_CUSTOM_VARS));
optionRepository.update(Option.ID_C_CUSTOM_VARS, customVarsOpt);
......
......@@ -5,7 +5,7 @@
<meta name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1" media="(device-height: 568px)">
<title>Solo Change Logs</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="apple-touch-icon" href="/favicon.png">
<link rel="apple-touch-icon" href="https://static.b3log.org/images/brand/solo-32.png">
<style>
a {
color: #4285f4;
......
......@@ -20,15 +20,13 @@
-->
<!--
Description: Static resources definition.
Version: 2.8.0.60, Jan 13, 2019
Version: 2.8.0.61, Mar 17, 2019
Author: Liang Ding
Author: Liyuan Li
-->
<static-files>
<!-- Uses the STANDARD Ant Path Pattern to configure these paths! -->
<include path="/favicon.ico"/>
<include path="/favicon.png"/>
<include path="/robots.txt"/>
<include path="/sw.js"/>
<include path="/manifest.json"/>
......
......@@ -31,7 +31,7 @@
<title>${adminConsoleLabel} - ${blogTitle}</title>
<link type="text/css" rel="stylesheet" href="${staticServePath}/scss/admin.css?${staticResourceVersion}" />
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@9.15.6/styles/atom-one-light.min.css" />
<link rel="icon" type="image/png" href="${staticServePath}/favicon.png" />
<link rel="icon" type="image/png" href="${faviconURL}" />
<link rel="manifest" href="${servePath}/manifest.json">
</head>
<body onhashchange="admin.setCurByHash();">
......
......@@ -125,6 +125,8 @@
</select>
<label for="feedOutputCnt">${feedOutputCnt1Label}</label>
<input id="feedOutputCnt" class="normalInput" type="text"/>
<label for="faviconURL">Favicon</label>
<input id="faviconURL" class="normalInput" type="text"/>
<label for="customVars">${customVars1Label}</label>
<input id="customVars" class="normalInput" type="text"/><br/><br/>
<button class="fn__right" onclick="admin.preference.update()">${updateLabel}</button>
......
......@@ -20,7 +20,7 @@
*
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.3.0.0, Feb 28, 2019
* @version 1.3.0.1, Mar 17, 2019
*/
/* preference 相关操作 */
......@@ -122,6 +122,7 @@ admin.preference = {
$('#articleListDisplay').val(preference.articleListStyle)
$('#feedOutputMode').val(preference.feedOutputMode)
$('#feedOutputCnt').val(preference.feedOutputCnt)
$('#faviconURL').val(preference.faviconURL)
$('#loadMsg').text('')
},
......@@ -254,6 +255,7 @@ admin.preference = {
'articleListStyle': $('#articleListDisplay').val(),
'feedOutputMode': $('#feedOutputMode').val(),
'feedOutputCnt': $('#feedOutputCnt').val(),
'faviconURL': $('#faviconURL').val(),
'commentable': $('#commentable').prop('checked'),
'customVars': $('#customVars').val(),
},
......
......@@ -28,8 +28,8 @@
<title>${title}<#if blogTitle??> - ${blogTitle}</#if></title>
<link type="text/css" rel="stylesheet"
href="${staticServePath}/scss/start.css?${staticResourceVersion}" charset="utf-8"/>
<link rel="icon" type="image/png" href="${staticServePath}/favicon.png"/>
<link rel="apple-touch-icon" href="${staticServePath}/favicon.png">
<link rel="icon" type="image/png" href="${faviconURL}"/>
<link rel="apple-touch-icon" href="${faviconURL}">
</head>
<body>
<div class="wrap">
......
......@@ -26,12 +26,12 @@
<title>${searchLabel} - ${blogTitle}${searchLabel}</title>
<link type="text/css" rel="stylesheet"
href="${staticServePath}/scss/start.css?${staticResourceVersion}" charset="utf-8"/>
<link rel="icon" type="image/png" href="${staticServePath}/favicon.png"/>
<link rel="apple-touch-icon" href="${staticServePath}/favicon.png">
<link rel="icon" type="image/png" href="${faviconURL}"/>
<link rel="apple-touch-icon" href="${faviconURL}">
</head>
<body class="search__body">
<div class="search__header fn-clear">
<a href="${servePath}"><img width="44" border="0" alt="Solo" title="Solo" src="${staticServePath}/favicon.png"/></a>
<a href="${servePath}"><img width="32" border="0" alt="Solo" title="Solo" src="${faviconURL}"/></a>
<div class="search__input">
<input value="${keyword}" id="keyword" type="text" onkeypress="if(event.keyCode===13){document.getElementById('searchBtn').click()}">
<button id="searchBtn" onclick="window.location.href='${servePath}/search?keyword=' + document.getElementById('keyword').value">搜索</button>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment