Implementation of the Wagtail's StreamField block picker for paper-admin.
Project description
paper-streamfield
Implementation of the Wagtail's StreamField block picker for paper-admin.
Compatibility
python
>= 3.8django
>= 3.1paper-admin
>= 6.0
Installation
Install the latest release with pip:
pip install paper-streamfield
Add streamfield
to your INSTALLED_APPS in django's settings.py
:
INSTALLED_APPS = (
# other apps
"streamfield",
)
Add streamfield.urls
to your URLconf:
urlpatterns = patterns('',
...
path("streamfields/", include("streamfield.urls")),
)
How to use
-
Create some models that you want to use as blocks:
# blocks/models.py from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.utils.text import Truncator class HeadingBlock(models.Model): text = models.TextField() rank = models.PositiveSmallIntegerField( default=1, validators=[ MinValueValidator(1), MaxValueValidator(6) ] ) class Meta: verbose_name = "Heading" def __str__(self): return Truncator(self.text).chars(128) class TextBlock(models.Model): text = models.TextField() class Meta: verbose_name = "Text" def __str__(self): return Truncator(self.text).chars(128)
-
Register your models using
StreamBlockModelAdmin
class.# blocks/admin.py from django.contrib import admin from streamfield.admin import StreamBlockModelAdmin from .models import HeadingBlock, TextBlock @admin.register(HeadingBlock) class HeadingBlockAdmin(StreamBlockModelAdmin): list_display = ["__str__", "rank"] @admin.register(TextBlock) class TextBlockAdmin(StreamBlockModelAdmin): pass
-
Create templates for each block model, named as lowercase model name or snake_cased model name.
<!-- blocks/templates/blocks/headingblock.html --> <!-- or --> <!-- blocks/templates/blocks/heading_block.html --> <h{{ block.rank }}>{{ block.text }}</h{{ block.rank }}>
<!-- blocks/templates/blocks/textblock.html --> <!-- or --> <!-- blocks/templates/blocks/text_block.html --> <div>{{ block.text|linebreaks }}</div>
-
Add a
StreamField
to your model:# app/models.py from django.db import models from django.utils.translation import gettext_lazy as _ from streamfield.field.models import StreamField class Page(models.Model): stream = StreamField( _("stream"), models=[ "blocks.HeaderBlock", "blocks.TextBlock", ] ) class Meta: verbose_name = "Page"
Result:
Now you can create some blocks:
-
Use
render_stream
template tag to render the stream field.<!-- app/templates/index.html --> {% load streamfield %} {% render_stream page.stream %}
Result:
Special cases
Use custom template name or template engine
If you need to use custom template name or template engine, you can specify
You can specify a template name or engine to render a specific block
with StreamBlockMeta
class in your block model:
class HeadingBlock(models.Model):
# ...
class StreamBlockMeta:
engine = "jinja2"
template = "blocks/heading.html"
Add extra context
You can add extra context to the template by passing
additional keyword arguments to render_stream
template tag:
<!-- blocks/templates/blocks/textblock.html -->
<div class="{{ classes }}">{{ block.text|linebreaks }}</div>
<!-- app/templates/index.html -->
{% load streamfield %}
{% render_stream page.stream classes="text text--small" %}
Access parent context from within a block
In some cases you need to access the parent context from the block template.
You can access the parent context from the block template by using
parent_context
variable:
<!-- blocks/templates/blocks/textblock.html -->
<div class="{{ parent_context.classes }}">{{ block.text|linebreaks }}</div>
<!-- app/templates/index.html -->
{% load streamfield %}
<!-- Add classes to the page context -->
{% with classes="text text--small" %}
{% render_stream page.stream %}
{% endwith %}
Customize block in admin interface
You can customize how a block is rendered in the admin interface
by specifying stream_block_template
field in the StreamBlockModelAdmin
class:
from django.contrib import admin
from streamfield.admin import StreamBlockModelAdmin
from .models import ImageBlock
@admin.register(ImageBlock)
class ImageBlockAdmin(StreamBlockModelAdmin):
stream_block_template = "blocks/admin/image.html"
list_display = ["__str__", "title", "alt"]
<!-- blocks/admin/image.html -->
{% extends "streamfield/admin/block.html" %}
{% block content %}
<div class="d-flex">
<div class="flex-grow-0 mr-2">
<img class="preview"
src="{{ instance.image }}"
width="48"
height="36"
title="{{ instance.title }}"
alt="{{ instance.alt }}"
style="object-fit: cover">
</div>
{{ block.super }}
</div>
{% endblock content %}
Caching the rendered HTML of a block
You can cache the rendered HTML of a block by using CacheRenderer
class:
class HeadingBlock(models.Model):
# ...
class StreamBlockMeta:
renderer = "streamfield.renderers.CacheRenderer"
cache_ttl = 3600
Note that the specified block will not be invalidated when something changes in it.
Settings
PAPER_STREAMFIELD_DEFAULT_RENDERER
Default renderer for render_stream
template tag.
Default: "streamfield.renderers.DefaultRenderer"
PAPER_STREAMFIELD_DEFAULT_TEMPLATE_ENGINE
Default template engine for render_stream
template tag.
Default: None
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for paper_streamfield-0.5.0-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 09d33eb20c23b0a6c996520a99655c50e25ed0be5e3fc74b6f9e433d8cba119f |
|
MD5 | afacfd89292bbe4ab42196bfb302dc0c |
|
BLAKE2b-256 | 4e47d4e6357975871c2a700919d1c835333639e399c7f88aac42dab4e4b354dc |