Home page can now host richt content

This commit is contained in:
Konstantin 2024-04-05 19:03:18 +02:00
parent 9b4bb6c9f1
commit 38733808ed
7 changed files with 191 additions and 5 deletions

View file

@ -1,4 +1,4 @@
from wagtail.blocks import RichTextBlock from wagtail.blocks import RichTextBlock, BlockQuoteBlock
from wagtail.embeds.blocks import EmbedBlock from wagtail.embeds.blocks import EmbedBlock
from base.blocks import StreamBlock, HeadingBlock, ImageBlock from base.blocks import StreamBlock, HeadingBlock, ImageBlock
@ -6,6 +6,7 @@ from wagtailcodeblock.blocks import CodeBlock
class BlogPostBlock(StreamBlock): class BlogPostBlock(StreamBlock):
heading_block = HeadingBlock() heading_block = HeadingBlock()
blockquote = BlockQuoteBlock()
paragraph = RichTextBlock(blank=True) paragraph = RichTextBlock(blank=True)
code = CodeBlock(label='Code snippet') code = CodeBlock(label='Code snippet')
image_block = ImageBlock() image_block = ImageBlock()

View file

@ -0,0 +1,22 @@
# Generated by Django 5.0.2 on 2024-04-05 16:56
import wagtail.blocks
import wagtail.embeds.blocks
import wagtail.fields
import wagtail.images.blocks
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('blog', '0013_alter_blogpage_body'),
]
operations = [
migrations.AlterField(
model_name='blogpage',
name='body',
field=wagtail.fields.StreamField([('heading_block', wagtail.blocks.StructBlock([('heading_text', wagtail.blocks.CharBlock(form_classname='title', required=True)), ('size', wagtail.blocks.ChoiceBlock(blank=True, choices=[('', 'Select a heading size'), ('h2', 'H2'), ('h3', 'H3'), ('h4', 'H4')], required=False))])), ('blockquote', wagtail.blocks.BlockQuoteBlock()), ('paragraph', wagtail.blocks.RichTextBlock(blank=True)), ('code', wagtail.blocks.StructBlock([('language', wagtail.blocks.ChoiceBlock(choices=[('bash', 'Bash/Shell'), ('css', 'CSS'), ('dart', 'Dart'), ('docker', 'Docker'), ('elixir', 'Elixir'), ('go', 'Go'), ('html', 'HTML'), ('javascript', 'Javascript'), ('json', 'JSON'), ('kotlin', 'Kotlin'), ('python', 'Python'), ('rust', 'Rust'), ('swift', 'Swift'), ('toml', 'TOML'), ('yaml', 'YAML')], help_text='Coding language', identifier='language', label='Language')), ('code', wagtail.blocks.TextBlock(identifier='code', label='Code'))], label='Code snippet')), ('image_block', wagtail.blocks.StructBlock([('image', wagtail.images.blocks.ImageChooserBlock(required=True)), ('caption', wagtail.blocks.CharBlock(required=False)), ('attribution', wagtail.blocks.CharBlock(required=False))])), ('embed_block', wagtail.embeds.blocks.EmbedBlock(help_text='Insert a URL to embed. For example, https://www.youtube.com/watch?v=SGJFWirQ3ks', icon='media'))], blank=True, help_text='Write anything'),
),
]

View file

@ -14,6 +14,7 @@ from wagtail.snippets.models import register_snippet
from blog.blocks import BlogPostBlock from blog.blocks import BlogPostBlock
from wagtailseo.models import SeoMixin, SeoType from wagtailseo.models import SeoMixin, SeoType
class BlogIndexPage(SeoMixin, Page): class BlogIndexPage(SeoMixin, Page):
intro = RichTextField(blank=True) intro = RichTextField(blank=True)
@ -29,6 +30,7 @@ class BlogIndexPage(SeoMixin, Page):
] ]
promote_panels = SeoMixin.seo_panels promote_panels = SeoMixin.seo_panels
class BlogTagIndexPage(Page): class BlogTagIndexPage(Page):
def get_context(self, request): def get_context(self, request):
@ -40,6 +42,7 @@ class BlogTagIndexPage(Page):
context['blogpages'] = blogpages context['blogpages'] = blogpages
return context return context
class BlogPageTag(TaggedItemBase): class BlogPageTag(TaggedItemBase):
content_object = ParentalKey( content_object = ParentalKey(
'BlogPage', 'BlogPage',
@ -47,6 +50,7 @@ class BlogPageTag(TaggedItemBase):
on_delete=models.CASCADE on_delete=models.CASCADE
) )
class BlogPage(SeoMixin, Page): class BlogPage(SeoMixin, Page):
date = models.DateField("Post date") date = models.DateField("Post date")
intro = models.TextField() intro = models.TextField()
@ -104,6 +108,7 @@ class BlogPageGalleryImage(Orderable):
FieldPanel('caption'), FieldPanel('caption'),
] ]
@register_snippet @register_snippet
class Author(models.Model): class Author(models.Model):
name = models.CharField(max_length=255) name = models.CharField(max_length=255)
@ -121,4 +126,4 @@ class Author(models.Model):
return self.name return self.name
class Meta: class Meta:
verbose_name_plural = 'Authors' verbose_name_plural = 'Authors'

16
home/blocks.py Normal file
View file

