Merge branch 'develop' into xjj_branch

develop
dynastxu 3 months ago
commit f8bd1d0438

@ -0,0 +1,598 @@
/*
* DjangoBlog
* theme.css - /
* DjangoBlog
*/
:root {
/* ====== 浅色主题变量 ====== */
--bg-primary: #ffffff;
--bg-secondary: #f8f9fa;
--bg-tertiary: #e9ecef;
--bg-card: #ffffff;
--text-primary: #333333;
--text-secondary: #666666;
--text-muted: #999999;
--border-color: #dee2e6;
--link-color: #007bff;
--link-hover-color: #0056b3;
--code-bg: #f8f9fa;
--blockquote-border: #e9ecef;
--shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
/* 导航栏 */
--nav-bg: #f8f9fa;
--nav-text: #333333;
--nav-border: #dee2e6;
/* 按钮 */
--btn-primary-bg: #007bff;
--btn-primary-text: #ffffff;
--btn-secondary-bg: #6c757d;
--btn-secondary-text: #ffffff;
/* 输入框 */
--input-bg: #ffffff;
--input-text: #333333;
--input-border: #ced4da;
--input-focus-border: #007bff;
}
[data-theme="dark"] {
/* ====== 深色主题变量 ====== */
--bg-primary: #1a1a1a;
--bg-secondary: #2d2d2d;
--bg-tertiary: #404040;
--bg-card: #2d2d2d;
--text-primary: #e9ecef;
--text-secondary: #adb5bd;
--text-muted: #6c757d;
--border-color: #495057;
--link-color: #4dabf7;
--link-hover-color: #74c0fc;
--code-bg: #2d2d2d;
--blockquote-border: #495057;
--shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
/* 导航栏 */
--nav-bg: #2d2d2d;
--nav-text: #e9ecef;
--nav-border: #495057;
/* 按钮 */
--btn-primary-bg: #4dabf7;
--btn-primary-text: #ffffff;
--btn-secondary-bg: #6c757d;
--btn-secondary-text: #ffffff;
/* 输入框 */
--input-bg: #2d2d2d;
--input-text: #e9ecef;
--input-border: #495057;
--input-focus-border: #4dabf7;
}
/* ====== 基础元素样式 ====== */
body {
background-color: var(--bg-primary);
color: var(--text-primary);
transition: var(--transition);
min-height: 100vh;
}
/* ====== DjangoBlog 特定样式适配 ====== */
/* 站点头部 */
.site-header {
background-color: var(--nav-bg) !important;
border-bottom: 1px solid var(--nav-border);
}
.site-title a,
.site-description {
color: var(--nav-text) !important;
}
/* 主导航 */
.main-navigation {
background-color: var(--nav-bg);
border-color: var(--nav-border);
}
.main-navigation a {
color: var(--nav-text) !important;
}
.main-navigation a:hover {
color: var(--link-hover-color) !important;
}
/* 主要内容区域 */
#page {
background-color: var(--bg-primary);
}
#main {
background-color: var(--bg-primary);
}
/* 文章和卡片样式 */
.entry-content,
.entry-header,
.entry-summary,
.type-post,
.widget,
.comment-list,
.comment-body {
background-color: var(--bg-card);
color: var(--text-primary);
border-color: var(--border-color);
}
/* 文章标题 */
.entry-title,
.entry-title a {
color: var(--text-primary) !important;
}
.entry-title a:hover {
color: var(--link-hover-color) !important;
}
/* 元信息 */
.entry-meta,
.comment-metadata {
color: var(--text-muted) !important;
}
/* 小工具 */
.widget-title {
color: var(--text-primary);
border-bottom-color: var(--border-color);
}
/* 链接 */
a {
color: var(--link-color);
}
a:hover {
color: var(--link-hover-color);
}
/* 代码块 */
pre, code {
background-color: var(--code-bg) !important;
color: var(--text-primary) !important;
border-color: var(--border-color);
}
/* 引用 */
blockquote {
border-left-color: var(--blockquote-border);
background-color: var(--bg-secondary);
color: var(--text-secondary);
}
/* 表格 */
table {
background-color: var(--bg-card);
color: var(--text-primary);
border-color: var(--border-color);
}
th, td {
border-color: var(--border-color);
background-color: var(--bg-card);
color: var(--text-primary);
}
/* 表单 */
input, textarea, select {
background-color: var(--input-bg);
border-color: var(--input-border);
color: var(--input-text);
}
input:focus, textarea:focus, select:focus {
background-color: var(--input-bg);
border-color: var(--input-focus-border);
color: var(--input-text);
}
/* 按钮 */
button, .button, input[type="submit"], input[type="button"] {
background-color: var(--btn-primary-bg);
color: var(--btn-primary-text);
border-color: var(--btn-primary-bg);
}
/* 页脚 */
.site-footer {
background-color: var(--bg-secondary) !important;
border-top-color: var(--border-color);
color: var(--text-secondary);
}
/* ====== 主题切换按钮样式 ====== */
.theme-toggle-btn {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
transition: var(--transition);
color: var(--text-primary);
margin-left: 10px;
}
.theme-toggle-btn:hover {
transform: scale(1.1);
background-color: var(--bg-tertiary);
border-color: var(--link-color);
}
.theme-toggle-btn:focus {
outline: none;
box-shadow: 0 0 0 2px var(--link-color);
}
/* ====== 导航栏集成样式 ====== */
.nav-container {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
}
.theme-toggle-container {
margin: 0 15px;
display: flex;
align-items: center;
}
.user-menu {
display: flex;
align-items: center;
}
.user-dropdown {
position: relative;
display: inline-block;
}
.username {
padding: 8px 15px;
color: var(--text-primary);
cursor: pointer;
border: 1px solid var(--border-color);
border-radius: 4px;
background: var(--bg-secondary);
transition: var(--transition);
font-size: 14px;
}
.username:hover {
background: var(--bg-tertiary);
}
.dropdown-content {
display: none;
position: absolute;
right: 0;
background-color: var(--bg-card);
min-width: 160px;
box-shadow: var(--shadow);
border: 1px solid var(--border-color);
border-radius: 4px;
z-index: 1000;
}
.dropdown-content a {
color: var(--text-primary);
padding: 12px 16px;
text-decoration: none;
display: block;
transition: var(--transition);
border: none;
}
.dropdown-content a:hover {
background-color: var(--bg-secondary);
text-decoration: none;
}
.user-dropdown:hover .dropdown-content {
display: block;
}
.dropdown-divider {
height: 1px;
background-color: var(--border-color);
margin: 5px 0;
}
.login-link {
padding: 8px 15px;
color: var(--text-primary);
text-decoration: none;
border: 1px solid var(--border-color);
border-radius: 4px;
background: var(--bg-secondary);
transition: var(--transition);
font-size: 14px;
}
.login-link:hover {
background: var(--bg-tertiary);
color: var(--link-hover-color);
text-decoration: none;
}
/* ====== 平滑过渡效果 ====== */
body,
.site-header,
.main-navigation,
.entry-content,
.entry-header,
.widget,
.comment-list,
.site-footer,
a,
button,
input,
textarea,
select,
table,
pre,
code {
transition: var(--transition);
}
/* 图片过渡 */
img {
transition: opacity 0.3s ease;
}
[data-theme="dark"] img {
opacity: 0.9;
}
[data-theme="dark"] img:hover {
opacity: 1;
}
/* ====== 响应式调整 ====== */
@media (max-width: 768px) {
.theme-toggle-btn {
width: 36px;
height: 36px;
font-size: 1.1rem;
}
.nav-container {
flex-direction: column;
gap: 10px;
}
.theme-toggle-container {
margin: 10px 0;
}
.user-menu {
width: 100%;
justify-content: center;
}
}
/* ====== 导航栏集成优化样式 ====== */
/* 导航容器布局 */
.nav-container {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}
.primary-nav {
flex: 1;
}
.nav-actions {
display: flex;
align-items: center;
gap: 15px;
}
/* 主题切换按钮优化 */
.theme-toggle-container {
display: flex;
align-items: center;
}
.theme-toggle-btn {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 50%;
width: 40px;
height: 40px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
transition: var(--transition);
color: var(--text-primary);
}
.theme-toggle-btn:hover {
transform: scale(1.1);
background-color: var(--bg-tertiary);
border-color: var(--link-color);
}
/* 用户菜单优化 */
.user-menu {
display: flex;
align-items: center;
}
.user-dropdown {
position: relative;
display: inline-block;
}
.username {
padding: 8px 15px;
color: var(--text-primary);
cursor: pointer;
border: 1px solid var(--border-color);
border-radius: 20px;
background: var(--bg-secondary);
transition: var(--transition);
font-size: 14px;
display: flex;
align-items: center;
gap: 5px;
}
.username:hover {
background: var(--bg-tertiary);
}
.user-icon {
font-size: 12px;
}
.dropdown-content {
display: none;
position: absolute;
right: 0;
top: 100%;
background-color: var(--bg-card);
min-width: 140px;
box-shadow: var(--shadow);
border: 1px solid var(--border-color);
border-radius: 8px;
z-index: 1000;
margin-top: 5px;
}
.dropdown-content a {
color: var(--text-primary);
padding: 10px 15px;
text-decoration: none;
display: flex;
align-items: center;
gap: 8px;
transition: var(--transition);
border: none;
font-size: 14px;
}
.dropdown-content a:hover {
background-color: var(--bg-secondary);
text-decoration: none;
}
.user-dropdown:hover .dropdown-content {
display: block;
}
.dropdown-divider {
height: 1px;
background-color: var(--border-color);
margin: 5px 0;
}
.icon {
font-size: 12px;
}
.login-link {
padding: 8px 15px;
color: var(--text-primary);
text-decoration: none;
border: 1px solid var(--border-color);
border-radius: 20px;
background: var(--bg-secondary);
transition: var(--transition);
font-size: 14px;
display: flex;
align-items: center;
gap: 5px;
}
.login-link:hover {
background: var(--bg-tertiary);
color: var(--link-hover-color);
text-decoration: none;
}
/* 响应式设计 */
@media (max-width: 768px) {
.nav-container {
flex-direction: column;
gap: 10px;
padding: 10px;
}
.nav-actions {
width: 100%;
justify-content: center;
gap: 10px;
}
.theme-toggle-btn {
width: 36px;
height: 36px;
font-size: 1.1rem;
}
.primary-nav {
width: 100%;
text-align: center;
}
}
/* 确保原有导航样式兼容 */
.main-navigation {
background-color: var(--nav-bg);
border-bottom: 1px solid var(--nav-border);
transition: var(--transition);
padding: 10px 0;
}
.main-navigation div {
background: transparent !important;
}
.main-navigation a {
color: var(--nav-text) !important;
transition: var(--transition);
}
.main-navigation a:hover {
color: var(--link-hover-color) !important;
background: transparent !important;
}
/* 修复可能的分层问题 */
.site-header {
position: relative;
z-index: 100;
}
.main-navigation {
position: relative;
z-index: 99;
}

