aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2025-01-02 23:47:41 -0500
committerBobby <[email protected]>2025-01-02 23:47:41 -0500
commita9c4481356e54317584a4f92d7329364f8ad99e3 (patch)
treeafc5991e0c662a9250c7cde64bc08b3b51dc78e8
parentb6bf53661c750cc11fc4d976a594e3ef19cc7363 (diff)
downloadthatcomputerscientist-a9c4481356e54317584a4f92d7329364f8ad99e3.tar.xz
thatcomputerscientist-a9c4481356e54317584a4f92d7329364f8ad99e3.zip
some optimization stuff
-rwxr-xr-xapps/blog/admin.py11
-rw-r--r--apps/blog/migrations/0022_comment_downvotes_comment_upvotes.py23
-rwxr-xr-xapps/blog/models.py119
-rwxr-xr-xapps/blog/views.py25
-rwxr-xr-xinternal/weblog_utilities.py45
-rwxr-xr-xstatic/css/core/post_list.css99
-rwxr-xr-xstatic/css/shared/core.css148
-rw-r--r--static/images/core/messages/texts/navigation_en.pngbin0 -> 140274 bytes
-rw-r--r--templates/partials/_comment.html59
-rwxr-xr-xtemplates/partials/_weblog_list.html14
-rw-r--r--templates/shared/blog/single_weblog.html29
11 files changed, 429 insertions, 143 deletions
diff --git a/apps/blog/admin.py b/apps/blog/admin.py
index 157fff51..cd9a25b8 100755
--- a/apps/blog/admin.py
+++ b/apps/blog/admin.py
@@ -191,10 +191,17 @@ class WeblogAdmin(admin.ModelAdmin):
@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
- list_display = ("post", "get_author", "created_at", "edited")
+ list_display = (
+ "post",
+ "get_author",
+ "created_at",
+ "edited",
+ "upvotes",
+ "downvotes",
+ )
list_filter = ("edited", "created_at")
search_fields = ("body", "user__username", "anonymous_user__name")
- readonly_fields = ("created_at", "edited", "edited_at")
+ readonly_fields = ("created_at", "edited_at")
def get_author(self, obj):
return obj.user.username if obj.user else obj.anonymous_user.name
diff --git a/apps/blog/migrations/0022_comment_downvotes_comment_upvotes.py b/apps/blog/migrations/0022_comment_downvotes_comment_upvotes.py
new file mode 100644
index 00000000..0281c686
--- /dev/null
+++ b/apps/blog/migrations/0022_comment_downvotes_comment_upvotes.py
@@ -0,0 +1,23 @@
+# Generated by Django 5.1.4 on 2025-01-03 01:27
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('blog', '0021_categorytranslation_tagtranslation'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='comment',
+ name='downvotes',
+ field=models.IntegerField(default=0),
+ ),
+ migrations.AddField(
+ model_name='comment',
+ name='upvotes',
+ field=models.IntegerField(default=0),
+ ),
+ ]
diff --git a/apps/blog/models.py b/apps/blog/models.py
index 9fa7eb30..bdfb6921 100755
--- a/apps/blog/models.py
+++ b/apps/blog/models.py
@@ -64,18 +64,62 @@ class PostTranslation(Translation):
class TranslatableMixin:
+ @classmethod
+ def translate_queryset(cls, queryset, language_code="en"):
+ processed_objects = set()
+ return [obj.translate(language_code, processed_objects) for obj in queryset]
+
+ def translate(self, language_code="en", processed_objects=None):
+ if processed_objects is None:
+ processed_objects = set()
+
+ instance_id = f"{self.__class__.__name__}_{self.pk}"
+ if instance_id in processed_objects:
+ return self
+
+ processed_objects.add(instance_id)
+ translation = self.get_translation(language_code)
+
+ if translation:
+ translated_fields = [
+ field.name
+ for field in translation._meta.get_fields()
+ if not field.is_relation
+ and field.name not in ["id", "language", "created_at", "updated_at"]
+ ]
+
+ for field_name in translated_fields:
+ translated_value = getattr(translation, field_name, None)
+ if translated_value is not None:
+ setattr(self, field_name, translated_value)
+
+ self._translate_relations(language_code, processed_objects)
+ return self
+
+ def _translate_relations(self, language_code, processed_objects):
+ for field in self._meta.get_fields():
+ if not hasattr(field, "related_model") or not hasattr(
+ field.related_model, "translate"
+ ):
+ continue
+
+ if field.one_to_many or field.many_to_many:
+ related_manager = getattr(self, field.name, None)
+ if related_manager and hasattr(related_manager, "all"):
+ for obj in related_manager.all():
+ obj.translate(language_code, processed_objects)
+
+ elif field.many_to_one or field.one_to_one:
+ related_obj = getattr(self, field.name, None)
+ if related_obj and hasattr(related_obj, "translate"):
+ related_obj.translate(language_code, processed_objects)
+
def get_translation(self, language_code):
try:
return self.translations.get(language=language_code)
except self.translations.model.DoesNotExist:
return None
- def translate(self, field_name, language_code="en"):
- translation = self.get_translation(language_code)
- if translation and hasattr(translation, field_name):
- return getattr(translation, field_name)
- return getattr(self, field_name)
-
class Weblog(models.Model):
name = models.CharField(max_length=100)
@@ -94,7 +138,7 @@ class Weblog(models.Model):
return self.name
-class Category(models.Model):
+class Category(TranslatableMixin, models.Model):
weblog = models.ForeignKey(Weblog, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
name_ja = models.CharField(
@@ -120,7 +164,7 @@ class Category(models.Model):
return self.translate("name", language_code)
-class Tag(models.Model):
+class Tag(TranslatableMixin, models.Model):
weblog = models.ForeignKey(Weblog, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
name_ja = models.CharField(
@@ -145,7 +189,7 @@ class Tag(models.Model):
return self.translate("name", language_code)
-class Post(models.Model):
+class Post(TranslatableMixin, models.Model):
weblog = models.ForeignKey(Weblog, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
title_ja = models.CharField(
@@ -176,15 +220,52 @@ class Post(models.Model):
def __str__(self):
return f"{self.weblog.name} - {self.title}"
- def get_excerpt(self, language_code="en", length=1000):
- content = self.get_body(language_code)
- soup = BeautifulSoup(content, "html.parser")
- excerpt = ""
- for paragraph in soup.find_all("p"):
- excerpt += f"<p>{paragraph.text}</p>"
- if len(excerpt) >= length:
- break
- return excerpt
+ def get_excerpt(self, length=1000):
+ if not hasattr(self, "_excerpt"):
+ soup = BeautifulSoup(self.body, "html.parser")
+ excerpt = ""
+ for paragraph in soup.find_all("p"):
+ paragraph = "<p>" + str(paragraph) + "</p>"
+ excerpt += str(paragraph)
+
+ if len(excerpt) >= length:
+ break
+ self._excerpt = excerpt
+ return self._excerpt
+
+ @property
+ def excerpt(self):
+ return self.get_excerpt()
+
+ def get_processed_body(self):
+ if not hasattr(self, "_processed_body"):
+ soup = BeautifulSoup(self.body, "html.parser")
+ first_p = soup.find("p")
+
+ self._first_paragraph = str(first_p) if first_p else ""
+ if first_p:
+ first_p.decompose()
+
+ self._processed_body = str(soup)
+
+ return self._processed_body
+
+ @property
+ def processed_body(self):
+ return self.get_processed_body()
+
+ @property
+ def first_paragraph(self):
+ if not hasattr(self, "_first_paragraph"):
+ self.get_processed_body()
+ return self._first_paragraph
+
+ def translate(self, language_code="en", processed_objects=None):
+ instance = super().translate(language_code, processed_objects)
+ if hasattr(instance, "_processed_body"):
+ delattr(instance, "_processed_body")
+ delattr(instance, "_first_paragraph")
+ return instance
class AnonymousCommentUser(models.Model):
@@ -218,6 +299,8 @@ class Comment(models.Model):
parent = models.ForeignKey(
"self", on_delete=models.CASCADE, null=True, blank=True, related_name="replies"
)
+ upvotes = models.IntegerField(default=0)
+ downvotes = models.IntegerField(default=0)
body = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
edited = models.BooleanField(default=False)
diff --git a/apps/blog/views.py b/apps/blog/views.py
index f590ee2b..d2f6c647 100755
--- a/apps/blog/views.py
+++ b/apps/blog/views.py
@@ -7,23 +7,16 @@ from bs4 import BeautifulSoup
def single_post(request, slug):
try:
- post = Post.objects.get(slug=slug)
-
lang_code = request.LANGUAGE_CODE
- if lang_code == "ja":
- post.body = highlight_code(post.body_ja)
- else:
- post.body = highlight_code(post.body)
-
- soup = BeautifulSoup(post.body, "html.parser")
- first_paragraph = soup.find("p")
- if first_paragraph is not None:
- first_paragraph = str(first_paragraph)
- soup.find("p").decompose()
-
- post.first_paragraph = first_paragraph
- post.body = str(soup)
-
+ post = (
+ Post.objects.select_related("category")
+ .prefetch_related(
+ "tags", "translations", "category__translations", "tags__translations"
+ )
+ .get(slug=slug)
+ .translate(lang_code)
+ )
+ post.body = highlight_code(post.processed_body)
return render(request, "shared/blog/single_weblog.html", {"post": post})
except Post.DoesNotExist:
return HttpResponseNotFound()
diff --git a/internal/weblog_utilities.py b/internal/weblog_utilities.py
index 02b851e9..6721fdc8 100755
--- a/internal/weblog_utilities.py
+++ b/internal/weblog_utilities.py
@@ -1,35 +1,38 @@
-from apps.blog.models import Post, Comment
+from apps.blog.models import Post
from pygments import highlight
from pygments.lexers import get_lexer_by_name, guess_lexer
from pygments.formatters import HtmlFormatter
+from pygments.styles.vim import VimStyle
+from pygments.style import Style
+from pygments.token import Comment
from bs4 import BeautifulSoup
import html
AUTHOR_USERNAME = "bobby"
-def add_excerpt(post, lang="en"):
- if lang == "ja":
- soup = BeautifulSoup(post.body_ja, "html.parser")
- else:
- soup = BeautifulSoup(post.body, "html.parser")
- excerpt = ""
- for paragraph in soup.find_all("p"):
- paragraph = "<p>" + str(paragraph.text) + "</p>"
- excerpt += str(paragraph)
+class ShifooHighlight(Style):
+ """Custom Vim style with modified comment colors"""
- if len(excerpt) >= 1000:
- break
- return excerpt
+ # Inherit all styles from VimStyle
+ styles = dict(VimStyle.styles)
+ # Override comment styles using proper token types
+ styles.update(
+ {Comment: "#666666", Comment.Preproc: "#666666", Comment.Special: "#666666"}
+ )
-def recent_weblogs(lang="en", amount=3):
- recent_posts = Post.objects.filter(
- is_public=True, author__username=AUTHOR_USERNAME
- ).order_by("-date")[:amount]
- for post in recent_posts:
- post.excerpt = add_excerpt(post, lang)
- return recent_posts
+
+def recent_weblogs(lang="en", amount=10):
+ queryset = (
+ Post.objects.filter(is_public=True, author__username=AUTHOR_USERNAME)
+ .prefetch_related(
+ "tags", "translations", "category__translations", "tags__translations"
+ )
+ .order_by("-date")[:amount]
+ )
+
+ return Post.translate_queryset(queryset, lang)
def highlight_code(html_content):
@@ -55,7 +58,7 @@ def highlight_code(html_content):
formatter = HtmlFormatter(
noclasses=True,
- style="native",
+ style=ShifooHighlight,
wrapcode=True,
cssstyles="background: none; padding: 8px 0;",
)
diff --git a/static/css/core/post_list.css b/static/css/core/post_list.css
index 7f7511a2..7df9b158 100755
--- a/static/css/core/post_list.css
+++ b/static/css/core/post_list.css
@@ -49,6 +49,7 @@
}
.post-actions {
+ clear: both;
display: flex;
justify-content: space-between;
margin: 8px 0px;
@@ -62,12 +63,106 @@
font-size: 11px;
font-weight: normal;
text-transform: capitalize;
- background-color: #311b4f;
- color: #dddddd !important;
+ color: #fff !important;
border-radius: 10px;
+ background: linear-gradient(145deg, #452673, #311b4f);
+ box-shadow:
+ inset 0 1px 1px rgba(255, 255, 255, 0.4),
+ inset 0 -1px 1px rgba(0, 0, 0, 0.4),
+ 0 0 5px rgba(69, 38, 115, 0.5),
+ 0 2px 4px rgba(0, 0, 0, 0.2);
+ border: 1px solid #5a338f;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
+ transition: all 0.2s ease;
+ position: relative;
+ overflow: hidden;
}
.post-tag:hover {
+ background: linear-gradient(145deg, #512c85, #3d2361);
+ box-shadow:
+ inset 0 1px 1px rgba(255, 255, 255, 0.4),
+ inset 0 -1px 1px rgba(0, 0, 0, 0.4),
+ 0 0 10px rgba(69, 38, 115, 0.8),
+ 0 2px 4px rgba(0, 0, 0, 0.2);
+}
+
+.post-tag:hover::after {
+ content: '';
+ position: absolute;
+ top: -50%;
+ left: -150%;
+ width: 200%;
+ height: 200%;
+ background: linear-gradient(45deg,
+ transparent 0%,
+ rgba(255, 255, 255, 0.1) 45%,
+ rgba(255, 255, 255, 0.5) 50%,
+ rgba(255, 255, 255, 0.1) 55%,
+ transparent 100%);
+ transform: rotate(45deg);
+ animation: shine 4s linear infinite;
+}
+
+.post-tag:active {
+ background: linear-gradient(145deg, #311b4f, #452673);
+ box-shadow:
+ inset 0 2px 4px rgba(0, 0, 0, 0.4),
+ 0 0 5px rgba(69, 38, 115, 0.5);
+ transform: translateY(1px);
+}
+
+@keyframes shine {
+ 0% {
+ left: -150%;
+ }
+
+ 25% {
+ left: 100%;
+ }
+
+ 100% {
+ left: 100%;
+ }
+}
+
+/* .post-tag:hover {
background-color: #311b4f;
color: #dddddd !important;
+} */
+
+p>img {
+ shape-outside: margin-box;
+ width: auto;
+ height: auto;
+ max-width: 180px;
+ max-height: 180px;
+ border-radius: 4px;
+ overflow: hidden;
+ position: relative;
+ top: 6px;
+ margin-bottom: 8px;
+}
+
+p>img:nth-of-type(odd) {
+ float: left;
+ margin-right: 12px;
+ margin-left: 0;
+}
+
+p>img:nth-of-type(even) {
+ float: right;
+ margin-left: 12px;
+ margin-right: 0;
+}
+
+p>img.block {
+ width: 780px;
+ max-width: 780px;
+ height: auto;
+ max-height: 100%;
+ display: block;
+ margin: 0px 0px 16px 0px;
+ clear: both;
+ float: none;
} \ No newline at end of file
diff --git a/static/css/shared/core.css b/static/css/shared/core.css
index 41924bbb..de275aa1 100755
--- a/static/css/shared/core.css
+++ b/static/css/shared/core.css
@@ -98,41 +98,6 @@ a:hover {
text-decoration: underline;
}
-.link-button {
- background: rgba(134, 99, 229, 0.2);
- padding: 8px 16px;
- border-radius: 4px;
- color: #8d8dff;
- text-decoration: none;
- border: 1px solid #8d8dff;
- transition: all 0.3s ease;
- font-size: 12px;
-}
-
-.link-button:hover {
- background: rgba(223, 35, 196, 0.2);
- border-color: #df23c4;
- color: #df23c4;
- text-decoration: none;
- transform: translateY(-2px);
-}
-
-.action-button {
- padding: 4px 8px;
- border-radius: 4px;
- color: #8d8dff;
- text-decoration: none;
- font-size: 11px;
- transition: all 0.2s ease;
- background: rgba(141, 141, 255, 0.1);
-}
-
-.action-button:hover {
- color: #df23c4;
- background: rgba(223, 35, 196, 0.1);
- text-decoration: none;
-}
-
textarea {
resize: none;
background: transparent;
@@ -184,44 +149,6 @@ img {
display: flex;
}
-/* SCANLINES */
-#scanlines {
- position: fixed;
- left: 0;
- top: 0;
- width: 100vw;
- height: 100vh;
- pointer-events: none;
- z-index: 9;
- opacity: 0.18;
-}
-
-#scanlines:before {
- content: "";
- position: absolute;
- left: 0;
- top: 0;
- right: 0;
- bottom: 0;
- pointer-events: none;
- background: linear-gradient(to bottom, transparent 50%, rgba(0, 0, 0, .4) 50%);
- background-size: 100% 4px;
- will-change: background, background-size;
- animation: scanlines 0.2s linear infinite;
-}
-
-@keyframes scanlines {
- from {
- background: linear-gradient(to bottom, transparent 10%, rgba(0, 0, 0, .4) 50%);
- background-size: 100% 4px;
- }
-
- to {
- background: linear-gradient(to bottom, rgba(0, 0, 0, .4) 50%, transparent 50%);
- background-size: 100% 4px;
- }
-}
-
/* Main Content */
#right-sidebar {
@@ -447,4 +374,79 @@ html[lang='ja'] .navigation-title {
/* Text Formatting */
.section-title {
margin: 16px 0px;
+}
+
+
+/* SCANLINES */
+#scanlines {
+ position: fixed;
+ left: 0;
+ top: 0;
+ width: 100vw;
+ height: 100vh;
+ pointer-events: none;
+ z-index: 9;
+ opacity: 0.18;
+}
+
+#scanlines:before {
+ content: "";
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ pointer-events: none;
+ background: linear-gradient(to bottom, transparent 50%, rgba(0, 0, 0, .4) 50%);
+ background-size: 100% 4px;
+ will-change: background, background-size;
+ animation: scanlines 0.2s linear infinite;
+}
+
+@keyframes scanlines {
+ from {
+ background: linear-gradient(to bottom, transparent 10%, rgba(0, 0, 0, .4) 50%);
+ background-size: 100% 4px;
+ }
+
+ to {
+ background: linear-gradient(to bottom, rgba(0, 0, 0, .4) 50%, transparent 50%);
+ background-size: 100% 4px;
+ }
+}
+
+/* Other Stuff */
+.link-button {
+ background: rgba(134, 99, 229, 0.2);
+ padding: 8px 16px;
+ border-radius: 4px;
+ color: #8d8dff;
+ text-decoration: none;
+ border: 1px solid #8d8dff;
+ transition: all 0.3s ease;
+ font-size: 12px;
+}
+
+.link-button:hover {
+ background: rgba(223, 35, 196, 0.2);
+ border-color: #df23c4;
+ color: #df23c4;
+ text-decoration: none;
+ transform: translateY(-2px);
+}
+
+.action-button {
+ padding: 4px 8px;
+ border-radius: 4px;
+ color: #8d8dff;
+ text-decoration: none;
+ font-size: 11px;
+ transition: all 0.2s ease;
+ background: rgba(141, 141, 255, 0.1);
+}
+
+.action-button:hover {
+ color: #df23c4;
+ background: rgba(223, 35, 196, 0.1);
+ text-decoration: none;
} \ No newline at end of file
diff --git a/static/images/core/messages/texts/navigation_en.png b/static/images/core/messages/texts/navigation_en.png
new file mode 100644
index 00000000..18e9da18
--- /dev/null
+++ b/static/images/core/messages/texts/navigation_en.png
Binary files differ
diff --git a/templates/partials/_comment.html b/templates/partials/_comment.html
new file mode 100644
index 00000000..bc2d9580
--- /dev/null
+++ b/templates/partials/_comment.html
@@ -0,0 +1,59 @@
+<div class="comment-container" id="comment-{{ comment.id }}" style="margin-left: {% widthratio 24 1 comment.level %}px;">
+ <div class="comment-header">
+ {% if comment.user %}
+ <img src="{{ comment.user.avatar.url }}" alt="{{ comment.user.username }}">
+ <span class="font-medium">{{ comment.user.username }}</span>
+ {% else %}
+ <img src="{{ comment.anonymous_user.avatar }}" alt="{{ comment.anonymous_user.name }}">
+ <span class="font-medium">{{ comment.anonymous_user.name }}</span>
+ {% endif %}
+ <span>{{ comment.created_at|timesince }} ago</span>
+ {% if comment.edited %}
+ <span>(edited)</span>
+ {% endif %}
+ </div>
+
+ <div>
+ <p>{{ comment.body }}</p>
+ </div>
+
+ <div class="comment-actions">
+ <button
+ onclick="showReplyForm('{{ comment.id }}')">
+ Reply
+ </button>
+ {% if user == comment.user or is_admin %}
+ <button
+ onclick="showEditForm('{{ comment.id }}')">
+ Edit
+ </button>
+ <button
+ onclick="deleteComment('{{ comment.id }}')">
+ Delete
+ </button>
+ {% endif %}
+ </div>
+
+ <!-- Reply form (hidden by default) -->
+ <div id="reply-form-{{ comment.id }}" style="display: none; margin-left: 24px;">
+ <form method="POST" action="#" class="space-y-4">
+ {% csrf_token %}
+ <input type="hidden" name="parent_id" value="{{ comment.id }}">
+ <textarea name="body" rows="3"
+ placeholder="Write a reply..."></textarea>
+ <div class="flex justify-end gap-2">
+ <button type="button" onclick="hideReplyForm('{{ comment.id }}')">
+ Cancel
+ </button>
+ <button type="submit">
+ Reply
+ </button>
+ </div>
+ </form>
+ </div>
+
+ <!-- Nested replies -->
+ {% for reply in comment.replies.all %}
+ {% include 'partials/_comment.html' with comment=reply %}
+ {% endfor %}
+</div> \ No newline at end of file
diff --git a/templates/partials/_weblog_list.html b/templates/partials/_weblog_list.html
index d8a81dc7..a9b33462 100755
--- a/templates/partials/_weblog_list.html
+++ b/templates/partials/_weblog_list.html
@@ -5,11 +5,11 @@
<div class="post">
<div class="post-body">
<div class="post-image">
- <img src="{{ post.image_url }}" alt="{% if request.LANGUAGE_CODE == 'ja' %}{{ post.title_ja }}{% else %}{{ post.title }}{% endif %}">
+ <img src="{{ post.image_url }}" alt="{{ post.title }}">
</div>
<div class="post-content">
<h2>
- <a href="{% url "weblog:single_post" post.slug %}">{% if request.LANGUAGE_CODE == 'ja' %}{{ post.title_ja }}{% else %}{{ post.title }}{% endif %}</a>
+ <a href="{% url "weblog:single_post" post.slug %}">{{ post.title }}</a>
</h2>
<div class="author-info">
{% with post.author.userprofile_set.first as authorprofile %}
@@ -17,17 +17,19 @@
{% endwith %}
<a href="#"> {{ post.author.first_name }} {{ post.author.last_name }}</a>
<span>{% if request.LANGUAGE_CODE == 'ja' %}投稿カテゴリー:{% else %}posted in{% endif %}</span>
- <a href="#{{ post.category.slug }}">{% if request.LANGUAGE_CODE == 'ja' %}{{ post.category.name_ja }}{% else %}{{ post.category.name }}{% endif %}</a>
+ <a href="#{{ post.category.slug }}">{{ post.category.name }}</a>
<span>{% if request.LANGUAGE_CODE == 'ja' %}投稿日:{% else %}on{% endif %}</span>
<span style="margin-left: 4px;">{% localtime on %}{{ post.date | date:"M d, Y" }}{% endlocaltime %}</span>
</div>
- {{ post.excerpt | safe }}
+ <div class="post-exerpt">
+ {{ post.excerpt | safe }}
+ </div>
</div>
</div>
<div class="post-actions">
<div class="post-links">
<a href="{% url "weblog:single_post" post.slug %}">{% if request.LANGUAGE_CODE == 'ja' %}続きを読む{% else %}Continue Reading{% endif %}</a> |
- <a href="##comments">{{ post.comments.all|length }}
+ <a href="{% url "weblog:single_post" post.slug %}#comments">{{ post.comments.all|length }}
{% if request.LANGUAGE_CODE == 'ja' %}
コメント
{% else %}
@@ -36,7 +38,7 @@
</div>
<div class="post-tags">
{% for tag in post.tags.all %}
- <a class="post-tag" href="#{{ tag.slug }}">{% if request.LANGUAGE_CODE == 'ja' %}{{ tag.name_ja }}{% else %}{{ tag.name }}{% endif %}</a>
+ <a class="post-tag" href="#{{ tag.slug }}">{{ tag.name }}</a>
{% endfor %}
</div>
</div>
diff --git a/templates/shared/blog/single_weblog.html b/templates/shared/blog/single_weblog.html
index 42180de0..4bffbd1f 100644
--- a/templates/shared/blog/single_weblog.html
+++ b/templates/shared/blog/single_weblog.html
@@ -2,7 +2,7 @@
{% load static %}
{% load tz %}
{% block title %}
-<title>{% if request.LANGUAGE_CODE == 'ja' %}{{ post.title_ja }}{% else %}{{ post.title }}{% endif %}</title>
+<title>{{ post.title }}</title>
{% endblock title %}
{% block head %}
<link rel="stylesheet" href="{% static 'css/core/post_list.css' %}">
@@ -15,7 +15,7 @@
<div class="weblog-container">
<div class="weblog-title-area">
<h1>
- {% if request.LANGUAGE_CODE == 'ja' %}{{ post.title_ja }}{% else %}{{ post.title }}{% endif %}
+ {{ post.title }}
</h1>
<div class="weblog-details">
<div class="author-info">
@@ -24,7 +24,7 @@
{% endwith %}
<a href="#"> {{ post.author.first_name }} {{ post.author.last_name }}</a>
<span>{% if request.LANGUAGE_CODE == 'ja' %}投稿カテゴリー:{% else %}posted in{% endif %}</span>
- <a href="#{{ post.category.slug }}">{% if request.LANGUAGE_CODE == 'ja' %}{{ post.category.name_ja }}{% else %}{{ post.category }}{% endif %}</a>
+ <a href="#{{ post.category.slug }}">{{ post.category.name }}</a>
<span>{% if request.LANGUAGE_CODE == 'ja' %}投稿日:{% else %}on{% endif %}</span>
<span style="margin-left: 4px;">{% localtime on %}{{ post.date | date:"M d, Y" }}{% endlocaltime %}</span>
</div>
@@ -39,7 +39,7 @@
{{ post.first_paragraph | safe }}
</div>
<div class="weblog-image">
- <img src="{{ post.image_url }}" alt="{% if request.LANGUAGE_CODE == 'ja' %}{{ post.title_ja }}{% else %}{{ post.title }}{% endif %}">
+ <img src="{{ post.image_url }}" alt="{{ post.title }}">
</div>
<div class="weblog-content" id="weblog-body-content">
{{ post.body | safe }}
@@ -48,10 +48,21 @@
<div class="post-tags">
{% if request.LANGUAGE_CODE == 'ja' %}タグ: {% else %}Tagged with: {% endif %}
{% for tag in post.tags.all %}
- <a class="post-tag" href="#{{ tag.slug }}">{% if request.LANGUAGE_CODE == 'ja' %}{{ tag.name_ja }}{% else %}{{ tag.name }}{% endif %}</a>
+ <a class="post-tag" href="#{{ tag.slug }}">{{ tag.name }}</a>
{% endfor %}
</div>
</div>
+ <div class="comments-section" id="comments">
+ <h2>{% if request.LANGUAGE_CODE == 'ja' %}コメント{% else %}Comments{% endif %}</h2>
+ {% for comment in post.comments.all %}
+ {% if not comment.parent %}
+ {% include 'partials/_comment.html' with comment=comment %}
+ {% endif %}
+ {% endfor %}
+ {% if post.comments.all|length == 0 %}
+ <p>{% if request.LANGUAGE_CODE == 'ja' %}コメントはありません。{% else %}No comments yet.{% endif %}</p>
+ {% endif %}
+ </div>
</div>
{% endblock content %}
{% block scripts %}
@@ -91,5 +102,13 @@
output: 'html'
});
}
+
+ function showReplyForm(commentId) {
+ document.getElementById(`reply-form-${commentId}`).style.display = 'block';
+ }
+
+ function hideReplyForm(commentId) {
+ document.getElementById(`reply-form-${commentId}`).style.display = 'none';
+ }
</script>
{% endblock scripts %} \ No newline at end of file