Changelog

4.0.0

This update alters fields on MentionableMixin so you will need to run makemigrations and migrate after upgrading!

Wiki pages are now live! These will be kept up-to-date going forwards but may not be useful for pre-4.0 versions.

Changes
MentionableMixin:
  • allow_outgoing_webmentions default now configurable via settings.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 methodall_text, replaced by get_content_html. Overriding all_text still works for now but will log a warning asking you to rename the method.
Misc
  • Moved template files to mentions sub-directory. If you have custom overrides of these templates in your root templates/ directory please move them to templates/mentions/.
  • Admin-facing strings are now translatable.
  • Fix: Relative URLs in h-card homepage or avatar are now resolved to absolute URLs.
New stuff
urlpatterns helper functions

Added urlpatterns helper functions mentions_path, mentions_re_path for (hopefully) simpler setup. See the wiki for examples. - More straightforward view-to-model mapping. - Removes the need to implement resolve_from_url_kwargs on your MentionableMixin implementation.

Wagtail support

See the wiki for setup instructions: tl;dr. - Page models should implement MentionableMixin as usual. - RoutablePageMixin should use the new @mentions_wagtail_path, @mentions_wagtail_re_path decorators in place of the Wagtail equivalents @path, @re_path.

Misc

Added user agent header to all network requests, customisable via settings.WEBMENTIONS_USER_AGENT: str.

3.1.1

Fixes #43: outgoing webmention being resubmitted continuously.

3.1.0

  • 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 links in HTTP header.

  • Added settings.WEBMENTIONS_INCOMING_TARGET_MODEL_REQUIRED [bool | default=False]. If True, incoming mentions are only accepted if their target resolves to a MentionableMixin instance.

  • Added settings.WEBMENTIONS_ALLOW_SELF_MENTIONS [bool | default=True].

    • If False, outgoing links that target your own domain (as specified by settings.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.
  • Fix: WebmentionHeadMiddleware no longer overwrites existing links in HTTP header when adding webmention endpoint.

  • Fix: Webmention ’notes’ no longer persists across instances.

2.3.0

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.

2.2.0

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.

2.1.0

  • Added setting WEBMENTIONS_USE_CELERY (boolean, default True)
    If False:
    • celery does not need to be installed
    • New models PendingIncomingWebmention and PendingOutgoingContent 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 value webmention or simple so they can be differentiated when displaying.
  • Updated instructions for installation with or without celery.

2.0.0

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 to 5.2.2 due to CVE-2021-23727. If you are upgrading from 4.x please follow the upgrade instructions provided by Celery.

Web API changes:

  • /get endpoint:
    • Removed status from JSON object - now uses HTTP response codes 200 if the target url was resolved correctly or 404 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"
      }
    ]
  }

New

  • Use{% webmention_endpoint %} template tag to include your Webmentions endpoint in your Django template to help other sites find it easily.
    {% load webmention_endpoint %}
    <!-- my-template.html -->
    ...
    <head>
    {% webmention_endpoint %} <!-- Rendered as <link rel="webmention" href="/webmention/" /> -->
    </head>
    ...
    

1.2.2

Incoming webmentions may now target any path, not just those that map directly to a mentionable model.

1.0.3

The app is now detected correctly by makemigrations

1.0.1

First release on PyPI