为Wagtail提供AMP网页故事支持
项目描述
wagtail-webstories
此软件包为Wagtail添加了对AMP网页故事的支持。可以在原始URL位置链接或嵌入其他地方创建的故事,或将故事作为Wagtail页面导入,包括可选地将图片和视频导入Wagtail媒体库。
wagtail-webstories
与Wagtail 4.1及以上版本兼容。
安装
使用pip安装
pip install wagtail-webstories
添加到INSTALLED_APPS
INSTALLED_APPS = [
# ...
'wagtail_webstories',
# ...
]
运行迁移
./manage.py migrate
嵌入和链接外部故事
要将网页故事嵌入到基于StreamField的常规(非AMP)页面中,请将wagtail_webstories.blocks.ExternalStoryEmbedBlock
块类型包含在您的StreamField定义中
from wagtail_webstories.blocks import ExternalStoryEmbedBlock
class BlogPage(Page):
body = StreamField([
('heading', blocks.CharBlock()),
('paragraph', blocks.RichTextBlock()),
('story_embed', ExternalStoryEmbedBlock()),
])
此块允许页面作者提供AMP网络故事的URL,该URL将在前端模板(使用{% include_block %}
)上渲染为<amp-story-player>
元素;您的模板应包含渲染此内容的必要脚本,以及一个CSS规则来指定适当的尺寸
<script async src="https://cdn.ampproject.org/amp-story-player-v0.js"></script>
<link href="https://cdn.ampproject.org/amp-story-player-v0.css" rel="stylesheet" type="text/css">
<style>
amp-story-player { width: 360px; height: 600px; }
</style>
要包含指向故事的链接而不是嵌入它,可以使用wagtail_webstories.blocks.ExternalStoryBlock
代替ExternalStoryEmbedBlock
。默认模板wagtail_webstories/blocks/external_story_poster_link.html
输出故事的“卡片”渲染,使用故事的封面图片,需要使用以下CSS
.webstory-poster {
display: block; width: 300px; height: 400px; border-radius: 15px; background-size: cover; position: relative;
}
.webstory-poster .webstory-info {
position: absolute; bottom: 0; width: 100%; background-color: #ccc; color: black; border-bottom-left-radius: 15px; border-bottom-right-radius: 15px;
}
.webstory-poster .title {
font-size: 1.5em; padding: 10px;
}
.webstory-poster .publisher {
padding: 0 10px 20px 10px;
}
.webstory-poster .publisher img {
vertical-align: middle;
}
在没有StreamField的情况下嵌入和链接外部故事
外部故事通过模型wagtail_webstories.models.ExternalStory
处理。要为给定的URL获取ExternalStory实例,使用:ExternalStory.get_for_url(story_url)
。故事元数据在ExternalStory模型中缓存,以避免每次请求都需要重新获取故事 - 可用的元数据字段有url
、title
、publisher
、publisher_logo_src
、poster_portrait_src
、poster_square_src
和poster_landscape_src
。
StreamField块模板wagtail_webstories/blocks/external_story_embed_block.html
和wagtail_webstories/blocks/external_story_poster_link.html
可用于渲染ExternalStory对象,通过将变量story
传递给它
# models.py
class BlogPostWithStoryPage(Page):
story_url = model.URLField(max_length=2048)
def get_context(self, request):
context = super().get_context(request)
context['story_obj'] = ExternalStory.get_for_url(self.story_url)
return context
{# blog_post_with_story_page.html #}
{% include "wagtail_webstories/blocks/external_story_embed_block.html" with story=story_obj %}
导入
要允许将故事作为Wagtail页面导入,定义一个扩展wagtail_webstories.models.BaseWebStoryPage
的模型
from wagtail_webstories.models import BaseWebStoryPage
class StoryPage(BaseWebStoryPage):
pass
或者,如果您的项目有一个所有页面类型都必须继承的现有基础页面类(这将防止在基础类中使用BaseWebStoryPage),则扩展wagtail_webstories.models.WebStoryPageMixin
并定义content_panels
和promote_panels
以包含其面板定义
from wagtail_webstories.models import WebStoryPageMixin
class StoryPage(WebStoryPageMixin, BasePage):
content_panels = BasePage.content_panels + WebStoryPageMixin.web_story_content_panels
promote_panels = BasePage.promote_panels + WebStoryPageMixin.web_story_promote_panels
现在创建一个相应的模板,该模板扩展wagtail_webstories/base_web_story_page.html
{% extends "wagtail_webstories/base_web_story_page.html" %}
定义一个设置WAGTAIL_WEBSTORIES_IMPORT_MODEL
,指向要使用的页面模型
WAGTAIL_WEBSTORIES_IMPORT_MODEL = 'myapp.StoryPage'
这将现在在Wagtail管理菜单中添加一个“Web故事”项,允许您通过URL导入故事。
HTML清理
默认情况下,在导入和保存时,所有不允许的AMP网络故事规范的HTML元素和属性将被删除。要禁用此功能,将WAGTAIL_WEBSTORIES_CLEAN_HTML
设置为False
WAGTAIL_WEBSTORIES_CLEAN_HTML = False
图像导入
默认情况下,导入的故事中的图像引用保留在其原始URL上。BaseWebStoryPage提供了一个方法import_images()
来获取所有引用的图像并将它们导入Wagtail图像库,如果它们已经存在则去重。建议您从post_save
信号处理程序中调用此方法
# myapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import StoryPage
@receiver(post_save, sender=StoryPage)
def import_story_images(sender, instance, **kwargs):
changed = instance.import_images()
if changed:
instance.save()
# myapp/apps.py
from django.apps import AppConfig
class MyappConfig(AppConfig):
name = 'myapp'
def ready(self):
import myapp.signals # noqa
# myapp/__init__.py
default_app_config = 'myapp.apps.MyappConfig'
由于导入图像可能是一个耗时的过程,您可能希望将import_images
的调用卸载到Celery或类似的后台任务中,以避免这阻止了Web服务器线程。
要自定义新图像的创建(例如,将导入的图像分配给特定的集合,或在自定义图像模型上填充额外的元数据字段),则覆盖故事页面模型中的_create_image
方法
class StoryPage(BaseWebStoryPage):
def _create_image(self, file, title=None):
image = super()._create_image(file, title=title)
image.copyright = "All rights reserved"
return image
视频导入
如果您已安装wagtailmedia,则可以类似地通过调用import_videos()
将视频导入本地媒体库。上面的信号处理程序变为
# myapp/signals.py
@receiver(post_save, sender=StoryPage)
def import_story_images(sender, instance, **kwargs):
images_changed = instance.import_images()
videos_changed = instance.import_videos()
if images_changed or videos_changed:
instance.save()
链接和嵌入导入的故事
要将导入的Web故事嵌入或链接到常规(非AMP)基于StreamField的页面,请在StreamField定义中包含wagtail_webstories.blocks.StoryEmbedBlock
或wagtail_webstories.blocks.StoryChooserBlock
块类型。这些与ExternalStoryEmbedBlock和ExternalStoryBlock类似,但为页面作者提供了一个页面选择器界面,而不是URL字段。
from wagtail_webstories.blocks import StoryEmbedBlock
class BlogPage(Page):
body = StreamField([
('heading', blocks.CharBlock()),
('paragraph', blocks.RichTextBlock()),
('local_story_embed', StoryEmbedBlock(target_model=StoryPage)),
])
target_model
参数是可选的 - 默认情况下,任何继承自BaseWebStoryPage的页面类型都可以选择。与ExternalStoryEmbedBlock和ExternalStoryBlock一样,您的页面模板必须包含适当的JavaScript或CSS包含,用于渲染块。
模板 wagtail_webstories/blocks/story_poster_link.html
和 wagtail_webstories/blocks/story_embed_block.html
预期一个名为 page
的变量,该变量包含故事页面实例,因此这些模板也可以在 StreamField 之外使用。
# models.py
class StoryIndexPage(Page):
def get_context(self, request):
context = super().get_context(request)
context['stories'] = StoryPage.objects.child_of(self).live().order_by('-first_published_at')
return context
{# story_index_page.html #}
{% for story in stories %}
{% include "wagtail_webstories/blocks/story_poster_link.html" with page=story %}
{% endfor %}
项目详情
下载文件
下载适合您平台的文件。如果您不确定该选择哪个,请了解有关 安装包 的更多信息。
源分发
构建分发
wagtail-webstories-0.1.1.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | d7e71438d3628d4c4da4df28019079cc2dc99215b82187ab81aff5305df00f05 |
|
MD5 | bf96854d58db3ea2f34c55be4d3c48b1 |
|
BLAKE2b-256 | e3e69e632fdff01e7fd34c71ed57b245db97bdb9fe1f351f8e0fa933f3d6370a |
wagtail_webstories-0.1.1-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 1689c738ec7ee8d6eaeb2183563f96a5b2efaf2ad90034a5d40d8a6ba23aa401 |
|
MD5 | ecb188391057da71d6bdb9ff195904a0 |
|
BLAKE2b-256 | a68dba8c6eee4d25a44f5f065850dcf467c957f32adba0716e14464b7b4d490d |