Report filed with Download: the PDF declares no language and is always left to right #568

Closed
opened 2026-10-01 10:47:43 +00:00 by tiagoagueda · 0 comments
Owner

Found on 2026-09-29 in a read-only review of postulo at 95348908d, by comparing how the report's draft and its filed copy are rendered, and pressing Download in the test client for profiles in Arabic, Hebrew and French.

Related to #340.

Checked again on 2026-10-01 against main at 0a5cad587: still present. The code is now at applications/views.py:1208 (the draft rendered with the request); the errand and the template are where they were.

Pressing Download files the report through the report_pdf errand, which renders report_print.html with render_to_string and no request. The template's root element reads LANGUAGE_CODE and LANGUAGE_BIDI, which come from the i18n context processor, and context processors run only for a request. So every filed report starts <html lang="" dir="ltr">, with or without a worker. WeasyPrint takes the PDF's language and its line direction from that element. The draft that GET serves is rendered with render(request, …) and is right, so the copy filed under Sent documents differs from the one the person previewed.

  • Where: applications/slow.py:32-38 (render_a_report) and the comment above the call, which says "the print template asks for nothing a request carries"; templates/applications/report_print.html:20; compare applications/views.py:1168, which renders the draft with the request.
  • What happens: somebody reading Postulo in Hebrew or Arabic files the month's report for the employment office. The PDF is laid out left to right, so its margin-inline-* rules land on the wrong side, and it declares no language. In every other language the filed report carries no document language either. Tried with profile.language set to ar, he and fr-fr: the active language inside the errand was correct each time, and the root element was <html lang="" dir="ltr"> each time.
  • Why it matters: a screen reader, or a PDF/UA check, reads a document with no declared language by guesswork. The comment at report_print.html:16-18 promises a report "written in Arabic or Hebrew lays out from the other edge", and the filed copy does not.
  • Fix: do what the CV and letter renderers do. Pass document_language (translation.get_language()) and document_direction (core.languages.direction(...)) in the context, from both the errand and the view. Have report_print.html read those rather than LANGUAGE_CODE/LANGUAGE_BIDI, as base_letter.html:7 does. Correct the comment in slow.py.

Done when

  • tests/test_reports.py: a report filed through the report_pdf errand for a Hebrew profile starts <html lang="he" dir="rtl">, and one for a French profile starts <html lang="fr-fr" dir="ltr">. The existing tests at :555-575 render the template without a request and never look at either attribute.
Found on 2026-09-29 in a read-only review of postulo at 95348908d, by comparing how the report's draft and its filed copy are rendered, and pressing Download in the test client for profiles in Arabic, Hebrew and French. Related to #340. Checked again on 2026-10-01 against `main` at `0a5cad587`: still present. The code is now at `applications/views.py:1208` (the draft rendered with the request); the errand and the template are where they were. Pressing Download files the report through the `report_pdf` errand, which renders `report_print.html` with `render_to_string` and no request. The template's root element reads `LANGUAGE_CODE` and `LANGUAGE_BIDI`, which come from the i18n context processor, and context processors run only for a request. So every filed report starts `<html lang="" dir="ltr">`, with or without a worker. WeasyPrint takes the PDF's language and its line direction from that element. The draft that `GET` serves is rendered with `render(request, …)` and is right, so the copy filed under Sent documents differs from the one the person previewed. - **Where:** `applications/slow.py:32-38` (`render_a_report`) and the comment above the call, which says "the print template asks for nothing a request carries"; `templates/applications/report_print.html:20`; compare `applications/views.py:1168`, which renders the draft with the request. - **What happens:** somebody reading Postulo in Hebrew or Arabic files the month's report for the employment office. The PDF is laid out left to right, so its `margin-inline-*` rules land on the wrong side, and it declares no language. In every other language the filed report carries no document language either. Tried with `profile.language` set to `ar`, `he` and `fr-fr`: the active language inside the errand was correct each time, and the root element was `<html lang="" dir="ltr">` each time. - **Why it matters:** a screen reader, or a PDF/UA check, reads a document with no declared language by guesswork. The comment at `report_print.html:16-18` promises a report "written in Arabic or Hebrew lays out from the other edge", and the filed copy does not. - **Fix:** do what the CV and letter renderers do. Pass `document_language` (`translation.get_language()`) and `document_direction` (`core.languages.direction(...)`) in the context, from both the errand and the view. Have `report_print.html` read those rather than `LANGUAGE_CODE`/`LANGUAGE_BIDI`, as `base_letter.html:7` does. Correct the comment in `slow.py`. ## Done when - `tests/test_reports.py`: a report filed through the `report_pdf` errand for a Hebrew profile starts `<html lang="he" dir="rtl">`, and one for a French profile starts `<html lang="fr-fr" dir="ltr">`. The existing tests at `:555-575` render the template without a request and never look at either attribute.
tiagoagueda added this to the 0.5.0 milestone 2026-10-01 10:47:43 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#568
No description provided.