mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 03:41:05 -05:00
Docs: simplify editing ESP feature matrix
Move the big ESP feature matrix table into a CSV file for easier maintenance. Remove the doc8 line-length exception the old table needed. Docutils csv-table directive doesn't support colspan on the subheadings like the old table did. Add some JS that replicates the old behavior. (The new table is still readable even with JS disabled.)
This commit is contained in:
40
docs/_static/table-formatting.js
vendored
Normal file
40
docs/_static/table-formatting.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Return the first sibling of el that matches CSS selector, or null if no matches.
|
||||
* @param {HTMLElement} el
|
||||
* @param {string} selector
|
||||
* @returns {HTMLElement|null}
|
||||
*/
|
||||
function nextSiblingMatching(el, selector) {
|
||||
while (el && el.nextElementSibling) {
|
||||
el = el.nextElementSibling;
|
||||
if (el.matches(selector)) {
|
||||
return el;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert runs of empty <td> elements to a colspan on the first <td>.
|
||||
*/
|
||||
function collapseEmptyTableCells() {
|
||||
document.querySelectorAll(".rst-content tr:has(td:empty)").forEach((tr) => {
|
||||
for (
|
||||
let spanStart = tr.querySelector("td");
|
||||
spanStart;
|
||||
spanStart = nextSiblingMatching(spanStart, "td")
|
||||
) {
|
||||
let emptyCell;
|
||||
while ((emptyCell = nextSiblingMatching(spanStart, "td:empty"))) {
|
||||
emptyCell.remove();
|
||||
spanStart.colSpan++;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", collapseEmptyTableCells);
|
||||
} else {
|
||||
collapseEmptyTableCells();
|
||||
}
|
||||
@@ -279,6 +279,7 @@ def setup(app):
|
||||
anymail_config_js = (DOCS_PATH / "_static/anymail-config.js").read_text()
|
||||
app.add_js_file(None, body=anymail_config_js)
|
||||
app.add_js_file("version-alert.js", **{"async": "async"})
|
||||
app.add_js_file("table-formatting.js", **{"async": "async"})
|
||||
app.add_js_file("https://unpkg.com/rate-the-docs", **{"async": "async"})
|
||||
|
||||
# Django-specific roles, from
|
||||
|
||||
19
docs/esps/esp-feature-matrix.csv
Normal file
19
docs/esps/esp-feature-matrix.csv
Normal file
@@ -0,0 +1,19 @@
|
||||
Email Service Provider,:ref:`amazon-ses-backend`,:ref:`brevo-backend`,:ref:`mailersend-backend`,:ref:`mailgun-backend`,:ref:`mailjet-backend`,:ref:`mandrill-backend`,:ref:`postal-backend`,:ref:`postmark-backend`,:ref:`resend-backend`,:ref:`sendgrid-backend`,:ref:`sparkpost-backend`
|
||||
.. rubric:: :ref:`Anymail send options <anymail-send-options>`,,,,,,,,,,,
|
||||
:attr:`~AnymailMessage.envelope_sender`,Yes,No,No,Domain only,Yes,Domain only,Yes,No,No,No,Yes
|
||||
:attr:`~AnymailMessage.metadata`,Yes,Yes,No,Yes,Yes,Yes,No,Yes,Yes,Yes,Yes
|
||||
:attr:`~AnymailMessage.merge_metadata`,No,No,No,Yes,Yes,Yes,No,Yes,No,Yes,Yes
|
||||
:attr:`~AnymailMessage.send_at`,No,Yes,Yes,Yes,No,Yes,No,No,No,Yes,Yes
|
||||
:attr:`~AnymailMessage.tags`,Yes,Yes,Yes,Yes,Max 1 tag,Yes,Max 1 tag,Max 1 tag,Yes,Yes,Max 1 tag
|
||||
:attr:`~AnymailMessage.track_clicks`,No,No,Yes,Yes,Yes,Yes,No,Yes,No,Yes,Yes
|
||||
:attr:`~AnymailMessage.track_opens`,No,No,Yes,Yes,Yes,Yes,No,Yes,No,Yes,Yes
|
||||
:ref:`amp-email`,Yes,No,No,Yes,No,No,No,No,No,Yes,Yes
|
||||
.. rubric:: :ref:`templates-and-merge`,,,,,,,,,,,
|
||||
:attr:`~AnymailMessage.template_id`,Yes,Yes,Yes,Yes,Yes,Yes,No,Yes,No,Yes,Yes
|
||||
:attr:`~AnymailMessage.merge_data`,Yes,No,Yes,Yes,Yes,Yes,No,Yes,No,Yes,Yes
|
||||
:attr:`~AnymailMessage.merge_global_data`,Yes,Yes,(emulated),(emulated),Yes,Yes,No,Yes,No,Yes,Yes
|
||||
.. rubric:: :ref:`Status <esp-send-status>` and :ref:`event tracking <event-tracking>`,,,,,,,,,,,
|
||||
:attr:`~AnymailMessage.anymail_status`,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes
|
||||
:class:`~anymail.signals.AnymailTrackingEvent` from webhooks,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes
|
||||
.. rubric:: :ref:`Inbound handling <inbound>`,,,,,,,,,,,
|
||||
:class:`~anymail.signals.AnymailInboundEvent` from webhooks,Yes,Yes,Yes,Yes,Yes,Yes,Yes,Yes,No,Yes,Yes
|
||||
|
@@ -33,56 +33,25 @@ The table below summarizes the Anymail features supported for each ESP.
|
||||
|
||||
.. currentmodule:: anymail.message
|
||||
|
||||
.. rst-class:: sticky-left
|
||||
|
||||
============================================ ============ ======= ============ =========== ========== =========== ========== ========== ======== ========== ===========
|
||||
Email Service Provider |Amazon SES| |Brevo| |MailerSend| |Mailgun| |Mailjet| |Mandrill| |Postal| |Postmark| |Resend| |SendGrid| |SparkPost|
|
||||
============================================ ============ ======= ============ =========== ========== =========== ========== ========== ======== ========== ===========
|
||||
.. rubric:: :ref:`Anymail send options <anymail-send-options>`
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
:attr:`~AnymailMessage.envelope_sender` Yes No No Domain only Yes Domain only Yes No No No Yes
|
||||
:attr:`~AnymailMessage.metadata` Yes Yes No Yes Yes Yes No Yes Yes Yes Yes
|
||||
:attr:`~AnymailMessage.merge_metadata` No No No Yes Yes Yes No Yes No Yes Yes
|
||||
:attr:`~AnymailMessage.send_at` No Yes Yes Yes No Yes No No No Yes Yes
|
||||
:attr:`~AnymailMessage.tags` Yes Yes Yes Yes Max 1 tag Yes Max 1 tag Max 1 tag Yes Yes Max 1 tag
|
||||
:attr:`~AnymailMessage.track_clicks` No No Yes Yes Yes Yes No Yes No Yes Yes
|
||||
:attr:`~AnymailMessage.track_opens` No No Yes Yes Yes Yes No Yes No Yes Yes
|
||||
:ref:`amp-email` Yes No No Yes No No No No No Yes Yes
|
||||
|
||||
.. rubric:: :ref:`templates-and-merge`
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
:attr:`~AnymailMessage.template_id` Yes Yes Yes Yes Yes Yes No Yes No Yes Yes
|
||||
:attr:`~AnymailMessage.merge_data` Yes No Yes Yes Yes Yes No Yes No Yes Yes
|
||||
:attr:`~AnymailMessage.merge_global_data` Yes Yes (emulated) (emulated) Yes Yes No Yes No Yes Yes
|
||||
.. rubric:: :ref:`Status <esp-send-status>` and :ref:`event tracking <event-tracking>`
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
:attr:`~AnymailMessage.anymail_status` Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
|
||||
|AnymailTrackingEvent| from webhooks Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes Yes
|
||||
.. rubric:: :ref:`Inbound handling <inbound>`
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|AnymailInboundEvent| from webhooks Yes Yes Yes Yes Yes Yes Yes Yes No Yes Yes
|
||||
============================================ ============ ======= ============ =========== ========== =========== ========== ========== ======== ========== ===========
|
||||
.. It's much easier to edit esp-feature-matrix.csv with a CSV-aware editor, such as:
|
||||
.. PyCharm (Pro has native CSV support; use a CSV editor plugin with Community)
|
||||
.. VSCode with a CSV editor extension
|
||||
.. Excel (watch out for charset issues), Apple Numbers, or Google Sheets
|
||||
.. Every row must have the same number of columns. If you add a column, you must
|
||||
.. also add a comma to each sub-heading row. (A CSV editor should handle this for you.)
|
||||
.. Please keep columns sorted alphabetically by ESP name.
|
||||
|
||||
.. csv-table::
|
||||
:file: esp-feature-matrix.csv
|
||||
:header-rows: 1
|
||||
:widths: auto
|
||||
:class: sticky-left
|
||||
|
||||
Trying to choose an ESP? Please **don't** start with this table. It's far more
|
||||
important to consider things like an ESP's deliverability stats, latency, uptime,
|
||||
and support for developers. The *number* of extra features an ESP offers is almost
|
||||
meaningless. (And even specific features don't matter if you don't plan to use them.)
|
||||
|
||||
.. |Amazon SES| replace:: :ref:`amazon-ses-backend`
|
||||
.. |Brevo| replace:: :ref:`brevo-backend`
|
||||
.. |MailerSend| replace:: :ref:`mailersend-backend`
|
||||
.. |Mailgun| replace:: :ref:`mailgun-backend`
|
||||
.. |Mailjet| replace:: :ref:`mailjet-backend`
|
||||
.. |Mandrill| replace:: :ref:`mandrill-backend`
|
||||
.. |Postal| replace:: :ref:`postal-backend`
|
||||
.. |Postmark| replace:: :ref:`postmark-backend`
|
||||
.. |Resend| replace:: :ref:`resend-backend`
|
||||
.. |SendGrid| replace:: :ref:`sendgrid-backend`
|
||||
.. |SparkPost| replace:: :ref:`sparkpost-backend`
|
||||
.. |AnymailTrackingEvent| replace:: :class:`~anymail.signals.AnymailTrackingEvent`
|
||||
.. |AnymailInboundEvent| replace:: :class:`~anymail.signals.AnymailInboundEvent`
|
||||
|
||||
|
||||
Other ESPs
|
||||
----------
|
||||
|
||||
@@ -109,8 +109,6 @@ max-line-length = 88
|
||||
target-version = ["py37"]
|
||||
|
||||
[tool.doc8]
|
||||
# ignore very long lines in ESP support table:
|
||||
ignore-path-errors = ["docs/esps/index.rst;D001"]
|
||||
# for now, Anymail allows longer lines in docs source:
|
||||
max-line-length = 120
|
||||
|
||||
|
||||
Reference in New Issue
Block a user