如何在 Wagtail 中创建块/模板/片段?

问题描述 投票:0回答:1

需要指导,文档不够清楚,所以我提出这个问题。我想使用类似于 slick-slider 的 coderedcms 实现作为基础来制作自定义轮播(参考网站:www.fcs.mg.gov.br)。我认为这是一件绝对简单的事情,但我现在才刚刚学习 Wagtail。基本上创建一个自定义块,向其中添加模板并将其注册为片段,以便可以重用。一个关于这些文件的树的样子的例子也很棒。谢谢。

python wagtail wagtail-snippet
1个回答
0
投票

我希望您使用比示例更轻的图像 😉 ...其中一些幻灯片图像有 5+MB ...40MB 页面大小! 本文档将指导如何在模板中使用图像过滤器来减小尺寸、设置质量(即压缩)并选择较轻的图像类型(将图像转换为 webp 等)。显示大小应不超过 30-40kB 左右。

有多种方法可以解决此用例。

您是否希望在多个页面上使用相同的图像集合并从一个点集中管理,以便任何更改都反映在整个站点范围内?

如果是的话 - 注册一个片段模型将是可行的方法。我将为此使用 ClusterableModel/Orderable 设置,以便您可以控制图像显示的顺序。 这个文档就是一个例子,其中每个图像都是一个可排序的实例(示例中的

BandMember
,每个图像集合都是一个
Band
)。

要将画廊实例链接到页面模型,您需要创建一个标准 DjangoForeignKey 字段,如下所示:

slider = models.ForeignKey(
    "your_gallery_app_name.YourGalleryModel",
    null=True,
    blank=False,
    related_name="+",
    on_delete=models.SET_NULL,
    verbose_name=_("Slider Gallery"),
)

在页面的

panels
部分,您只需要为此字段添加一个标准
FieldPanel

如果您希望代码可重用,但每个页面都应该有一个唯一的图像集合,那么您还有两个选择:

  1. 每页只有一个画廊,总是显示在同一个地方
  2. 每页可以没有画廊,也可以有多个画廊,位置可以改变。

选项 1 - 您只需要上面讨论的可订购课程,而不需要

ClusterableModel
。相反,您只需要
Orderable
和链接回您的
ParentalKey
类型的
Page
。如果图库中的每个项目都是带有其他字段的图像,则它将类似于:

class CarouselImages(Orderable):
    from django.db import models
    from modelcluster.fields import ParentalKey
    from wagtail.fields import RichTextField

    page = ParentalKey("your_page_app.YourPageModel", related_name="carousel_images")
    carousel_image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name="Image",
    )
    caption = RichTextField(null=True, blank=True)
    some_date = models.DateTimeField(
        null=True, blank=True, help_text="Some helpful text"
    )
    some_text = models.CharField(max_length=255, default="some default value")
    some_text_area = models.TextField(default="some default value")
    some_choice_field = models.CharField(
        max_length=255,
        default="a",
        choices=[("a", "Choice A"), ("b", "Choice B"), ("c", "Choice C")],
    )

    panels = [
        FieldPanel("carousel_image"),
        FieldPanel("caption"),
        FieldPanel("some_date"),
        FieldPanel("some_text"),
        FieldPanel("some_text_area"),
        FieldPanel("some_choice_field"),
    ]

    class Meta(Orderable.Meta):
        verbose_name = _("Carousel Image")

注意

related_name
中的
ParentalKey
属性。在您的页面模型上,您不需要为图库添加字段,只需将 InlinePanel 添加到面板部分并使用此 related_name:

    MultiFieldPanel(
        [InlinePanel("carousel_images", max_num=5, min_num=2)],
        heading="Carousel Images",
    ),

您可以如上所述设置最小和最大图像,或者保留其中一个或两个。

完成此操作后,您将在页面编辑器中看到“轮播图像”字段,您可以在其中添加图像和其他属性。在您的模板中,您可以通过 self.carousel_images 访问图库,例如

{% for img in self.carousel_images %}
    ....
{% endfor %}

选项 2,您可以没有画廊,也可以在页面上的不同位置拥有多个画廊,您可以创建一对自定义 StructBlock(画廊项目和画廊各一个),并将画廊块添加到页面的 StreamField。例如

from django.utils.translation import gettext_lazy as _
from wagtail.blocks import (CharBlock, ListBlock,
                            PageChooserBlock, StructBlock, TextBlock)
from wagtail.images.blocks import ImageChooserBlock

class CarouselImageBlock(StructBlock):
    image = ImageChooserBlock(label=_("Select Image & Enter Details"))
    title = CharBlock(label=_("Optional Image Title"), required=False)
    caption = TextBlock(label=_("Optional Image Caption"), required=False)
    link = PageChooserBlock(
        required=False,
        label=_("Optional Link to Internal Page")
    )

    class Meta:
        icon = 'image'
        label = _("Image for Carousel")


class ImageCarouselBlock(StructBlock):
    heading = CharBlock(
        label=_("Carousel Title"),
        required=False,
    )
    carousel_images = ListBlock(CarouselImageBlock, min_num=2, max_num=5)

    class Meta:
        template = 'blocks/image_carousel.html'
        icon = "image-carousel"
        label = _("Image Carousel")
        label_format = label

template = 'blocks/image_carousel.html' 将指向块渲染模板,您可以在其中迭代与上面相同的项目,例如:

{% for slide in self.carousel_images %}
    ....
{% endfor %}

还有其他选择,但其中之一可能会满足您的需求。

© www.soinside.com 2019 - 2024. All rights reserved.