django-wm

Automatic Webmention functionality for Django models

Changelog

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.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.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.0.1

First release on PyPI

1.0.3

The app is now detected correctly by makemigrations

1.2.2

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

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.

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.

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.