Humanize reading time
This commit is contained in:
parent
2dd660ed13
commit
710a4c7955
11 changed files with 36 additions and 27 deletions
|
@ -16,3 +16,4 @@ psycopg2
|
|||
djangorestframework
|
||||
django-htmx
|
||||
wagtail-metadata
|
||||
humanize
|
||||
|
|
|
@ -28,6 +28,7 @@ draftjs-exporter==2.1.7 # via wagtail
|
|||
et-xmlfile==1.1.0 # via openpyxl
|
||||
gunicorn==20.1.0 # via -r requirements/base.in
|
||||
html5lib==1.1 # via wagtail
|
||||
humanize==4.3.0 # via -r requirements/base.in
|
||||
idna==3.3 # via requests
|
||||
l18n==2021.3 # via wagtail
|
||||
lxml==4.9.1 # via -r requirements/base.in
|
||||
|
|
|
@ -40,6 +40,7 @@ flake8==4.0.1 # via -r requirements/dev.in
|
|||
gunicorn==20.1.0 # via -r requirements/base.txt
|
||||
honcho==1.1.0 # via -r requirements/dev.in
|
||||
html5lib==1.1 # via -r requirements/base.txt, wagtail
|
||||
humanize==4.3.0 # via -r requirements/base.txt
|
||||
idna==3.3 # via -r requirements/base.txt, requests
|
||||
isort==5.10.1 # via -r requirements/dev.in
|
||||
l18n==2021.3 # via -r requirements/base.txt, wagtail
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import math
|
||||
from datetime import timedelta
|
||||
from typing import Any, Optional
|
||||
|
||||
from django.db import models
|
||||
|
@ -68,11 +68,18 @@ class BaseContentPage(BasePage, MetadataMixin):
|
|||
return get_table_of_contents(self.content_html)
|
||||
|
||||
@cached_property
|
||||
def reading_time(self) -> int:
|
||||
def reading_time(self) -> timedelta:
|
||||
"""
|
||||
https://help.medium.com/hc/en-us/articles/214991667-Read-time
|
||||
"""
|
||||
return int(math.ceil(self.word_count / 265))
|
||||
return timedelta(seconds=(self.word_count / 265) * 60)
|
||||
|
||||
@cached_property
|
||||
def show_reading_time(self) -> bool:
|
||||
"""
|
||||
Only show reading time if it's longer than 2 minutes
|
||||
"""
|
||||
return self.reading_time.total_seconds() >= 120
|
||||
|
||||
@cached_property
|
||||
def word_count(self) -> int:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% load wagtailcore_tags %}
|
||||
{% load wagtailcore_tags humanize_tags %}
|
||||
|
||||
<div class="content-details field is-grouped is-grouped-multiline {{extra_classes}}">
|
||||
|
||||
|
@ -11,11 +11,11 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if page.reading_time %}
|
||||
{% if page.show_reading_time %}
|
||||
<div class="control">
|
||||
<div class="tags has-addons">
|
||||
<span class="tag is-dark"><i class="far fa-clock"></i></span>
|
||||
<span class="tag is-light" title="{{ page.word_count }} words">{{ page.reading_time }} minutes</span>
|
||||
<span class="tag is-light" title="{{ page.word_count }} words">{{ page.reading_time|naturaldelta }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
{% extends "wagtailmetadata/parts/tags.html" %}
|
||||
|
||||
{% load humanize_tags %}
|
||||
|
||||
{% block twitter %}
|
||||
{{ block.super }}
|
||||
{% if object.reading_time %}
|
||||
{% if object.show_reading_time %}
|
||||
<meta name="twitter:label1" content="Reading time" />
|
||||
<meta name="twitter:data1" content="{{ object.reading_time }} minutes" />
|
||||
<meta name="twitter:data1" content="{{ object.reading_time|naturaldelta }}" />
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -41,11 +41,8 @@ class ContactPage(BaseContentPage):
|
|||
subpage_types: list = []
|
||||
|
||||
@cached_property
|
||||
def reading_time(self) -> int:
|
||||
"""
|
||||
How does one read a list page?
|
||||
"""
|
||||
return 0
|
||||
def show_reading_time(self) -> bool:
|
||||
return False
|
||||
|
||||
@cached_property
|
||||
def table_of_contents(self) -> list[TocEntry]:
|
||||
|
|
|
@ -24,11 +24,8 @@ class SearchPage(RoutablePageMixin, BaseContentPage):
|
|||
PAGE_SIZE = 15
|
||||
|
||||
@cached_property
|
||||
def reading_time(self) -> int:
|
||||
"""
|
||||
How does one read a search page?
|
||||
"""
|
||||
return 0
|
||||
def show_reading_time(self) -> bool:
|
||||
return False
|
||||
|
||||
@cached_property
|
||||
def table_of_contents(self) -> list[TocEntry]:
|
||||
|
|
|
@ -33,6 +33,7 @@ INSTALLED_APPS = [
|
|||
"website.images",
|
||||
"website.contact",
|
||||
"website.spotify",
|
||||
"website.utils",
|
||||
"website.contrib.code_block",
|
||||
"website.contrib.mermaid_block",
|
||||
"website.contrib.unsplash",
|
||||
|
|
|
@ -35,15 +35,11 @@ class SpotifyPlaylistPage(BaseContentPage):
|
|||
return []
|
||||
|
||||
@cached_property
|
||||
def reading_time(self) -> int:
|
||||
return int(
|
||||
timedelta(
|
||||
milliseconds=sum(
|
||||
track["track"]["duration_ms"]
|
||||
for track in self.playlist_data["tracks"]
|
||||
)
|
||||
).total_seconds()
|
||||
/ 60
|
||||
def reading_time(self) -> timedelta:
|
||||
return timedelta(
|
||||
milliseconds=sum(
|
||||
track["track"]["duration_ms"] for track in self.playlist_data["tracks"]
|
||||
)
|
||||
)
|
||||
|
||||
@cached_property
|
||||
|
|
6
website/utils/templatetags/humanize_tags.py
Normal file
6
website/utils/templatetags/humanize_tags.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
import humanize
|
||||
from django.template import Library
|
||||
|
||||
register = Library()
|
||||
|
||||
register.filter(humanize.naturaldelta)
|
Loading…
Reference in a new issue