Repository navigation
Callbacks
Use import paths in COMMENTAIL; see Configuration. Avoid slow
remote work in render callbacks. No callback should return credentials or private text.
-
CAPTCHA_BACKEND: an import path to a class with no-argument construction.create(request, site) -> CaptchaTaskandverify(request, site, challenge_id: str, answer: str) -> bool. ImportCaptchaTaskfromcommentail.security:idis a string/UUID identifier (up to 255 characters),templateis a resolvable template name,datais a dictionary of public string values. Keep answers/private provider state on the server. The template receivescaptcha.data; its form control submitsanswer. The library issues a separate browser ID and sends the original provider ID only to verification. Site/session binding, expiry, attempts, refresh invalidation, creation quotas and successful single use remain enforced by the library. The backend owns expiry/cleanup of any separate private provider state. Changing the backend invalidates prior tasks; provider errors fail closed with neutral UI messages.Noneuses arithmetic. -
GET_AVATAR:get_avatar(context, request) -> str | None, returning an image URL or using generated initials/gradient. FrozenCommentContextcontainsid,display_name,user,site,target, without guest email/internal Comment. -
GET_AUTHOR_NAME:get_author_name(user, request) -> str, for the registered author's current name. Name/avatar failures fall back to library defaults. -
GET_COMMENT_TEMPLATES:get_comment_templates(page, request) -> list[str], enumerating dynamic dependencies. Presence of the widget tag still controls connection. Resolver failures are diagnosed without breaking the page editor. -
CAN_SEND_GUEST_EMAIL:can_send_guest_email(recipient, target, site) -> bool, proving guest access to restricted pages and registered non-Page objects without a browser request. A failure denies delivery and becomes a job error.GuestRecipientcontainsemail,name,confirmed_at; the latter can beNonefor verification mail.
from django.http import HttpRequest
from commentail.avatars import CommentContext
def get_avatar(context: CommentContext, request: HttpRequest) -> str | None:
if context.user is None:
return None
profile = getattr(context.user, "profile", None)
image = getattr(profile, "avatar", None)
return image.url if image else NoneAdapt attributes to your user model. None uses deterministic initials/gradient;
callback errors fall back. The enhanced widget shows initials for broken image URLs.
Guest email is not in the context. Registered names are current; guest names stay
as submitted.
Return template-name strings such as articles/discussion.html from
GET_COMMENT_TEMPLATES(page, request). The actual template still needs the widget
tag; the callback does not enable comments by itself.
CAN_SEND_GUEST_EMAIL must prove recipient access without a browser session.
Return False unless your entitlement rules authorize the recipient for this exact
target and Site. Do not use unconditional True for private content. Public Pages
need no special callback; registered non-Page objects require it for guest mail.
Implement a no-argument backend with the documented create/verify methods. The
public template posts answer and preserves the hidden challenge field. Keep all
solutions and private provider state server-side. Library proof constraints wrap
custom backends; your backend cleans up its own extra state. A backend change
invalidates previously issued tasks. Arithmetic CAPTCHA alone is not strong bot detection.
- Home
- Installation
- Configuration
- Moderation
- Rules and CSV
- Guest comments
- Replies and editing
- Email and worker
- Styling
- Templates
- Recent comments
- Structured data
- Callbacks
- Object adapters
- Security and privacy
- Deployment
- Performance
- Troubleshooting
- Example and testing
- Release 0.1.0
- Release 0.1.1
- Release 0.2.0
- Stability
- Template contract
- Release 1.0.0
- Release 1.1.0
- Release 1.2.0
- Changelog
- Roadmap
- Support