Lesson 15 / 22 · Commentail 1.3.2
Callbacks are functions in your project that Commentail invokes for host-specific behavior. Configure import-path strings rather than calling the functions in settings.
Names and avatars
Create myproject/comments.py, substituting your actual importable project package:
def get_author_name(user, request):
"""Use the account's chosen full name, then its login name."""
return user.get_full_name().strip() or user.get_username()
def get_avatar(context, request):
"""Read the host project's optional profile avatar."""
if context.user is None:
return None
profile = getattr(context.user, "profile", None)
image = getattr(profile, "avatar", None)
return image.url if image else None
def get_comment_templates(page, request):
"""Declare the actual dynamic include used by the host Page template."""
return ["articles/discussion.html"]
The naming example expects User methods get_full_name() and get_username(). The avatar assumes an existing profile.avatar; it does not create profiles. Adapt the field names to your model. Avoid remote HTTP requests while rendering each card.
COMMENTAIL = {
"default": {
"GET_AUTHOR_NAME": "myproject.comments.get_author_name",
"GET_AVATAR": "myproject.comments.get_avatar",
"GET_COMMENT_TEMPLATES": "myproject.comments.get_comment_templates",
},
}
The name callback changes registered-author display; guest names stay as submitted. Avatar context contains id, display_name, user, site and target, without guest email. Returning None keeps generated initials. Callback errors fall back to library defaults.
Declare dynamic dependencies
Use the third callback only when a Page chooses discussion templates dynamically and ordinary detection cannot find them. Create the actual templates/articles/discussion.html containing {% load commentail_tags %} and {% commentail page %}, and include it from the Page template. The callback alone does not render a widget. Remove it and its setting when no dynamic dependency exists.
Prove offline guest access
CAN_SEND_GUEST_EMAIL(recipient, target, site) proves access when the worker has no browser session. Public Wagtail Pages need no special callback. Restricted Pages require your actual entitlement rule, such as a valid subscription. Never return unconditional True. Lesson 17 gives a concrete implementation for public non-Page objects.
A custom CAPTCHA backend
A no-argument class implements create(request, site) returning CaptchaTask from commentail.security, and verify(request, site, challenge_id, answer) returning bool. The task contains a string ID of up to 255 characters, a template name and public string data. Keep answers and secrets server-side; the template submits answer.
The library enforces browser/Site binding, expiry, attempts and single use. Your backend owns any extra private state and cleanup. This route is for a real verifiable provider; an always-True teaching implementation would disable protection. Read the exact contract and constraints before implementing one.
Related lessons
- 13. Override templates and action pages
- 16. Languages and multiple Wagtail Sites
- 17. Comments on products and other Django models
Choose a sign-in method or comment as a guest below.