@ -0,0 +1,132 @@
// blog/static/blog/js/theme-switcher.js
(function() {
'use strict';
class ThemeSwitcher {
constructor() {
this.themeToggle = null;
this.currentTheme = this.getPreferredTheme();
this.init();
}
init() {
console.log('初始化主题切换器,当前主题:', this.currentTheme);
this.setTheme(this.currentTheme);
this.bindEvents();
this.watchSystemTheme();
}
getPreferredTheme() {
try {
const storedTheme = localStorage.getItem('theme');
if (storedTheme) {
return storedTheme;
}
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
return 'dark';
}
return 'light';
} catch (error) {
console.warn('获取主题偏好失败:', error);
return 'light';
}
}
setTheme(theme) {
try {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
this.currentTheme = theme;
this.updateToggleIcon();
console.log('主题已设置为:', theme);
const event = new CustomEvent('themeChanged', {
detail: { theme: theme }
});
document.dispatchEvent(event);
} catch (error) {
console.error('设置主题失败:', error);
}
}
toggleTheme() {
const newTheme = this.currentTheme === 'light' ? 'dark' : 'light';
console.log('切换主题:', this.currentTheme, '->', newTheme);
this.setTheme(newTheme);
}
bindEvents() {
this.themeToggle = document.getElementById('theme-toggle');
if (this.themeToggle) {
this.themeToggle.addEventListener('click', () => {
this.toggleTheme();
});
this.updateToggleIcon();
} else {
console.warn('未找到主题切换按钮 #theme-toggle');
setTimeout(() => {
this.themeToggle = document.getElementById('theme-toggle');
if (this.themeToggle) {
this.themeToggle.addEventListener('click', () => {
this.toggleTheme();
});
this.updateToggleIcon();
}
}, 1000);
}
}
updateToggleIcon() {
if (!this.themeToggle) return;
const iconElement = this.themeToggle.querySelector('.theme-icon');
if (iconElement) {
const icon = this.currentTheme === 'light' ? '🌙' : '☀️';
const title = this.currentTheme === 'light' ? '切换到深色模式' : '切换到浅色模式';
iconElement.textContent = icon;
this.themeToggle.title = title;
this.themeToggle.setAttribute('aria-label', title);
}
}
watchSystemTheme() {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const handleSystemThemeChange = (e) => {
if (!localStorage.getItem('theme')) {
const newTheme = e.matches ? 'dark' : 'light';
console.log('系统主题变化,自动切换至:', newTheme);
this.setTheme(newTheme);
}
};
if (mediaQuery.addEventListener) {
mediaQuery.addEventListener('change', handleSystemThemeChange);
} else {
mediaQuery.addListener(handleSystemThemeChange);
}
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', function() {
window.themeSwitcher = new ThemeSwitcher();
});
} else {
window.themeSwitcher = new ThemeSwitcher();
}
window.toggleTheme = function() {
if (window.themeSwitcher) {
window.themeSwitcher.toggleTheme();
}
};
})();

