hexo-theme-stellar 1.39.0 → 1.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/_config.yml +3 -1
- package/layout/_partial/cover/post_cover.ejs +1 -1
- package/layout/_partial/main/article/article_footer.ejs +13 -10
- package/layout/_partial/main/navbar/nav_tabs_blog.ejs +6 -3
- package/layout/_partial/main/navbar/nav_tabs_wiki.ejs +1 -1
- package/layout/_partial/main/pin_slider.ejs +11 -12
- package/layout/_partial/main/post_list/post_card.ejs +13 -13
- package/layout/_partial/sidebar/index_leftbar.ejs +2 -2
- package/layout/index.ejs +67 -11
- package/package.json +1 -1
- package/scripts/helpers/escape_html.js +9 -0
- package/scripts/helpers/related_posts.js +9 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.39.1
|
|
4
|
+
|
|
5
|
+
> 发布日期:2026-08-13
|
|
6
|
+
|
|
7
|
+
### 新功能
|
|
8
|
+
- 置顶文章新增平铺样式配置 `article.pin_style: flat`:首页第一页不再渲染置顶轮播,置顶文章按与轮播一致的排序权重在文章列表靠前平铺展示
|
|
9
|
+
|
|
10
|
+
### 修复
|
|
11
|
+
- 用户内容统一 HTML 转义并移除圆点 aria-label,修复标题含引号导致构建失败
|
|
12
|
+
|
|
13
|
+
### 升级注意(配置变更与破坏性改动)
|
|
14
|
+
- 新增 `article.pin_style`(`carousel` / `flat`,默认 `carousel`):默认行为不变;设置 `flat` 后首页置顶文章改为平铺样式展示
|
|
15
|
+
|
|
16
|
+
Full Changelog: [1.39.0...1.39.1](https://github.com/xaoxuu/hexo-theme-stellar/compare/1.39.0...1.39.1)
|
|
17
|
+
|
|
3
18
|
## 1.39.0
|
|
4
19
|
|
|
5
20
|
> 发布日期:2026-08-13
|
package/_config.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
######## Stellar info ########
|
|
2
2
|
stellar:
|
|
3
|
-
version: '1.39.
|
|
3
|
+
version: '1.39.1'
|
|
4
4
|
homepage: 'https://xaoxuu.com/wiki/stellar/'
|
|
5
5
|
repo: 'https://github.com/xaoxuu/hexo-theme-stellar'
|
|
6
6
|
main_css: /css/main.css
|
|
@@ -180,6 +180,8 @@ notebook:
|
|
|
180
180
|
|
|
181
181
|
######## Article ########
|
|
182
182
|
article:
|
|
183
|
+
# 置顶文章样式:carousel = 轮播(默认), flat = 平铺(不渲染轮播,置顶文章在首页文章列表靠前展示,排序规则与轮播一致)
|
|
184
|
+
pin_style: carousel
|
|
183
185
|
# 文章类型,决定布局风格,可以在 front-matter/topic/wiki 中覆盖此参数
|
|
184
186
|
type: tech # tech: 默认技术类文章, story: 图文类文章,文字和段落间增距大
|
|
185
187
|
# 缩进两个文字宽度,适合文字类博客,可以在 front-matter/topic/wiki 中覆盖此参数
|
|
@@ -28,7 +28,7 @@ function div() {
|
|
|
28
28
|
}
|
|
29
29
|
el += '<div class="l_cover post' + scrollreveal(' ') + '">';
|
|
30
30
|
el += '<div class="cover">';
|
|
31
|
-
el += '<div class="lazy img bg" data-bg="' + url + '"></div>';
|
|
31
|
+
el += '<div class="lazy img bg" data-bg="' + escape_html(url) + '"></div>';
|
|
32
32
|
el += '</div>';
|
|
33
33
|
el += '</div>';
|
|
34
34
|
return el;
|
|
@@ -98,6 +98,9 @@ function layoutDiv() {
|
|
|
98
98
|
showSharePlugin = true
|
|
99
99
|
}
|
|
100
100
|
if (theme.article.share && showSharePlugin) {
|
|
101
|
+
function urlenc(v) {
|
|
102
|
+
return encodeURIComponent(v == null ? '' : String(v))
|
|
103
|
+
}
|
|
101
104
|
function socialButtons() {
|
|
102
105
|
var el = ''
|
|
103
106
|
theme.article.share.forEach((item, i) => {
|
|
@@ -109,20 +112,20 @@ function layoutDiv() {
|
|
|
109
112
|
if (item == 'wechat') {
|
|
110
113
|
el += ' onclick="util.toggle("qrcode-wechat")"';
|
|
111
114
|
} else if (item == 'weibo') {
|
|
112
|
-
el += ' href="https://service.weibo.com/share/share.php?url=' + page.permalink;
|
|
113
|
-
el += '&title=' + page.title + ' - ' + config.title;
|
|
115
|
+
el += ' href="https://service.weibo.com/share/share.php?url=' + urlenc(page.permalink);
|
|
116
|
+
el += '&title=' + urlenc(page.title + ' - ' + config.title);
|
|
114
117
|
if (page.layout == 'post' && page.cover) {
|
|
115
|
-
el += '&pics=' + page.cover;
|
|
118
|
+
el += '&pics=' + urlenc(page.cover);
|
|
116
119
|
} else if (page.wiki && page.icon) {
|
|
117
|
-
el += '&pics=' + page.icon;
|
|
120
|
+
el += '&pics=' + urlenc(page.icon);
|
|
118
121
|
}
|
|
119
|
-
el += '&summary=' + truncate(page.description || strip_html(page.excerpt || page.content), {length: 120});
|
|
122
|
+
el += '&summary=' + urlenc(truncate(page.description || strip_html(page.excerpt || page.content), {length: 120}));
|
|
120
123
|
el += '"';
|
|
121
124
|
} else if (item == 'email') {
|
|
122
|
-
el += ' href="mailto:?subject=' + page.title + ' - ' + config.title + '&'
|
|
123
|
-
el += 'body=' + page.permalink + '"';
|
|
125
|
+
el += ' href="mailto:?subject=' + urlenc(page.title + ' - ' + config.title) + '&'
|
|
126
|
+
el += 'body=' + urlenc(page.permalink) + '"';
|
|
124
127
|
} else if (item == 'link') {
|
|
125
|
-
el += ' onclick="util.copy("copy-link", "' + __('message.copied') + '")"';
|
|
128
|
+
el += ' onclick="util.copy("copy-link", "' + escape_html(__('message.copied')) + '")"';
|
|
126
129
|
}
|
|
127
130
|
el += '>';
|
|
128
131
|
el += icon(`share:${item}`)
|
|
@@ -135,7 +138,7 @@ function layoutDiv() {
|
|
|
135
138
|
if (theme.article.share.includes('wechat')) {
|
|
136
139
|
return `
|
|
137
140
|
<div class="qrcode" id="qrcode-wechat" style="opacity:0;height:0">
|
|
138
|
-
<img src="https://api.qrserver.com/v1/create-qr-code/?size=256x256&data=${page.permalink}"/>
|
|
141
|
+
<img src="https://api.qrserver.com/v1/create-qr-code/?size=256x256&data=${urlenc(page.permalink)}"/>
|
|
139
142
|
</div>
|
|
140
143
|
`
|
|
141
144
|
} else {
|
|
@@ -146,7 +149,7 @@ function layoutDiv() {
|
|
|
146
149
|
<section id="share">
|
|
147
150
|
<div class="header"><span>${__('meta.share')}</span></div>
|
|
148
151
|
<div class="body">
|
|
149
|
-
<div class="link"><input class="copy-area" readonly="true" id="copy-link" value="${page.permalink}" /></div>
|
|
152
|
+
<div class="link"><input class="copy-area" readonly="true" id="copy-link" value="${escape_html(page.permalink)}" /></div>
|
|
150
153
|
<div class="social-wrap dis-select">${socialButtons()}</div>
|
|
151
154
|
${qrcode()}
|
|
152
155
|
</div>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<%
|
|
2
2
|
function layoutDiv() {
|
|
3
3
|
var el = '';
|
|
4
|
-
|
|
4
|
+
// 置顶文章样式为平铺时不渲染轮播,置顶文章改由首页文章列表靠前展示
|
|
5
|
+
if (theme.article?.pin_style !== 'flat') {
|
|
6
|
+
el += partial('_partial/main/pin_slider', {type: 'post'});
|
|
7
|
+
}
|
|
5
8
|
el += '<div class="navbar top">';
|
|
6
9
|
el += '<div class="navbar-blur">';
|
|
7
10
|
el += '<div class="navbar-container">';
|
|
@@ -14,7 +17,7 @@ function layoutDiv() {
|
|
|
14
17
|
|
|
15
18
|
if (site.categories && site.categories.length > 0) {
|
|
16
19
|
if (page.category) {
|
|
17
|
-
el += '<a class="active" href="' + pretty_url(config.category_dir) + '">' + __("btn.category") + __("symbol.colon") + page.category + '</a>';
|
|
20
|
+
el += '<a class="active" href="' + pretty_url(config.category_dir) + '">' + __("btn.category") + __("symbol.colon") + escape_html(page.category) + '</a>';
|
|
18
21
|
} else if (page.layout == "categories") {
|
|
19
22
|
el += '<a class="active" href="' + pretty_url(config.category_dir) + '">' + __("btn.categories") + '</a>';
|
|
20
23
|
} else {
|
|
@@ -24,7 +27,7 @@ function layoutDiv() {
|
|
|
24
27
|
|
|
25
28
|
if (site.tags && site.tags.length > 0) {
|
|
26
29
|
if (page.tag) {
|
|
27
|
-
el += '<a class="active" href="' + pretty_url(config.tag_dir) + '">' + __("btn.tag") + __("symbol.colon") + page.tag + '</a>';
|
|
30
|
+
el += '<a class="active" href="' + pretty_url(config.tag_dir) + '">' + __("btn.tag") + __("symbol.colon") + escape_html(page.tag) + '</a>';
|
|
28
31
|
} else if (page.layout == "tags") {
|
|
29
32
|
el += '<a class="active" href="' + pretty_url(config.tag_dir) + '">' + __("btn.tags") + '</a>';
|
|
30
33
|
} else {
|
|
@@ -23,7 +23,7 @@ function layoutDiv() {
|
|
|
23
23
|
if (tag.name && tag.name.length > 0 && page.tagName === tag.name) {
|
|
24
24
|
el += ' class="active"';
|
|
25
25
|
}
|
|
26
|
-
el += ' href="' + pretty_url(tag.path) + '">' + tag.name + '</a>';
|
|
26
|
+
el += ' href="' + escape_html(pretty_url(tag.path)) + '">' + escape_html(tag.name) + '</a>';
|
|
27
27
|
el += '</a>';
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -69,18 +69,18 @@ function postSlide(post) {
|
|
|
69
69
|
var headline = (post.poster != null && post.poster.headline != null && post.poster.headline.length > 0) ? post.poster.headline : post.title
|
|
70
70
|
var subtitle = postSubtitle(post)
|
|
71
71
|
var el = ''
|
|
72
|
-
el += '<a class="pin-slide post-slide' + (noCover ? ' no-cover' : '') + '" href="' + pretty_url(post.link || post.path) + '"'
|
|
72
|
+
el += '<a class="pin-slide post-slide' + (noCover ? ' no-cover' : '') + '" href="' + escape_html(pretty_url(post.link || post.path)) + '"'
|
|
73
73
|
if (!noCover) {
|
|
74
|
-
el += ' style="--pin-cover-url:url(\'' + post.cover.replace(/'/g, '%27') + '\')"'
|
|
74
|
+
el += ' style="--pin-cover-url:url(\'' + escape_html(post.cover.replace(/'/g, '%27')) + '\')"'
|
|
75
75
|
}
|
|
76
76
|
el += '>'
|
|
77
77
|
if (!noCover) {
|
|
78
|
-
el += '<img class="pin-slide-bg" src="' + post.cover + '" alt=""/>'
|
|
78
|
+
el += '<img class="pin-slide-bg" src="' + escape_html(post.cover) + '" alt=""/>'
|
|
79
79
|
}
|
|
80
80
|
el += '<div class="pin-slide-text">'
|
|
81
|
-
el += '<div class="pin-slide-headline">' + headline + '</div>'
|
|
81
|
+
el += '<div class="pin-slide-headline">' + escape_html(headline) + '</div>'
|
|
82
82
|
if (subtitle.length > 0) {
|
|
83
|
-
el += '<div class="pin-slide-caption">' + subtitle + '</div>'
|
|
83
|
+
el += '<div class="pin-slide-caption">' + escape_html(subtitle) + '</div>'
|
|
84
84
|
}
|
|
85
85
|
el += '</div>'
|
|
86
86
|
el += '</a>'
|
|
@@ -90,7 +90,7 @@ function postSlide(post) {
|
|
|
90
90
|
function projectChips(tags) {
|
|
91
91
|
var caps = ''
|
|
92
92
|
if (tags && tags.length > 0) {
|
|
93
|
-
caps += '<span class="pin-slide-chip">' + tags.join('</span><span class="pin-slide-chip">') + '</span>'
|
|
93
|
+
caps += '<span class="pin-slide-chip">' + tags.map(function(t) { return escape_html(t) }).join('</span><span class="pin-slide-chip">') + '</span>'
|
|
94
94
|
}
|
|
95
95
|
return caps
|
|
96
96
|
}
|
|
@@ -100,14 +100,14 @@ function wikiSlide(proj) {
|
|
|
100
100
|
var title = proj.title || proj.name || proj.id
|
|
101
101
|
var excerpt = proj.description || ''
|
|
102
102
|
var el = ''
|
|
103
|
-
el += '<a class="pin-slide" href="' + pretty_url(proj.homepage?.path || '/') + '">'
|
|
104
|
-
el += '<img class="pin-slide-bg" src="' + img + '" alt=""/>'
|
|
103
|
+
el += '<a class="pin-slide" href="' + escape_html(pretty_url(proj.homepage?.path || '/')) + '">'
|
|
104
|
+
el += '<img class="pin-slide-bg" src="' + escape_html(img) + '" alt=""/>'
|
|
105
105
|
el += '<div class="pin-slide-mask"></div>'
|
|
106
106
|
el += '<div class="pin-slide-info">'
|
|
107
107
|
el += '<div class="pin-slide-caps">' + projectChips(proj.tags) + '</div>'
|
|
108
|
-
el += '<div class="pin-slide-title">' + title + '</div>'
|
|
108
|
+
el += '<div class="pin-slide-title">' + escape_html(title) + '</div>'
|
|
109
109
|
if (excerpt.length > 0) {
|
|
110
|
-
el += '<div class="pin-slide-excerpt">' + excerpt + '</div>'
|
|
110
|
+
el += '<div class="pin-slide-excerpt">' + escape_html(excerpt) + '</div>'
|
|
111
111
|
}
|
|
112
112
|
el += '</div>'
|
|
113
113
|
el += '</a>'
|
|
@@ -125,8 +125,7 @@ if (pinItems.length > 0) {
|
|
|
125
125
|
slidesHtml += postSlide(item)
|
|
126
126
|
}
|
|
127
127
|
if (pinItems.length > 1) {
|
|
128
|
-
|
|
129
|
-
dotsHtml += '<button type="button" class="pin-slider-dot' + (si == 0 ? ' active' : '') + '" data-index="' + si + '" aria-label="' + label + '"></button>'
|
|
128
|
+
dotsHtml += '<button type="button" class="pin-slider-dot' + (si == 0 ? ' active' : '') + '" data-index="' + si + '"></button>'
|
|
130
129
|
}
|
|
131
130
|
}
|
|
132
131
|
var groupKey = pinType == 'wiki' ? 'wiki' : 'post'
|
|
@@ -39,14 +39,14 @@ function div_default() {
|
|
|
39
39
|
}
|
|
40
40
|
if (cover_url) {
|
|
41
41
|
el += '<div class="post-cover">';
|
|
42
|
-
el += '<img src="' + cover_url + '"/>';
|
|
42
|
+
el += '<img src="' + escape_html(cover_url) + '"/>';
|
|
43
43
|
el += '</div>';
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// 标题
|
|
48
48
|
el += '<h2 class="post-title">';
|
|
49
|
-
el += post.title ? post.title : date(post.date, config.date_format);
|
|
49
|
+
el += post.title ? escape_html(post.title) : date(post.date, config.date_format);
|
|
50
50
|
el += '</h2>';
|
|
51
51
|
|
|
52
52
|
// 摘要
|
|
@@ -57,11 +57,11 @@ function div_default() {
|
|
|
57
57
|
el += '">';
|
|
58
58
|
el += '<p>';
|
|
59
59
|
if (post.excerpt) {
|
|
60
|
-
el += strip_html(post.excerpt);
|
|
60
|
+
el += escape_html(strip_html(post.excerpt));
|
|
61
61
|
} else if (post.description) {
|
|
62
|
-
el += post.description;
|
|
62
|
+
el += escape_html(post.description);
|
|
63
63
|
} else if (post.content && theme.article.auto_excerpt > 0) {
|
|
64
|
-
el += truncate(strip_html(post.content), {length: theme.article.auto_excerpt});
|
|
64
|
+
el += escape_html(truncate(strip_html(post.content), {length: theme.article.auto_excerpt}));
|
|
65
65
|
}
|
|
66
66
|
el += '</p>';
|
|
67
67
|
el += '</div>';
|
|
@@ -87,12 +87,12 @@ function div_default() {
|
|
|
87
87
|
let lastCat = cats.pop();
|
|
88
88
|
el += '<span class="cap breadcrumb"' + category_color(lastCat) + '>';
|
|
89
89
|
el += icon('default:category')
|
|
90
|
-
el += `<span>${str}</span>`
|
|
90
|
+
el += `<span>${escape_html(str)}</span>`
|
|
91
91
|
el += '</span>';
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
//
|
|
95
|
+
// 置顶文章由轮播(默认)或首页列表靠前展示(flat 平铺)承担,卡片内不显示 pin 图标。
|
|
96
96
|
el += '</div>';
|
|
97
97
|
el += '</article>';
|
|
98
98
|
return el;
|
|
@@ -107,22 +107,22 @@ function div_photo() {
|
|
|
107
107
|
position = 'bottom';
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
el += '<div class="cover" position="' + position + '" style="--cover-url:url(\'' + obj.image.replace(/'/g, '%27') + '\')">';
|
|
111
|
-
el += '<img src="' + obj.image + '"/>';
|
|
110
|
+
el += '<div class="cover" position="' + position + '" style="--cover-url:url(\'' + escape_html(obj.image.replace(/'/g, '%27')) + '\')">';
|
|
111
|
+
el += '<img src="' + escape_html(obj.image) + '"/>';
|
|
112
112
|
if (position.length > 0) {
|
|
113
113
|
el += '<div class="cover-info" position="' + position + '"';
|
|
114
114
|
if (obj.color) {
|
|
115
|
-
el += 'style="color:' + obj.color + '"';
|
|
115
|
+
el += 'style="color:' + escape_html(obj.color) + '"';
|
|
116
116
|
}
|
|
117
117
|
el += '>';
|
|
118
118
|
if (obj.topic) {
|
|
119
|
-
el += '<div class="text topic">' + obj.topic + '</div>';
|
|
119
|
+
el += '<div class="text topic">' + escape_html(obj.topic) + '</div>';
|
|
120
120
|
}
|
|
121
121
|
if (obj.headline) {
|
|
122
|
-
el += '<div class="text headline">' + obj.headline + '</div>';
|
|
122
|
+
el += '<div class="text headline">' + escape_html(obj.headline) + '</div>';
|
|
123
123
|
}
|
|
124
124
|
if (obj.caption) {
|
|
125
|
-
el += '<div class="text caption">' + obj.caption + '</div>';
|
|
125
|
+
el += '<div class="text caption">' + escape_html(obj.caption) + '</div>';
|
|
126
126
|
}
|
|
127
127
|
el += '</div>';
|
|
128
128
|
|
|
@@ -131,10 +131,10 @@ function layoutFooterDiv() {
|
|
|
131
131
|
if (item.icon && (item.url || item.onclick)) {
|
|
132
132
|
el += '<a class="social"';
|
|
133
133
|
if (item.title) {
|
|
134
|
-
el += ' title="' + item.title + '"';
|
|
134
|
+
el += ' title="' + escape_html(item.title) + '"';
|
|
135
135
|
}
|
|
136
136
|
if (item.url) {
|
|
137
|
-
el += ' href="' + url_for(item.url) + '"';
|
|
137
|
+
el += ' href="' + escape_html(url_for(item.url)) + '"';
|
|
138
138
|
if (item.url.includes('://')) {
|
|
139
139
|
el += ' target="_blank" rel="external nofollow noopener noreferrer"';
|
|
140
140
|
} else {
|
package/layout/index.ejs
CHANGED
|
@@ -29,8 +29,49 @@ if (homeCmt && homeCmt !== false && is_home_first_page()) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
//
|
|
33
|
-
var
|
|
32
|
+
// 置顶文章样式:carousel = 轮播(默认),flat = 平铺(首页列表靠前展示)
|
|
33
|
+
var pinStyle = theme.article?.pin_style || 'carousel'
|
|
34
|
+
var pinFlat = pinStyle === 'flat'
|
|
35
|
+
|
|
36
|
+
// 与 pin_slider.ejs 保持一致的置顶判定与排序权重
|
|
37
|
+
function pinValue(post) {
|
|
38
|
+
return post.pin != null ? post.pin : post.sticky
|
|
39
|
+
}
|
|
40
|
+
function isPinned(post) {
|
|
41
|
+
var v = pinValue(post)
|
|
42
|
+
return v !== false && v != null
|
|
43
|
+
}
|
|
44
|
+
function pinWeight(post) {
|
|
45
|
+
var v = pinValue(post)
|
|
46
|
+
if (v === true) {
|
|
47
|
+
return 1
|
|
48
|
+
}
|
|
49
|
+
var n = Number(v)
|
|
50
|
+
return isNaN(n) ? 0 : n
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 首页第一页渲染置顶轮播时,列表不再重复展示置顶文章(carousel 模式)
|
|
54
|
+
var pinSliderActive = is_home_first_page() && !pinFlat
|
|
55
|
+
|
|
56
|
+
// flat 模式:首页第一页收集全部置顶文章,按轮播顺序置顶展示
|
|
57
|
+
var flatPins = []
|
|
58
|
+
if (pinFlat && is_home_first_page()) {
|
|
59
|
+
var allPosts = site.posts.toArray() || []
|
|
60
|
+
for (var fi = 0; fi < allPosts.length; fi++) {
|
|
61
|
+
var fpost = allPosts[fi]
|
|
62
|
+
if (fpost.indexing === false) {
|
|
63
|
+
continue
|
|
64
|
+
}
|
|
65
|
+
if (isPinned(fpost)) {
|
|
66
|
+
flatPins.push({post: fpost, index: fi})
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
flatPins.sort(function(a, b) {
|
|
70
|
+
var d = pinWeight(b.post) - pinWeight(a.post)
|
|
71
|
+
// 权重相同保持原顺序(与轮播一致)
|
|
72
|
+
return d !== 0 ? d : a.index - b.index
|
|
73
|
+
})
|
|
74
|
+
}
|
|
34
75
|
|
|
35
76
|
function layout_post_card(layout, post, content) {
|
|
36
77
|
var el = '';
|
|
@@ -49,17 +90,32 @@ function layout_post_card(layout, post, content) {
|
|
|
49
90
|
function layout_post_list(partial) {
|
|
50
91
|
var el = '';
|
|
51
92
|
el += `<div class="post-list post">`;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
93
|
+
if (flatPins.length > 0) {
|
|
94
|
+
var pinnedPaths = {}
|
|
95
|
+
flatPins.forEach(function(item) {
|
|
96
|
+
pinnedPaths[item.post.path] = true
|
|
97
|
+
})
|
|
98
|
+
flatPins.forEach(function(item) {
|
|
99
|
+
el += layout_post_card('post', item.post, partial(item.post));
|
|
100
|
+
})
|
|
101
|
+
page.posts.each(function(post){
|
|
102
|
+
if (post.indexing != false && !pinnedPaths[post.path]) {
|
|
103
|
+
el += layout_post_card('post', post, partial(post));
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
} else {
|
|
107
|
+
page.posts.each(function(post){
|
|
108
|
+
if (post.indexing != false) {
|
|
109
|
+
if (pinSliderActive) {
|
|
110
|
+
var pinVal = pinValue(post)
|
|
111
|
+
if (pinVal !== false && pinVal != null) {
|
|
112
|
+
return
|
|
113
|
+
}
|
|
58
114
|
}
|
|
115
|
+
el += layout_post_card('post', post, partial(post));
|
|
59
116
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
})
|
|
117
|
+
})
|
|
118
|
+
}
|
|
63
119
|
el += '</div>';
|
|
64
120
|
return el;
|
|
65
121
|
}
|
package/package.json
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
var util = require('hexo-util');
|
|
8
8
|
|
|
9
|
+
function esc(v) {
|
|
10
|
+
return util.escapeHTML(v == null ? '' : String(v))
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
hexo.extend.helper.register('popular_posts_wrapper', function(args){
|
|
10
14
|
const title = args.title;
|
|
11
15
|
const json = args.json.json;
|
|
@@ -18,7 +22,7 @@ hexo.extend.helper.register('popular_posts_wrapper', function(args){
|
|
|
18
22
|
var returnHTML = "";
|
|
19
23
|
var div = `
|
|
20
24
|
<section class='header'>
|
|
21
|
-
<div class='title cap theme'>${title}</div>
|
|
25
|
+
<div class='title cap theme'>${esc(title)}</div>
|
|
22
26
|
</section>
|
|
23
27
|
<section class='body'>
|
|
24
28
|
`;
|
|
@@ -28,14 +32,14 @@ hexo.extend.helper.register('popular_posts_wrapper', function(args){
|
|
|
28
32
|
|
|
29
33
|
function listItem(obj){
|
|
30
34
|
var el = '';
|
|
31
|
-
el += '<a class="item" href="' + obj.path + '" title="' + obj.title + '">';
|
|
35
|
+
el += '<a class="item" href="' + esc(obj.path) + '" title="' + esc(obj.title) + '">';
|
|
32
36
|
var p = posts.filter(p => root + p.path == obj.path)
|
|
33
37
|
if (p && p.length > 0) {
|
|
34
38
|
p = p.data[0];
|
|
35
39
|
}
|
|
36
|
-
el += '<span class="title">' + obj.title + '</span>';
|
|
40
|
+
el += '<span class="title">' + esc(obj.title) + '</span>';
|
|
37
41
|
if (obj.excerpt && obj.excerpt.length > 0) {
|
|
38
|
-
el += '<span class="excerpt">' + util.truncate(util.stripHTML(obj.excerpt), {length: 120}) + '</span>';
|
|
42
|
+
el += '<span class="excerpt">' + esc(util.truncate(util.stripHTML(obj.excerpt), {length: 120})) + '</span>';
|
|
39
43
|
}
|
|
40
44
|
el += '</a>';
|
|
41
45
|
return el;
|
|
@@ -47,7 +51,7 @@ hexo.extend.helper.register('popular_posts_wrapper', function(args){
|
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
if (returnHTML != "") returnHTML = "<div class=\"" + cls + "\">" + returnHTML + "</div>";
|
|
54
|
+
if (returnHTML != "") returnHTML = "<div class=\"" + esc(cls) + "\">" + returnHTML + "</div>";
|
|
51
55
|
div += returnHTML;
|
|
52
56
|
div += '</section>';
|
|
53
57
|
return div;
|