Add basic word count and reading time
This commit is contained in:
parent
1a8821eaa8
commit
299a6342cc
2 changed files with 28 additions and 5 deletions
|
@ -1,3 +1,4 @@
|
|||
import math
|
||||
from typing import Any
|
||||
|
||||
from django.db import models
|
||||
|
@ -8,7 +9,7 @@ from wagtail.fields import StreamField
|
|||
from wagtail.images import get_image_model_string
|
||||
from wagtail.models import Page
|
||||
|
||||
from .streamfield import get_blocks
|
||||
from .streamfield import get_blocks, get_word_count
|
||||
from .utils import TocEntry, get_table_of_contents
|
||||
|
||||
|
||||
|
@ -53,11 +54,14 @@ class BaseContentMixin(models.Model):
|
|||
|
||||
@cached_property
|
||||
def reading_time(self) -> int:
|
||||
return 4
|
||||
"""
|
||||
https://help.medium.com/hc/en-us/articles/214991667-Read-time
|
||||
"""
|
||||
return int(math.ceil(self.word_count / 265))
|
||||
|
||||
@cached_property
|
||||
def word_count(self) -> int:
|
||||
return 1600
|
||||
return get_word_count(self.body)
|
||||
|
||||
|
||||
class ContentPage(BasePage, BaseContentMixin): # type: ignore[misc]
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
from typing import Iterator
|
||||
|
||||
from django.utils import lorem_ipsum
|
||||
from django.utils.html import format_html_join
|
||||
from django.utils.html import format_html_join, strip_tags
|
||||
from django.utils.text import smart_split
|
||||
from wagtail import blocks
|
||||
from wagtail.embeds.blocks import EmbedBlock
|
||||
|
||||
IGNORE_WORDCOUNT_BLOCKS = (blocks.RawHTMLBlock, EmbedBlock)
|
||||
|
||||
|
||||
class LoremBlock(blocks.StructBlock):
|
||||
paragraphs = blocks.IntegerBlock(min_value=1)
|
||||
|
||||
def render(self, value: dict, context: dict) -> str:
|
||||
def render(self, value: dict, context: dict | None = None) -> str:
|
||||
return format_html_join(
|
||||
"\n\n",
|
||||
"<p>{}</p>",
|
||||
|
@ -26,3 +31,17 @@ def get_blocks() -> list[tuple[str, blocks.BaseBlock]]:
|
|||
("lorem", LoremBlock()),
|
||||
("html", blocks.RawHTMLBlock()),
|
||||
]
|
||||
|
||||
|
||||
def get_plain_text(value: blocks.StreamValue) -> Iterator[str]:
|
||||
for block in value:
|
||||
if isinstance(block.block_type, IGNORE_WORDCOUNT_BLOCKS):
|
||||
continue
|
||||
yield strip_tags(str(block))
|
||||
|
||||
|
||||
def get_word_count(value: blocks.StreamValue) -> int:
|
||||
count = 0
|
||||
for chunk in get_plain_text(value):
|
||||
count += len(list(smart_split(chunk)))
|
||||
return count
|
||||
|
|
Loading…
Reference in a new issue