You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DjangoBlog/templates/blog/article_detail.html

306 lines
13 KiB

{# gq: #}
{% extends 'share_layout/base.html' %}
{% load blog_tags %}
{% load cache %}
{% block header %}
<title>{{ article.title }} | {{ SITE_DESCRIPTION }}</title>
<meta name="description" content="{{ article.body|truncatewords:1 }}"/>
<meta name="keywords" content="{% keywords_to_str article %}"/>
<meta property="og:type" content="article"/>
<meta property="og:title" content="{{ article.title }}"/>
<meta property="og:description" content="{{ article.body|truncatewords:1 }}"/>
<meta property="og:url"
content="{{ article.get_full_url }}"/>
<meta property="article:published_time" content="{% datetimeformat article.pub_time %}"/>
<meta property="article:modified_time" content="{% datetimeformat article.last_modify_time %}"/>
<meta property="article:author" content="{{ article.author.get_full_url }}"/>
<meta property="article:section" content="{{ article.category.name }}"/>
{% for t in article.tags.all %}
<meta property="article:tag" content="{{ t.name }}"/>
{% endfor %}
<link rel="canonical" href="{{ article.get_full_url }}"/>
<style type="text/css">
.like-button {
background-color: #f0f0f0;
border: none;
color: #333;
padding: 8px 16px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 4px;
min-width: 100px; /* 确保按钮有足够的宽度 */
visibility: visible !important; /* 强制确保按钮可见 */
position: relative;
z-index: 10;
}
.like-button:hover {
background-color: #e0e0e0;
transform: scale(1.05); /* 调整缩放比例 */
}
.like-button.liked {
background-color: #ff6b6b;
color: white;
box-shadow: 0 2px 4px rgba(255, 107, 107, 0.5);
}
.like-button.loading {
opacity: 0.7;
cursor: not-allowed;
}
.likes-count {
font-weight: bold;
margin-left: 5px;
font-size: 14px;
}
.entry-likes {
display: inline-block;
vertical-align: middle;
}
/* 确保点赞按钮区域总是可见 */
.entry-meta .entry-likes {
display: inline-block !important;
}
</style>
{% endblock %}
{% block content %}
<div id="primary" class="site-content">
<div id="content" role="main">
<!-- 将点赞按钮移出缓存区域以确保它能正确加载 -->
<article id="post-{{ article.pk }}" class="post-{{ article.pk }} post type-post status-publish format-standard hentry">
<header class="entry-header">
<h1 class="entry-title">
{{ article.title }}
</h1>
<div class="entry-meta">
<span class="byline">
<i class="fa fa-user"></i>
<span class="author vcard">
<a class="url fn n" href="{{ article.author.get_absolute_url }}"
title="View all posts by {{ article.author.username }}"
rel="author">{{ article.author.username }}
</a>
</span>
</span>
<span class="sep">|</span>
<span class="entry-date">
<i class="fa fa-calendar"></i>
<time class="entry-date updated" datetime="{{ article.pub_time }}">
{% datetimeformat article.pub_time %}
</time>
</span>
<span class="sep">|</span>
<span class="entry-category">
<i class="fa fa-folder-o"></i>
<a href="{{ article.category.get_absolute_url }}" rel="category tag">
{{ article.category.name }}
</a>
</span>
<span class="sep">|</span>
<span class="entry-views">
<i class="fa fa-eye"></i>
{{ article.views }} views
</span>
<span class="sep">|</span>
<span class="entry-likes">
<button id="like-button" class="like-button" data-article-id="{{ article.pk }}">
<i class="fa fa-heart"></i>
<span class="likes-text">Like</span>
<span class="likes-count">({{ article.likes }})</span>
</button>
</span>
</div>
</header>
{% cache 36000 article_detail_content article.pk %}
<div class="entry-content">
{{ article.body|custom_markdown|escape|linebreaksbr }}
</div>
<footer class="entry-footer">
<div style="padding-bottom: 10px;">
<hr/>
<div class="post-like">
<i class="fa fa-tags"></i>
{% for tag in article.tags.all %}
<a href="{{ tag.get_absolute_url }}" rel="tag">{{ tag.name }}</a>
{% endfor %}
</div>
</div>
</footer>
{% endcache %}
</article>
<!-- You can start editing here. -->
{% include 'comments/tags/comment_list.html' %}
{% if user.is_authenticated %}
{% include 'comments/tags/post_comment.html' %}
{% else %}
<div class="comments-area-title">
<h3 class="comments-title">评论</h3>
<div class="comment-form-login-notice">
<p>您必须<a href="{% url 'account:login' %}?next={{ request.get_full_path }}">登录</a>才能发表评论。</p>
</div>
</div>
{% endif %}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
// 添加获取CSRF token的函数
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
// 使用一个全局变量来跟踪是否已经初始化了点赞按钮
let likeButtonInitialized = false;
// 创建一个初始化函数
function initializeLikeButton() {
// 如果已经初始化过,则不再执行
if (likeButtonInitialized) {
return;
}
const likeButton = document.getElementById('like-button');
// 添加调试信息
console.log('Like button element:', likeButton);
console.log('Article ID:', likeButton ? likeButton.getAttribute('data-article-id') : 'Not found');
if (likeButton) {
likeButtonInitialized = true;
const article_id = likeButton.getAttribute('data-article-id');
const likesCountElement = likeButton.querySelector('.likes-count');
const likesTextElement = likeButton.querySelector('.likes-text');
// 检查用户是否已点赞
axios.get(`/article/${article_id}/like/check/`, {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
})
.then(function(response) {
const data = response.data;
if (data.liked) {
likeButton.classList.add('liked');
likesTextElement.textContent = 'Liked'; // 确保更新按钮文本
}
})
.catch(function(error) {
console.error('Error checking like status:', error);
});
// 点击事件处理
likeButton.addEventListener('click', function() {
// 添加加载状态
likeButton.classList.add('loading');
likeButton.disabled = true;
// 根据当前状态决定是点赞还是取消点赞
const isLiked = likeButton.classList.contains('liked');
const url = `/article/${article_id}/like/`;
// 发送相应请求
let requestPromise;
if (isLiked) {
// 取消点赞 - 发送 DELETE 请求
requestPromise = axios.delete(url, {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
});
} else {
// 点赞 - 发送 POST 请求
requestPromise = axios.post(url, {}, {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
});
}
requestPromise
.then(function(response) {
const data = response.data;
// 更新点赞数量
if (data.likes_count !== undefined) {
likesCountElement.textContent = '(' + data.likes_count + ')';
}
// 更新按钮状态
if (data.liked !== undefined) {
if (data.liked) {
likeButton.classList.add('liked');
likesTextElement.textContent = 'Liked';
} else {
likeButton.classList.remove('liked');
likesTextElement.textContent = 'Like';
}
}
// 移除加载状态
likeButton.classList.remove('loading');
likeButton.disabled = false;
})
.catch(function(error) {
// 移除加载状态
likeButton.classList.remove('loading');
likeButton.disabled = false;
if (error.response && error.response.status === 403) {
alert('请先登录再点赞');
window.location.href = '/accounts/login/?next=' + encodeURIComponent(window.location.pathname);
} else if (error.response && error.response.data) {
// 处理400错误返回的JSON数据
const data = error.response.data;
if (data.detail) {
alert(data.detail);
}
// 即使出现错误,也更新显示正确的点赞数
if (data.likes_count !== undefined) {
likesCountElement.textContent = '(' + data.likes_count + ')';
}
} else {
console.error('Error:', error);
alert('操作失败,请稍后再试');
}
});
});
} else {
console.error('Like button not found in the DOM.');
}
}
// 使用更可靠的DOM加载完成检测方法
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeLikeButton);
} else {
// DOM已经加载完成
initializeLikeButton();
}
</script>
{% endblock %}