@ -0,0 +1,16 @@
from wagtail.blocks import RichTextBlock, BlockQuoteBlock
from wagtail.embeds.blocks import EmbedBlock
from base.blocks import StreamBlock, HeadingBlock, ImageBlock
from wagtailcodeblock.blocks import CodeBlock
class HomeContentBlock(StreamBlock):
heading_block = HeadingBlock()
paragraph = RichTextBlock(blank=True)
code = CodeBlock(label='Code snippet')
blockquote = BlockQuoteBlock()
image_block = ImageBlock()
embed_block = EmbedBlock(
help_text="Insert a URL to embed. For example, https://www.youtube.com/watch?v=SGJFWirQ3ks",
icon="media",
)

View file

@ -0,0 +1,136 @@
# Generated by Django 5.0.2 on 2024-04-05 16:56
import json
import wagtail.blocks
import wagtail.embeds.blocks
import wagtail.fields
import wagtail.images.blocks
from django.core.serializers.json import DjangoJSONEncoder
from django.db import migrations
def convert_to_streamfield(apps, schema_editor):
HomePage = apps.get_model("home", "HomePage")
for page in HomePage.objects.all():
page.body = json.dumps(
[{"type": "paragraph", "value": page.body}],
cls=DjangoJSONEncoder
)
page.save()
def convert_to_richtext(apps, schema_editor):
HomePage = apps.get_model("home", "HomePage")
for page in HomePage.objects.all():
if page.body:
stream = json.loads(page.body)
page.body = "".join([
child["value"] for child in stream
if child["type"] == "paragraph"
])
page.save()
class Migration(migrations.Migration):
dependencies = [
('home', '0005_homepage_canonical_url_homepage_og_image_and_more'),
]
operations = [
migrations.RunPython(
convert_to_streamfield,
convert_to_richtext,
),
migrations.AlterField(
model_name='homepage',
name='body',
field=wagtail.fields.StreamField([('heading_block', wagtail.blocks.StructBlock(
[('heading_text', wagtail.blocks.CharBlock(form_classname='title', required=True)), ('size',
wagtail.blocks.ChoiceBlock(
blank=True,
choices=[('',
'Select a heading size'),
('h2',
'H2'),
('h3',
'H3'),
('h4',
'H4')],
required=False))])),
('paragraph', wagtail.blocks.RichTextBlock(blank=True)), ('code',
wagtail.blocks.StructBlock(
[(
'language',
wagtail.blocks.ChoiceBlock(
choices=[
(
'bash',
'Bash/Shell'),
(
'css',
'CSS'),
(
'dart',
'Dart'),
(
'docker',
'Docker'),
(
'elixir',
'Elixir'),
(
'go',
'Go'),
(
'html',
'HTML'),
(
'javascript',
'Javascript'),
(
'json',
'JSON'),
(
'kotlin',
'Kotlin'),
(
'python',
'Python'),
(
'rust',
'Rust'),
(
'swift',
'Swift'),
(
'toml',
'TOML'),
(
'yaml',
'YAML')],
help_text='Coding language',
identifier='language',
label='Language')),
('code',
wagtail.blocks.TextBlock(
identifier='code',
label='Code'))],
label='Code snippet')),
('blockquote', wagtail.blocks.BlockQuoteBlock()), ('image_block',
wagtail.blocks.StructBlock(
[('image',
wagtail.images.blocks.ImageChooserBlock(
required=True)),
('caption',
wagtail.blocks.CharBlock(
required=False)),
('attribution',
wagtail.blocks.CharBlock(
required=False))])),
('embed_block', wagtail.embeds.blocks.EmbedBlock(
help_text='Insert a URL to embed. For example, https://www.youtube.com/watch?v=SGJFWirQ3ks',
icon='media'))], blank=True, help_text='Write anything'),
),
]

View file

@ -1,9 +1,10 @@
from django.db import models from django.db import models
from wagtail.models import Page from wagtail.models import Page
from wagtail.fields import RichTextField from wagtail.fields import RichTextField, StreamField
from wagtail.admin.panels import FieldPanel, MultiFieldPanel from wagtail.admin.panels import FieldPanel, MultiFieldPanel
from wagtailseo.models import SeoMixin from wagtailseo.models import SeoMixin
from .blocks import HomeContentBlock
class HomePage(SeoMixin, Page): class HomePage(SeoMixin, Page):
@ -34,7 +35,12 @@ class HomePage(SeoMixin, Page):
verbose_name="Hero CTA link", verbose_name="Hero CTA link",
help_text="Choose a page to link to for the Call to Action", help_text="Choose a page to link to for the Call to Action",
) )
body = RichTextField(blank=True) body = StreamField(
HomeContentBlock(),
blank=True,
use_json_field=True,
help_text="Write anything",
)
content_panels = Page.content_panels + [ content_panels = Page.content_panels + [
MultiFieldPanel( MultiFieldPanel(

View file

@ -19,7 +19,7 @@
<section class="max-w-7xl px-0 md:px-4 lg:px-8"> <section class="max-w-7xl px-0 md:px-4 lg:px-8">
<div class="w-full px-2 lg:px-4"> <div class="w-full px-2 lg:px-4">
{{ page.body|richtext }} {{ page.body }}
</div> </div>
</section> </section>