{"result":{"depiction_url":null,"edges":{"observes":{"objects":[{"created":"2026-09-09T13:47:45Z","object_id":{"id":1273,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_rsc_pivot_done","title":"observe_rsc_pivot_done\/2","uri":"https:\/\/zotonic.com\/id\/1273"},"seq":1},{"created":"2026-09-09T13:47:45Z","object_id":{"id":1466,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_admin_menu","title":"observe_admin_menu\/3","uri":"https:\/\/zotonic.com\/id\/1466"},"seq":2},{"created":"2026-09-09T13:47:45Z","object_id":{"id":1468,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_acl_is_allowed","title":"observe_acl_is_allowed\/2","uri":"https:\/\/zotonic.com\/id\/1468"},"seq":3},{"created":"2026-09-29T13:07:38Z","object_id":{"id":1816,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_email_failed","title":"observe_email_failed\/2","uri":"https:\/\/zotonic.com\/id\/1816"},"seq":4},{"created":"2026-09-09T13:47:45Z","object_id":{"id":1982,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_search_query","title":"observe_search_query\/2","uri":"https:\/\/zotonic.com\/id\/1982"},"seq":5},{"created":"2026-09-29T13:07:38Z","object_id":{"id":2105,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_email_bounced","title":"observe_email_bounced\/2","uri":"https:\/\/zotonic.com\/id\/2105"},"seq":6},{"created":"2026-09-29T13:07:38Z","object_id":{"id":2108,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_email_sent","title":"observe_email_sent\/2","uri":"https:\/\/zotonic.com\/id\/2108"},"seq":7},{"created":"2026-09-09T13:47:45Z","object_id":{"id":2122,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_mailinglist_message","title":"observe_mailinglist_message\/2","uri":"https:\/\/zotonic.com\/id\/2122"},"seq":8}],"predicate":{"id":2550,"is_a":["meta","predicate"],"name":"observes","title":{"_type":"trans","tr":{"en":"Observes"}},"uri":"https:\/\/zotonic.com\/id\/observes"}},"references":{"objects":[{"created":"2020-05-30T05:47:25Z","object_id":{"id":1552,"is_a":["text","documentation","developerguide"],"name":"doc_developerguide_email","title":{"_type":"trans","tr":{"en":"Configure outbound email and verify delivery"}},"uri":"https:\/\/zotonic.com\/id\/1552"},"seq":1000000},{"created":"2020-05-30T05:47:25Z","object_id":{"id":1395,"is_a":["text","documentation","reference","template_scomp"],"name":"doc_template_scomp_scomp_mailinglist_subscribe","title":"mailinglist_subscribe","uri":"https:\/\/zotonic.com\/id\/1395"},"seq":1000000}],"predicate":{"id":332,"is_a":["meta","predicate"],"name":"references","title":{"_type":"trans","tr":{"en":"References"}},"uri":"https:\/\/zotonic.com\/id\/references"}},"refers":{"objects":[{"created":"2026-09-09T13:47:45Z","object_id":{"id":1395,"is_a":["text","documentation","reference","template_scomp"],"name":"doc_template_scomp_scomp_mailinglist_subscribe","title":"mailinglist_subscribe","uri":"https:\/\/zotonic.com\/id\/1395"},"seq":1000000}],"predicate":{"id":2409,"is_a":["meta","predicate"],"name":"refers","title":{"_type":"trans","tr":{"en":"Refers"}},"uri":"https:\/\/zotonic.com\/id\/refers"}},"subject":{"objects":[{"created":"2026-09-09T13:47:45Z","object_id":{"id":2555,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/2555"},"seq":1},{"created":"2026-09-09T13:47:45Z","object_id":{"id":2561,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_content_editor","title":"Content editor","uri":"https:\/\/zotonic.com\/id\/2561"},"seq":2},{"created":"2026-09-09T13:47:45Z","object_id":{"id":2597,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_mailing_lists","title":"Mailing lists","uri":"https:\/\/zotonic.com\/id\/2597"},"seq":3},{"created":"2026-09-09T13:47:45Z","object_id":{"id":2635,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_module","title":"Module","uri":"https:\/\/zotonic.com\/id\/2635"},"seq":4},{"created":"2026-09-09T13:47:45Z","object_id":{"id":2654,"is_a":["categorization","keyword","keyword_task"],"name":"zotonic_topic_send_and_receive","title":"Send and receive","uri":"https:\/\/zotonic.com\/id\/2654"},"seq":5}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":1465,"is_a":["text","documentation","reference","module"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1465"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_module_mod_mailinglist","page_url":{"en":"https:\/\/zotonic.com\/docs\/1465\/mod_mailinglist","x-default":"https:\/\/zotonic.com\/docs\/1465\/mod_mailinglist"},"preview_url":null,"resource":{"version":4045,"pivot_location_lat":null,"title":"mod_mailinglist","is_authoritative":true,"body":"<p>This module implements a mailing list system. You can make as many mailing lists as you like and send any page to any\nmailing list, including confirm mail and unsubscribe page.<\/p>\n<p>Mailing lists are pages of the category mailinglist, which is installed by the module upon activation. In the admin\nthere is support for managing these mailing lists where you can import, export, add or delete recipients.<\/p>\n<p>For details on configuring e-mail sending and receiving in Zotonic, see <a href=\"\/id\/doc_developerguide_email#guide-email\">E-mail handling<\/a>.<\/p>\n<h2>Including the subscribe custom tag on your pages<\/h2>\n<p>The module includes the <a href=\"\/id\/doc_template_scomp_scomp_mailinglist_subscribe\" class=\"doc-reference doc-reference-scomp\"><code>scomp#mailinglist_subscribe<\/code><\/a> tag\n(and template) that you can use on your site.<\/p>\n<p>When you want to add a subscribe template to your page then you will need the following scomp include in your template:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{% mailinglist_subscribe id=mailing_id %}\n<\/code><\/pre>\n<p>Where <code>mailing_id<\/code> should be set to the page id of your mailing list. This scomp includes the template\n<code>_scomp_mailinglist_subscribe.tpl<\/code>. The subscription form itself can be found in the template\n<code>_mailinglist_subscribe_form.tpl<\/code>. You should overrule the latter template when you want to add or remove\nfields from the subscription form.<\/p>\n<p>It is possible to simplify the subscribe form by using the option <code>is_email_only<\/code>. When this parameter is used the users\nonly have to supply their email address to be added to the mailing list. Example:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{% mailinglist_subscribe id=mailing_id is_email_only %}\n<\/code><\/pre>\n<h2>Displaying the number of subscribers<\/h2>\n<p>It is possible to show the number of subscribers to a mailinglist by retrieving this number from the mailinglist model. Example:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">{{ m.mailinglist.count_recipients[mailinglist_id] }} of subscribers\n<\/code><\/pre>\n<h2>Pages for the mailing list category<\/h2>\n<p>The mailinglist module predefines the following dispatch rules for the mailinglist:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-django\">\/mailinglist\/1234\n\/mailinglist\/1234\/my-mailinglist-slug\n<\/code><\/pre>\n<p>Where 1234 stands for the id of your mailinglist (which is obviously another id).<\/p>\n<p>The mailinglist page is very simple. It shows the title, summary and body of the mailinglist, followed by a subscribe\nform and finally a list of other mailing lists.<\/p>\n<h2>Template used for the e-mails<\/h2>\n<p>All e-mails use the <a href=\"..\/templates\/template_mailing_page.html#template-mailing-page\">mailing_page.tpl<\/a> template. It is\na very simple template that just tells why the recipient received the e-mail, refers to the sent content page on the\nInternet and finally shows the title, the summary and the body of the sent page.<\/p>\n<p>In the footer there is a link to the unsubscribe page.<\/p>\n<p>All e-mail templates extend from the <a href=\"..\/templates\/template_email_base.html#template-email-base\">email_base.tpl<\/a>\ntemplate. The following templates are used for e-mails:<\/p>\n<table class=\"table\"><thead><tr><th>Template<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><a href=\"..\/templates\/template_email_mailinglist_confirm.html#template-email-mailinglist-confirm\">email_mailinglist_confirm.tpl<\/a><\/td><td>Sent after subscribing to a mailing list, requests to click on an url to confirm the subscription.<\/td><\/tr><tr><td><a href=\"..\/templates\/template_email_mailinglist_goodbye.html#template-email-mailinglist-goodbye\">email_mailinglist_goodbye.tpl<\/a><\/td><td>Sent after unsubscribing from a mailing list.<\/td><\/tr><tr><td><a href=\"..\/templates\/template_email_mailinglist_welcome.html#template-email-mailinglist-welcome\">email_mailinglist_welcome.tpl<\/a><\/td><td>Sent after subscribing and confirming the subscription.<\/td><\/tr><\/tbody><\/table>\n<h2>Sending mailings in the admin<\/h2>\n<p>On the resource edit page of any page (remember: the mailinglist module can send any resource as a mailing!) there is a\nlink in the right column called Go to the mailing page.<\/p>\n<h2>The mailinglist recipients page<\/h2>\n<p>Each mailinglist has a special page in the admin that lets you view the recipients that are part of the list. On that\npage you can perform varions functions on the recipients of the list.<\/p>\n<ul><li>Add new recipient - Opens a dialog to add a single recipient to the list.<\/li><li>Download recipient list - Downloads a <code>.txt<\/code> file with all the e-mail addresses and name details of all recipients.<\/li><li>Upload recipient list - Upload a new file with recipients. Each e-mail address goes on its own line. There is a checkbox which lets you clear the list before the import, effectively overwriting all recipients in the list.<\/li><li>Clear recipient list - After a confirmation, this removes all recipients from the list.<\/li><li>Combine two lists - this opens a dialog which lets you combine two lists. Using this new dialog, the recipients of two lists can be combined according to the three set operations union, subtract and intersect.<\/li><\/ul>\n<h2>The mailing status page<\/h2>\n<p>From the mailing status page you can send the current resource to a mailing list, to the test mailing list or to an\nemail address.<\/p>\n<h3>Sending mailings<\/h3>\n<p>Each send is stored as a durable mailing run, including single-address tests.\nThe Send mailing page selects the list, rendering language, audience, resend\npolicy and timing. A review step estimates eligible and skipped recipients.\nConfirmation opens the run&#39;s live status page.<\/p>\n<p>Mailings can run immediately, at a selected date, or when the page becomes\npublished. Separate runs can send the same page\/list in different languages.\nThe queue task claims runs atomically. Its presence and interrupted workers\nare checked every minute. Test mailings run immediately.<\/p>\n<p>Delivery notifications update mailinglist_run_recipient and mailinglist_run_message;\nmailinglist_run_stats maintains per-language state counts. Email logs are never\nused for progress or duplicate detection. Sent means accepted by the mail\nserver; late bounces update results. Explicit retry\/resend runs preserve history.<\/p>\n<p>The Mailings admin page shows runs separately from Mailing lists management.\nBoth page and list resource editors include live status panels.<\/p>\n<h2>Accepted Events<\/h2>\n<p>This module handles the following notifier callbacks:<\/p>\n<ul><li><code>observe_acl_is_allowed<\/code>: Allow mailinglist admins to add or remove subscriber edges to mailinglists.<\/li><li><code>observe_admin_menu<\/code>: Contribute module entries to the admin menu tree.<\/li><li><code>observe_mailinglist_message<\/code>: Send status messages (like welcome and goodbye) to a recipient.<\/li><li><code>observe_rsc_pivot_done<\/code>: Update publication mailing due dates after their page is pivoted.<\/li><li><code>observe_search_query<\/code>: Add mailing-list specific search query handling for <code>mailinglist_recipients<\/code>.<\/li><li><code>observe_tick_24h<\/code>: Every 24h cleanup the mailinglists recipients using <code>m_mailinglist:periodic_cleanup<\/code>.<\/li><\/ul>\n<p>Delegate callbacks:<\/p>\n<ul><li><code>event\/2<\/code> with <code>postback<\/code> messages: <code>dialog_mailing_cancel_confirm<\/code>, <code>mailing_cancel<\/code>, <code>mailing_page_redirect<\/code>, <code>mailinglist_reset<\/code>, <code>mailinglist_unsubscribe<\/code>.<\/li><li><code>event\/2<\/code> with <code>submit<\/code> messages: <code>mailing_testaddress<\/code>, <code>mailinglist_combine<\/code>, <code>mailinglist_optout<\/code>, <code>mailinglist_upload<\/code>.<\/li><\/ul>","slug":"mod_mailinglist","doc_module_config":[{"default":"[]","description":"The email address used as the &#39;From&#39; of mailings, used if the property &#39;mailinglist_reply_to&#39; is not set on the mailinglist. If empty, falls back to site.email_from and ultimately the default email sender.","has_default":true,"key":"email_from","module":"mod_mailinglist","type":"string"},{"default":"false","description":"If true, send a confirmation email to the recipient when they are added to a mailinglist. If false, send a welcome email. Can be overridden in the signup form and mailinglist settings.","has_default":true,"key":"send_confirm","module":"mod_mailinglist","type":"boolean"},{"default":"[]","description":"The secret used to encrypt the keys to manage a specific subscription for an email address.This is generated automatically and must be kept secret.","has_default":true,"key":"recipient_secret","module":"mod_mailinglist","type":"string"}],"is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"85d0daa30aeadf780307e4051ecf75ef3eae073a2b73c99ec4f715f99a0e785b","is_featured":false,"content_group_id":{"id":2551,"is_a":["meta","content_group"],"name":"content_group_imported_docs","title":"Imported documentation","uri":"https:\/\/zotonic.com\/id\/content_group_imported_docs"},"category_id":{"id":320,"is_a":["meta","category"],"name":"module","title":"Modules","uri":"https:\/\/test.zotonic.com\/id\/320"},"doc_source_path":"apps\/zotonic_mod_mailinglist\/src\/mod_mailinglist.erl","publication_start":"2023-06-24T08:17:52Z","github_url":"https:\/\/github.com\/zotonic\/zotonic\/blob\/master\/apps\/zotonic_mod_mailinglist\/src\/mod_mailinglist.erl","pivot_location_lng":null,"doc_source_kind":"module","name":"doc_module_mod_mailinglist","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2020-05-30T05:47:23Z","uri":null,"doc_status":"current","is_dependent":false,"erlang_app":"zotonic_mod_mailinglist","publication_end":"9999-06-01T00:00:00Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"privacy":0,"doc_source_commit":"92d27433689eef55504265c6dd5486c65dd73483\n","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"modified":"2026-10-13T15:40:16Z","title_slug":"mod_mailinglist"},"uri":"https:\/\/zotonic.com\/id\/1465","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1465"}},"status":"ok"}