Changelog
[!WARNING]
python manage.py migrate
required for new fields.
Added
Webmention.has_been_read: bool
field.- New context processor
mentions.context_processors.unread_webmentions
addsunread_webmentions
field to template context, containing the queryset of unread Webmention objects. - Added admin actions for marking as read/unread.
- New context processor
New
objects
manager for Webmention with some common filters and actions.New settings for allowing or disabling webmentions to/from a set of domains:
New settings for tags that can be added to your HTML links to allow/disable sending webmentions for just that specific link. (Overrides above allow/deny lists)
Resolves #53: Compatibility with dependency mf2py>=2.0
.
- Resolves #50: broken search field on QuotableAdmin.
- Added tests for admin pages to avoid that sort of thing happening again.
- Minor touch-ups for the admin pages.
- Source and target URL fields are now read-only.
- Added appropriate search fields and list filters for each model.
quote
field now uses a textarea widget for comfier editing.
Added management command
mentions_reverify [filters ...] [--all]
- Allows you to reprocess received Webmentions to see if they are still ‘live’.
- Accepts a space-separated list of
field=value
queryset filters, or--all
to reprocess all of them.
Added management command
mentions_pending
to replacepending_mentions
for naming consistency with other commands.pending_mentions
still works though.
Now compatible with
Wagtail>=3.0.3
(previously>=4.0
).mentions_wagtail_path
still requires>=4.0
: usementions_wagtail_route
ormentions_wagtail_re_path
.
This update alters fields on
MentionableMixin
so you will need to runmakemigrations
andmigrate
after upgrading!
MentionableMixin
:allow_outgoing_webmentions
default now configurable viasettings.WEBMENTIONS_ALLOW_OUTGOING_DEFAULT
.Removed
slug
field. If you use this field you can restore the previous behaviour by adding the following to your model.class MyModel(MentionableMixin, models.Model): slug = models.SlugField(unique=True) @classmethod def resolve_from_url_kwargs(cls, slug, **url_kwargs): return cls.objects.get(slug=slug)
Deprecated method
all_text
, replaced byget_content_html
. Overridingall_text
still works for now but will log a warning asking you to rename the method.
Moved template files to
mentions
sub-directory. If you have custom overrides of these templates in your roottemplates/
directory please move them totemplates/mentions/
.Added user agent header to all network requests.
- Customisable via
settings.WEBMENTIONS_USER_AGENT: str
.
- Customisable via
Admin-facing strings are now translatable.
Added
urlpatterns
helper functionsmentions_path
,mentions_re_path
for (hopefully) simpler setup.- More straightforward view-to-model mapping.
- Removes the need to implement
resolve_from_url_kwargs
on your MentionableMixin implementation. - See the wiki for example setup instructions.
Support for Wagtail.
Page
models should implementMentionableMixin
as usual.RoutablePageMixin
should use the new@mentions_wagtail_path
,@mentions_wagtail_re_path
decorators in place of the Wagtail equivalents@path
,@re_path
.- These work essentially the same
mentions_path
andmentions_re_path
.
- These work essentially the same
If using RichTextField call
richtext
on any RichTextField values inget_content_html
:from wagtail.templatetags.wagtailcore_tags import richtext class MyModel(MentionableMixin, Page): ... def get_content_html(self) -> str: return f"{richtext(self.overview)} {richtext(self.body)}"
Wiki pages are now live! These will be kept up-to-date going forwards but may not be useful for pre-4.0 versions.
Fix: Relative URLs in
h-card
homepage or avatar are now resolved to absolute URLs.
Fixes #43: outgoing webmention being resubmitted continuously.
Resolves #38: Revalidate target URLs when handling pending mentions
- Should be unnecessary generally (they are also validated at discovery time when parsed from HTML) but important if validation checks are updated.
Resolves #41: Find correct endpoint when multiple
link
s in HTTP header.Added
settings.WEBMENTIONS_INCOMING_TARGET_MODEL_REQUIRED
[bool
| default=False
]. IfTrue
, incoming mentions are only accepted if their target resolves to aMentionableMixin
instance.Added
settings.WEBMENTIONS_ALLOW_SELF_MENTIONS
[bool
| default=True
].- If
False
, outgoing links that target your own domain (as specified bysettings.DOMAIN_NAME
) will be ignored - you will only submit mentions to other domains. - If
True
, outgoing links that use a relative path (e.g.href="/article/1/"
) are now supported.
- If
Fix: WebmentionHeadMiddleware no longer overwrites existing links in HTTP header when adding webmention endpoint.
Fix: Webmention ’notes’ no longer persists across instances.
Upgrade warning
If upgrading from an older version please be aware of these changes:
- Unused
MentionableMixin.allow_incoming_webmentions
field has been removed. - Any existing instances of
PendingIncomingWebmention
andPendingOutgoingContent
will be deleted.- These models have new constraints so it is necessary to recreate them.
- If this is problematic for you please don’t upgrade yet. Contact me or create an issue and I will make a tool to persist these between versions.
Changes
Thanks to @philgyford for reporting most of the issues referenced here.
Resolves #25.
Added
QuotableMixin.post_type
field.Incoming webmentions are now checked for the following microformat properties that describe the type of mention they are:
u-bookmark-of
u-like-of
u-listen-of
u-in-reply-to
u-repost-of
u-translation-of
u-watch-of
The
/webmention/get
endpoint serializes these values in thetype
field respectively as:bookmark
like
listen
reply
repost
translation
watch
- If no specific
type
is specified this defaults towebmention
.
Resolves #30
- Added
MentionableMixin.should_process_webmentions() -> bool
method to enable custom logic.
- Added
Resolves #31
- Success message now rendered via template, enabling override by user.
Resolves #32
- Same-page #anchor links no longer treated as webmention targets.
-
- Much improved parsing of
h-card
.- Now tries to find an
h-card
that is directly related to the mention link (embedded inp-author
of a parenth-entry
orh-feed
container). - If that doesn’t yield a result, try to find a top-level
h-card
on the page.
- Now tries to find an
- Removed
HCard.from_soup()
classmethod. Parsing logic moved totasks.incoming.parsing
package.
- Much improved parsing of
Resolves #36
- Added constraints to
PendingIncomingWebmention
andPendingOutgoingContent
to avoid duplication.- Warning: If updating from an older version of
django-wm
this will delete any existingPending...
model instances.
- Warning: If updating from an older version of
- Request timeouts are now handled gracefully.
PendingIncomingWebmention
andOutgoingWebmentionStatus
now implement the newRetryableMixin
.- Reworked webmention processing tasks to allow failed webmentions to be retried periodically.
- See settings
WEBMENTIONS_MAX_RETRIES
,WEBMENTIONS_RETRY_INTERVAL
,WEBMENTIONS_TIMEOUT
below for customisation details.
- See settings
- Added constraints to
New
dashboard/
view: a simple overview of recent mentions.- Shows the latest instances of
Webmention
,OutgoingWebmentionStatus
,PendingIncomingWebmention
,PendingOutgoingContent
and info on their current status. - By default, restricted to users with
mentions.view_webmention_dashboard
permission. - Can be made public via
settings.WEBMENTIONS_DASHBOARD_PUBLIC = True
.
- Shows the latest instances of
New optional settings:
settings.WEBMENTIONS_TIMEOUT
[float
| default=10
] specifies the time (in seconds) to wait for network calls to resolve.settings.WEBMENTIONS_RETRY_INTERVAL
[int
| default=600
] specifies the minimum time (in seconds) to wait before retrying to process a webmention.settings.WEBMENTIONS_MAX_RETRIES
[int
| default=5
] specifies how many times we can attempt to process a mention before giving up.settings.WEBMENTIONS_DASHBOARD_PUBLIC
[bool
| default=False
] specifies whether the thedashboard/
view can be viewed by anyone. IfFalse
(default), thedashboard/
view is only available to users withmentions.view_webmention_dashboard
permission.
WebmentionHeadMiddleware
- Removed port from generated endpoint URL in HTTP headers as
request.META.SERVER_PORT
may not be reliable depending on reverse proxy configuration.
- Removed port from generated endpoint URL in HTTP headers as
MentionableMixin
:mentions()
is now a method, not a property.- Removed field
allow_incoming_webmentions
as it has never been used for anything.
Streamlined template tags
{% load webmentions_endpoint %}
replaced by{% load webmentions %}
.{% webmention_endpoint %}
replaced by{% webmentions_endpoint %}
(used in HTML<head>
).- New tag
{% webmentions_dashboard %}
creates a link to yourwebmentions/dashboard/
view.
Resolves #28
New MentionableMixin classmethod: resolve_from_url_kwargs(**url_kwargs)
- This method receives captured parameters from an urlpatterns
path.
- By default, it uses <slug:slug>
to look up your object by a unique
slug
field.
- You can customize this by overriding the classmethod in your
MentionableMixin implementation
e.g.
# urls.py
urlpatterns = [
path(
fr"<int:year>/<int:month>/<int:day>/<slug:post_slug>/",
MyBlogPostView.as_view(),
name="my-blog",
kwargs={
"model_name": "myapp.MyBlog",
},
),
]
# models.py
class MyBlog(MentionableMixin, models.Model):
date = models.DateTimeField(default=timezone.now)
slug = models.SlugField()
content = models.TextField()
def all_text(self):
return self.content
def get_absolute_url(self):
return reverse(
"my-blog",
kwargs={
"year": self.date.strftime("%Y"),
"month": self.date.strftime("%m"),
"day": self.date.strftime("%d"),
"post_slug": self.slug,
}
)
@classmethod
def resolve_from_url_kwargs(cls, year, month, day, post_slug, **url_kwargs):
return cls.objects.get(
date__year=year,
date__month=month,
date__day=day,
slug=post_slug,
)
mentions.resolution.get_model_for_url_path
now delegates to
MentionableMixin.resolve_from_url_kwargs
to resolve captured URL parameters to a model instance.
Merges #24: QuotableMixin.published can now be overriden - thanks @garrettc.
Fixes #26: requests
2.20 or greater (until version 3) are now allowed. Likewise for beautifulsoup4
4.6 and mf2py
1.1.
Added get_mentions_for_view(HttpRequest) -> Iterable[QuotableMixin]
convenience method. This may be used to retrieve mentions for rendering directly in a Django template, as an alternative to using the webmention/get
endpoint from a frontend script.
- Added setting
WEBMENTIONS_USE_CELERY
(boolean, defaultTrue
)
IfFalse
:celery
does not need to be installed- New models
PendingIncomingWebmention
andPendingOutgoingContent
are created to store the required data for later batch-processing. - New management command:
manage.py pending_mentions
can be used to process these data.
/get
endpoint:- Now returns results for SimpleMention objects as well as Webmentions.
- Added field
type
with valuewebmention
orsimple
so they can be differentiated when displaying.
Updated instructions for installation with or without celery.
Breaking Changes
Migrations are now included. If you are upgrading from any
1.x.x
version please follow these instructions to avoid data loss. Thanks to **@GriceTurrble for providing these instructions.requirements.txt
celery
version updated to5.2.2
due to CVE-2021-23727. If you are upgrading from4.x
please follow the upgrade instructions provided by Celery.
Web API changes:
/get
endpoint:- Removed
status
from JSON object - now uses HTTP response codes200
if the target url was resolved correctly or404
otherwise. - Missing HCards are now serialized as null instead of an empty dict
// https://example.org/webmention/get?url=my-article // Old 1.x.x response { "status": 1, "target_url": "https://example.org/my-article", "mentions": [ { "hcard": {}, "quote": null, "source_url": "https://another-example.org/their-article", "published": "2020-01-17T21:45:24.542Z" } ] }
// https://example.org/webmention/get?url=my-article // New 2.0.0 response with HTTP status 200 (or 404 if target_url does not exist) { "target_url": "https://example.org/my-article", "mentions": [ { "hcard": null, "quote": null, "source_url": "https://another-example.org/their-article", "published": "2020-01-17T21:45:24.542Z" } ] }
- Removed
New
- Use
{% webmention_endpoint %}
template tag to include your Webmentions endpoint in your Django template to help other sites find it easily.{% load webmentionendpoint %} <!– my-template.html –> … <head> <!– Rendered as <link rel="webmention" href="/webmention/" /> –> {% webmentionendpoint %} </head> …
Incoming webmentions may now target any path, not just those that map directly to a mentionable model.
makemigrations