Documents: show each document's language as a flag beside its kind #280
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Postulo/postulo#280
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A CV and a cover letter each declare the language they are written in, and nothing in Documents says which. The field decides the
langof the PDF an employer receives — which is what a recruiter's screen reader reads it out with, and what WeasyPrint hyphenates and justifies by (#223) — so it is not a detail of the edit form. Somebody keeping "Backend, English" beside "Backend, Português" has to open each one to tell them apart, or trust the name they gave it.Show the language as a flag beside the kind, the way Settings → Language and time shows one beside every language in the picker (#52, #88, #119), and the way #208 asks for on Server settings → Defaults and #214 on postal addresses.
What it is today
src/postulo/templates/documents/cv_list.html:30-45— the cards. Kind sits in a chip at the top right of each, and the language appears nowhere:src/postulo/templates/documents/letter_list.html:35-50— rows rather than cards, but the same omission:{{ letter.get_kind_display }}on the secondary line, no language.src/postulo/templates/documents/cv_detail.html:11—kind · headline · theme, no language either. The only place a CV's language is ever named in the interface outside the form is the{% if fell_back %}warning at line 36, and that fires only when an entry has not been translated into it.CV.languageandCoverLetter.languagearedocuments/models.py:120and:333. Both areblank=True, meaning follow your profile.What already exists to reuse
{% flag country %}(core/templatetags/postulo.py:126) draws an SVG out ofstatic/flags/, 20×15 with the ratio stated so the row does not reflow. It returns""for an unknown or empty country, and takeslabel=for the case where the flag has to speak for itself.languages.flag_country(code)(core/languages.py:123) gives the country whose flag stands for a language, and deliberately returns""for the ones with no uncontested home —ar,sw,haand the rest listed at:61. No flag beats a wrong flag.rendering.document_language(document)(documents/rendering.py:69) already resolves the effective language: what the document says, else what its owner reads Postulo in, else the instance default. This is the value the flag should stand for, not the raw field.languages.NATIVE_NAMES(core/languages.py:135) gives the language's own name for itself, for the label.settings/locale.html:34,64is the worked example of a flag beside a language.Points to settle
{% flag %}'s defaultalt="" aria-hidden="true"is correct — "Portugal flag, português (Portugal)" is worse than silence. On a card there is no name beside it, so it has to carrylabel=, and the label is the language, not the country: Português, never Portugal.tests/test_flags.py:133pins the distinction.flag_countryreturns""for perhaps a dozen offered languages, and the card must read as well without the image as with it. Either the language's short name in the same slot, or nothing — but decided once here rather than per template.upload_list.html:34,rendered_list.html:34) show a kind too but carry nolanguagefield at all — an uploaded certificate's language is not known, and a rendered snapshot's was fixed at the moment it was frozen. Either leave both alone, or take the rendered ones from the source document and say so; not worth widening this issue for.cv_detail.html:11,letter_detail.html) should almost certainly gain the same flag on the same line, since that is where somebody checks a document before exporting it.Notes for whoever takes it
CVListView(documents/views.py:67) is scoped byOwnedObjectMixin(core/mixins.py:16), so every row on the page belongs to the same person: the profile fallback indocument_languageresolves once for the list, not once per card. Resolving it naively per row is an N+1 onowner.profile.documents/models.pymoves the#:source references of every translatable string below it and makesscripts/messages.py extract --checkfail with no new string at all — #193 was exactly this. Runextract, then scope the revert tosrc/postulo/plugins/*/locale.tests/test_flags.pyis where the flag promises live, and the browser walk will want the cards checked at 320 pixels with a long language name — #167's lesson.Landed on
mainas916217648.