Skip to content

Commit d3e8c53

Browse files
committed
feat(rss): ✨ RSS 页面美化
1 parent 1e7c81d commit d3e8c53

2 files changed

Lines changed: 245 additions & 3 deletions

File tree

layouts/_default/rss.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{{ printf "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | safeHTML }}
2+
{{ printf "<?xml-stylesheet type=\"text/xsl\" href=\"%s\"?>" "/xsl/rss.xsl" | safeHTML }}
13
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
24
<channel>
35
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
@@ -17,9 +19,7 @@
1719
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
1820
{{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
1921
<guid>{{ .Site.Params.fullURL }}{{ .Permalink }}</guid>
20-
<description>
21-
{{ .Content | html }}
22-
</description>
22+
<description>{{ .Summary | html }}</description>
2323
</item>
2424
{{ end }}
2525
</channel>

static/xsl/rss.xsl

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom">
3+
<xsl:output method="html" indent="yes"/>
4+
5+
<xsl:template match="/">
6+
<html lang="zh-CN">
7+
<head>
8+
<meta charset="UTF-8"/>
9+
<title><xsl:value-of select="rss/channel/title"/></title>
10+
<style>
11+
:root {
12+
--primary: rgba(96, 156, 250, 1);
13+
--secondary: rgb(29 78 216 / 64%);
14+
--text: #2D3748;
15+
--bg: #f8f9fa;
16+
--card-bg: #ffffff;
17+
--border: rgba(0, 0, 0, 0.1);
18+
--blockquote: #3474d7;
19+
}
20+
21+
[data-theme="dark"] {
22+
--primary: #6B8CFF;
23+
--secondary: #B07CFF;
24+
--text: #E2E8F0;
25+
--bg: #1A202C;
26+
--card-bg: #2D3748;
27+
--border: rgba(255, 255, 255, 0.1);
28+
--blockquote: #7cafff;
29+
}
30+
31+
body {
32+
margin: 0;
33+
padding-left: 17%;
34+
padding-right: 17%;
35+
padding-top: 2rem;
36+
padding-bottom: 2rem;
37+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
38+
line-height: 1.6;
39+
background: var(--bg);
40+
color: var(--text);
41+
transition: background 0.3s ease;
42+
}
43+
44+
.big-header {
45+
background: linear-gradient(135deg, var(--primary), var(--secondary));
46+
color: white;
47+
padding: 1rem 2rem;
48+
border-radius: 12px;
49+
margin-bottom: 2rem;
50+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
51+
}
52+
53+
.header {
54+
display: flex;
55+
justify-content: space-between;
56+
align-items: center;
57+
}
58+
59+
.theme-toggle {
60+
background: none;
61+
border: none;
62+
cursor: pointer;
63+
padding: 8px;
64+
border-radius: 50%;
65+
transition: background 0.2s;
66+
}
67+
68+
.theme-toggle:hover {
69+
background: rgba(255, 255, 255, 0.1);
70+
}
71+
72+
.theme-icon {
73+
width: 24px;
74+
height: 24px;
75+
fill: white;
76+
}
77+
78+
.card {
79+
background: var(--card-bg);
80+
border: 1px solid var(--border);
81+
border-radius: 12px;
82+
padding: 1.5rem;
83+
box-shadow: 0 2px 8px rgba(154, 75, 255, 0.1);
84+
transition: transform 0.2s;
85+
margin-bottom: 1rem;
86+
overflow: hidden;
87+
}
88+
89+
.card:hover {
90+
transform: translateY(-4px);
91+
}
92+
93+
.card-title {
94+
color: var(--primary);
95+
margin: 0 0 1rem;
96+
font-size: 1.3rem;
97+
}
98+
99+
.card-date {
100+
color: #718096;
101+
font-size: 0.9rem;
102+
margin-bottom: 0.8rem;
103+
}
104+
105+
.card-content {
106+
color: var(--text);
107+
font-size: 1rem;
108+
line-height: 1.5;
109+
}
110+
111+
.card-link {
112+
display: inline-block;
113+
margin-top: 1rem;
114+
color: var(--secondary);
115+
text-decoration: none;
116+
font-weight: 500;
117+
}
118+
119+
.card-link:hover {
120+
text-decoration: underline;
121+
}
122+
123+
.meta-info {
124+
text-align: center;
125+
color: #718096;
126+
margin-top: 2rem;
127+
padding: 1rem;
128+
font-size: 0.9rem;
129+
}
130+
131+
.icon {
132+
display: none;
133+
}
134+
135+
img {
136+
max-width: 50%;
137+
}
138+
139+
blockquote {
140+
margin: 1em 0;
141+
padding: 0.2em 0.8em;
142+
border-left: 0.2em solid var(--blockquote);
143+
}
144+
145+
/* 暗色模式图标切换 */
146+
[data-theme="dark"] .light-icon {
147+
display: none;
148+
}
149+
[data-theme="dark"] .dark-icon {
150+
display: block;
151+
}
152+
153+
.light-icon {
154+
display: block;
155+
}
156+
.dark-icon {
157+
display: none;
158+
}
159+
160+
/* 暗色模式文本微调 */
161+
[data-theme="dark"] .card-date {
162+
color: #CBD5E0;
163+
}
164+
165+
/* 暗色模式阴影调整 */
166+
[data-theme="dark"] .card {
167+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
168+
}
169+
</style>
170+
</head>
171+
<body>
172+
<div class="big-header">
173+
<div class="header">
174+
<h1><xsl:value-of select="rss/channel/title"/></h1>
175+
176+
<button class="theme-toggle" id="themeToggle">
177+
<svg class="theme-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
178+
<!-- Moon icon (dark mode) -->
179+
<path class="dark-icon" d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1-8.313-12.454z"/>
180+
<!-- Sun icon (light mode) -->
181+
<path class="light-icon" d="M12 18a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-2a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM11 1h2v3h-2V1zm0 19h2v3h-2v-3zM3.515 4.929l1.414-1.414L7.05 5.636 5.636 7.05 3.515 4.93zM16.95 18.364l1.414-1.414 2.121 2.121-1.414 1.414-2.121-2.121zm2.121-14.85l1.414 1.415-2.121 2.121-1.414-1.414 2.121-2.121zM5.636 16.95l1.414 1.414-2.121 2.121-1.414-1.414 2.121-2.121zM23 11v2h-3v-2h3zM4 11v2H1v-2h3z"/>
182+
</svg>
183+
</button>
184+
</div>
185+
<blockquote>本页面是 Atom 订阅源,可直接被订阅。</blockquote>
186+
187+
</div>
188+
189+
<div class="card-container">
190+
<xsl:for-each select="rss/channel/item">
191+
<div class="card">
192+
<h2 class="card-title"><xsl:value-of select="title"/></h2>
193+
<div class="card-date">
194+
<xsl:value-of select="pubDate"/>
195+
<xsl:if test="author"> · <xsl:value-of select="author"/></xsl:if>
196+
</div>
197+
<div class="card-content">
198+
<xsl:value-of select="description" disable-output-escaping="yes"/>
199+
</div>
200+
<a href="{link}" class="card-link">阅读全文 →</a>
201+
</div>
202+
</xsl:for-each>
203+
</div>
204+
205+
<div class="meta-info">
206+
<div>由 FloatBlog 生成</div>
207+
<xsl:if test="rss/channel/lastBuildDate">
208+
<div>最后更新: <xsl:value-of select="rss/channel/lastBuildDate"/></div>
209+
</xsl:if>
210+
</div>
211+
212+
<script>
213+
<![CDATA[
214+
(function() {
215+
const themeToggle = document.getElementById('themeToggle');
216+
const body = document.documentElement;
217+
218+
// 初始化主题
219+
const savedTheme = localStorage.getItem('theme') || 'light';
220+
body.setAttribute('data-theme', savedTheme);
221+
222+
themeToggle.addEventListener('click', function() {
223+
const currentTheme = body.getAttribute('data-theme') === 'dark' ? 'light' : 'dark';
224+
body.setAttribute('data-theme', currentTheme);
225+
localStorage.setItem('theme', currentTheme);
226+
});
227+
228+
// 系统主题检测
229+
if (!localStorage.getItem('theme')) {
230+
const mql = window.matchMedia('(prefers-color-scheme: dark)');
231+
const handleSystemThemeChange = function(e) {
232+
body.setAttribute('data-theme', e.matches ? 'dark' : 'light');
233+
};
234+
mql.addListener(handleSystemThemeChange);
235+
}
236+
})();
237+
]]>
238+
</script>
239+
</body>
240+
</html>
241+
</xsl:template>
242+
</xsl:stylesheet>

0 commit comments

Comments
 (0)