Wagtail supports generating embed code from URLs to content on external providers such as Youtube or Twitter. By default, Wagtail will fetch the embed code directly from the relevant provider’s site using the oEmbed protocol.
Wagtail has a built-in list of the most common providers and this list can be changed with a setting. Wagtail also supports fetching embed code using Embedly and custom embed finders.
Wagtail’s embeds module should work straight out of the box for most providers. You can use any of the following methods to call the module:
Wagtail’s default rich text editor has a “media” icon that allows embeds to be placed into rich text. You don’t have to do anything to enable this; just make sure the rich text field’s content is being passed through the |richtext
filter in the template as this is what calls the embeds module to fetch and nest the embed code.
EmbedBlock
StreamField block typeThe EmbedBlock
block type allows embeds to be placed into a StreamField
.
The max_width
and max_height
arguments are sent to the provider when fetching the embed code.
For example:
from wagtail.embeds.blocks import EmbedBlock class MyStreamField(blocks.StreamBlock): ... embed = EmbedBlock(max_width=800, max_height=400)
{% embed %}
tagSyntax: {% embed <url> [max_width=<max width>] %}
You can nest embeds into a template by passing the URL and an optional max_width
argument to the {% embed %}
tag.
The max_width
argument is sent to the provider when fetching the embed code.
{% load wagtailembeds_tags %} {# Embed a YouTube video #} {% embed 'https://www.youtube.com/watch?v=Ffu-2jEdLPw' %} {# This tag can also take the URL from a variable #} {% embed page.video_url %}
You can also call the internal get_embed
function that takes a URL string and returns an Embed
object (see model documentation below). This also takes a max_width
keyword argument that is sent to the provider when fetching the embed code.
from wagtail.embeds.embeds import get_embed from wagtail.embeds.exceptions import EmbedException try: embed = get_embed('https://www.youtube.com/watch?v=Ffu-2jEdLPw') print(embed.html) except EmbedException: # Cannot find embed pass
Embed finders are the modules within Wagtail that are responsible for producing embed code from a URL.
Embed finders are configured using the WAGTAILEMBEDS_FINDERS
setting. This is a list of finder configurations that are each run in order until one of them successfully returns an embed:
The default configuration is:
WAGTAILEMBEDS_FINDERS = [ { 'class': 'wagtail.embeds.finders.oembed' } ]
The default embed finder fetches the embed code directly from the content provider using the oEmbed protocol. Wagtail has a built-in list of providers which are all enabled by default. You can find that provider list at the following link:
https://github.com/wagtail/wagtail/blob/main/wagtail/embeds/oembed_providers.py
You can limit which providers may be used by specifying the list of providers in the finder configuration.
For example, this configuration will only allow content to be nested from Vimeo and Youtube. It also adds a custom provider:
from wagtail.embeds.oembed_providers import youtube, vimeo # Add a custom provider # Your custom provider must support oEmbed for this to work. You should be # able to find these details in the provider's documentation. # - 'endpoint' is the URL of the oEmbed endpoint that Wagtail will call # - 'urls' specifies which patterns my_custom_provider = { 'endpoint': 'https://customvideosite.com/oembed', 'urls': [ '^http(?:s)?://(?:www\\.)?customvideosite\\.com/[^#?/]+/videos/.+$', ] } WAGTAILEMBEDS_FINDERS = [ { 'class': 'wagtail.embeds.finders.oembed', 'providers': [youtube, vimeo, my_custom_provider], } ]
Multiple finders can be chained together. This can be used for customising the configuration for one provider without affecting the others.
For example, this is how you can instruct Youtube to return videos in HTTPS (which must be done explicitly for YouTube):
from wagtail.embeds.oembed_providers import youtube WAGTAILEMBEDS_FINDERS = [ # Fetches YouTube videos but puts ``?scheme=https`` in the GET parameters # when calling YouTube's oEmbed endpoint { 'class': 'wagtail.embeds.finders.oembed', 'providers': [youtube], 'options': {'scheme': 'https'} }, # Handles all other oEmbed providers the default way { 'class': 'wagtail.embeds.finders.oembed', } ]
If multiple providers can handle a URL (for example, a YouTube video was requested using the configuration above), the topmost finder is chosen to perform the request.
Wagtail will not try to run any other finder, even if the chosen one didn’t return an embed.
As of October 2020, Facebook deprecated their public oEmbed APIs. If you would like to embed Facebook or Instagram posts in your site, you will need to use the new authenticated APIs. This requires you to set up a Facebook Developer Account and create a Facebook App that includes the oEmbed Product. Instructions for creating the necessary app are in the requirements sections of the Facebook and Instagram documentation.
As of June 2021, the oEmbed Product has been replaced with the oEmbed Read feature. In order to embed Facebook and Instagram posts your app must activate the oEmbed Read feature. Furthermore the app must be reviewed and accepted by Facebook. You can find the announcement in the API changelog.
Apps that activated the oEmbed Product before June 8, 2021 need to activate the oEmbed Read feature and review their app before September 7, 2021.
Once you have your app access tokens (App ID and App Secret), add the Facebook and/or Instagram finders to your WAGTAILEMBEDS_FINDERS
setting and configure them with the App ID and App Secret from your app:
WAGTAILEMBEDS_FINDERS = [ { 'class': 'wagtail.embeds.finders.facebook', 'app_id': 'YOUR FACEBOOK APP_ID HERE', 'app_secret': 'YOUR FACEBOOK APP_SECRET HERE', }, { 'class': 'wagtail.embeds.finders.instagram', 'app_id': 'YOUR INSTAGRAM APP_ID HERE', 'app_secret': 'YOUR INSTAGRAM APP_SECRET HERE', }, # Handles all other oEmbed providers the default way { 'class': 'wagtail.embeds.finders.oembed', } ]
By default, Facebook and Instagram embeds include some JavaScript that is necessary to fully render the embed. In certain cases, this might not be something you want - for example, if you have multiple Facebook embeds, this would result in multiple script tags. By passing 'omitscript': True
in the configuration, you can indicate that these script tags should be omitted from the embed HTML. Note that you will then have to take care of loading this script yourself.
Embed.ly is a paid-for service that can also provide embeds for sites that do not implement the oEmbed protocol.
They also provide some helpful features such as giving embeds a consistent look and a common video playback API which is useful if your site allows videos to be hosted on different providers and you need to implement custom controls for them.
Wagtail has built in support for fetching embeds from Embed.ly. To use it, first pip install the Embedly
python package.
Now add an embed finder to your WAGTAILEMBEDS_FINDERS
setting that uses the wagtail.embeds.finders.oembed
class and pass it your API key:
WAGTAILEMBEDS_FINDERS = [ { 'class': 'wagtail.embeds.finders.embedly', 'key': 'YOUR EMBED.LY KEY HERE' } ]
For complete control, you can create a custom finder class.
Here’s a stub finder class that could be used as a skeleton; please read the docstrings for details of what each method does:
from wagtail.embeds.finders.base import EmbedFinder class ExampleFinder(EmbedFinder): def __init__(self, **options): pass def accept(self, url): """ Returns True if this finder knows how to fetch an embed for the URL. This should not have any side effects (no requests to external servers) """ pass def find_embed(self, url, max_width=None): """ Takes a URL and max width and returns a dictionary of information about the content to be used for embedding it on the site. This is the part that may make requests to external APIs. """ # TODO: Perform the request return { 'title': "Title of the content", 'author_name': "Author name", 'provider_name': "Provider name (such as YouTube, Vimeo, etc)", 'type': "Either 'photo', 'video', 'link' or 'rich'", 'thumbnail_url': "URL to thumbnail image", 'width': width_in_pixels, 'height': height_in_pixels, 'html': "<h2>The Embed HTML</h2>", }
Once you’ve implemented all of those methods, you just need to add it to your WAGTAILEMBEDS_FINDERS
setting:
WAGTAILEMBEDS_FINDERS = [ { 'class': 'path.to.your.finder.class.here', # Any other options will be passed as kwargs to the __init__ method } ]
Embed
modelAs long as your embeds configuration is not broken, deleting items in the Embed
model should be perfectly safe to do. Wagtail will automatically repopulate the records that are being used on the site.
You may want to do this if you’ve changed from oEmbed to Embedly or vice-versa as the embed code they generate may be slightly different and lead to inconsistency on your site.
© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/stable/advanced_topics/embeds.html