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): title = models.TextField() rank = models.PositiveSmallIntegerField( default=1, validators=[ MinValueValidator(1), MaxValueValidator(6) ] ) class Meta: verbose_name = "Heading" def __str__(self): return Truncator(self.title).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
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.0rc1.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | e332ade801c93091fdd4abf7257f7045c462efd7e5862940cc3dc9487fd83914 |
|
MD5 | 535e8c6bde0a56a5ea277f5e865e59fa |
|
BLAKE2b-256 | a95a22ebcda6a9749583e7d4e1b8ea1bdfcb0f7a2a3c6cd7106de2408d01fc1a |
Hashes for paper_streamfield-0.5.0rc1-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6b1a0ebaf563b522671974318444e5cead51ce12888eace73e002fb5eea1edb4 |
|
MD5 | f1426e3d61433b9851d204bafac6c22d |
|
BLAKE2b-256 | 4969d7e854cd6053d21e840c95bee394c0a8b678d2edb0a2b5509f258dba851d |