@ -19,11 +19,14 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="format-detection" content="telephone=no"/>
<meta name="theme-color" content="#21759b"/>
{% load blog_tags %}
{% head_meta %}
{% block header %}
<!-- SEO插件会自动生成title、description、keywords等标签 -->
{% endblock %}
<link rel="profile" href="http://gmpg.org/xfn/11"/>
<!-- 资源提示和预加载优化 -->
@ -31,7 +34,6 @@
<link rel="dns-prefetch" href="//cdn.jsdelivr.net"/>
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin/>
<!--[if lt IE 9]>
<script src="{% static 'blog/js/html5.js' %}" type="text/javascript"></script>
<![endif]-->
@ -44,21 +46,40 @@
<!-- 本地字体加载 -->
<link rel="stylesheet" href="{% static 'blog/fonts/open-sans.css' %}">
{% compress css %}
<link rel='stylesheet' id='twentytwelve-style-css' href='{% static 'blog/css/style.css' %}' type='text/css'
media='all'/>
<!-- 主题预加载脚本 - 防止闪烁 -->
<script>
(function() {
'use strict';
const storedTheme = localStorage.getItem('theme');
const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
const initialTheme = storedTheme || (systemDark ? 'dark' : 'light');
document.documentElement.setAttribute('data-theme', initialTheme);
})();
</script>
<link rel='stylesheet' id='twentytwelve-style-css' href='{% static 'blog/css/style.css' %}' type='text/css' media='all'/>
<link href="{% static 'blog/css/oauth_style.css' %}" rel="stylesheet">
<link href="{% static 'blog/css/maupassant.css' %}" rel="stylesheet">
<!-- 新增主题 CSS -->
<link href="{% static 'blog/css/theme.css' %}" rel="stylesheet">
{% comment %}<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script>{% endcomment %}
<!--[if lt IE 9]>
<link rel='stylesheet' id='twentytwelve-ie-css' href='{% static 'blog/css/ie.css' %}' type='text/css' media='all' />
<![endif]-->
<link rel="stylesheet" href="{% static 'pygments/default.css' %}"/>
<link rel="stylesheet" href="{% static 'blog/css/nprogress.css' %}">
{% block compress_css %}
{% endblock %}
<!-- 插件CSS文件 - 集成到压缩系统 -->
{% plugin_compressed_css %}
{% endcompress %}
{% if GLOBAL_HEADER %}
{{ GLOBAL_HEADER|safe }}
@ -66,32 +87,73 @@
<!-- 插件head资源 -->
{% plugin_head_resources %}
{% block extra_css %}{% endblock %}
</head>
<body class="home blog custom-font-enabled">
<body class="home blog custom-font-enabled" data-theme="light">
<div id="page" class="hfeed site">
<header id="masthead" class="site-header" role="banner">
<hgroup>
<h1 class="site-title"><a href="/" title="{{ SITE_NAME }}" rel="home">{{ SITE_NAME }}</a>
</h1>
<h1 class="site-title"><a href="/" title="{{ SITE_NAME }}" rel="home">{{ SITE_NAME }}</a></h1>
<h2 class="site-description">{{ SITE_DESCRIPTION }}</h2>
</hgroup>
{% load i18n %}
{% include 'share_layout/nav.html' %}
<!-- 修改导航栏:集成主题切换和用户菜单 -->
<nav class="main-navigation" role="navigation">
<div class="nav-container">
<!-- 原有的导航菜单 -->
<div class="primary-nav">
{% include 'share_layout/nav.html' %}
</div>
<!-- 右侧功能区域 -->
<div class="nav-actions">
<!-- 主题切换按钮 -->
<div class="theme-toggle-container">
<button id="theme-toggle" class="theme-toggle-btn" title="切换主题" aria-label="切换主题">
<span class="theme-icon">🌙</span>
</button>
</div>
<!-- 用户菜单 - 修复版本 -->
<div class="user-menu">
{% if user.is_authenticated %}
<div class="user-dropdown">
<span class="username">
<i class="user-icon">👤</i>
{{ user.username }}
</span>
<div class="dropdown-content">
<!-- 使用安全的URL路径 -->
<a href="/accounts/profile/">
<i class="icon">⚙️</i>个人资料
</a>
<div class="dropdown-divider"></div>
<a href="/accounts/logout/">
<i class="icon">🚪</i>退出
</a>
</div>
</div>
{% else %}
<a class="login-link" href="/accounts/login/">
<i class="icon">🔑</i>登录
</a>
{% endif %}
</div>
</div>
</div>
</nav>
</header><!-- #masthead -->
<div id="main" class="wrapper">
<div id="main" class="wrapper">
{% block content %}
{% endblock %}
{% block sidebar %}
{% endblock %}
</div><!-- #main .wrapper -->
{% include 'share_layout/footer.html' %}
</div><!-- #page -->
@ -101,8 +163,12 @@
<script src="{% static 'blog/js/nprogress.js' %}"></script>
<script src="{% static 'blog/js/blog.js' %}"></script>
<script src="{% static 'blog/js/navigation.js' %}"></script>
<!-- 新增主题切换JS -->
<script src="{% static 'blog/js/theme-switcher.js' %}"></script>
{% block compress_js %}
{% endblock %}
<!-- 插件JS文件 - 集成到压缩系统 -->
{% plugin_compressed_js %}
{% endcompress %}
@ -115,5 +181,7 @@
<!-- 插件body资源 -->
{% plugin_body_resources %}
{% block extra_js %}{% endblock %}
</body>
</html>
</html>
Loading…
Cancel
Save