57 lines
1.6 KiB
Python
57 lines
1.6 KiB
Python
from typing import Iterator
|
|
|
|
from django.utils import lorem_ipsum
|
|
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_PLAINTEXT_BLOCKS = (blocks.RawHTMLBlock, EmbedBlock)
|
|
|
|
|
|
class LoremBlock(blocks.StructBlock):
|
|
paragraphs = blocks.IntegerBlock(min_value=1)
|
|
|
|
def render(self, value: dict, context: dict | None = None) -> str:
|
|
return format_html_join(
|
|
"\n\n",
|
|
"<p>{}</p>",
|
|
[(paragraph,) for paragraph in lorem_ipsum.paragraphs(value["paragraphs"])],
|
|
)
|
|
|
|
class Meta:
|
|
icon = "openquote"
|
|
label = "Lorem Ipsum"
|
|
|
|
|
|
def get_blocks() -> list[tuple[str, blocks.BaseBlock]]:
|
|
return [
|
|
("embed", EmbedBlock()),
|
|
("rich_text", blocks.RichTextBlock()),
|
|
("lorem", LoremBlock()),
|
|
("html", blocks.RawHTMLBlock()),
|
|
]
|
|
|
|
|
|
def get_plain_text(value: blocks.StreamValue) -> Iterator[str]:
|
|
for block in value:
|
|
if isinstance(block.block_type, IGNORE_PLAINTEXT_BLOCKS):
|
|
continue
|
|
yield strip_tags(str(block))
|
|
|
|
|
|
def truncate_streamfield(value: blocks.StreamValue, words: int) -> str:
|
|
collected_words: list[str] = []
|
|
for block_text in get_plain_text(value):
|
|
collected_words.extend(smart_split(block_text))
|
|
if len(collected_words) >= words:
|
|
break
|
|
|
|
return " ".join(collected_words[:words])
|
|
|
|
|
|
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
|