Italian addresses the reader as tu, across the catalogs, the mails and the help pages - #2240
Merged
Merged
Conversation
Ein italienischer Muttersprachler hat uns eine korrigierte Fassung beider
Kataloge geschickt; in jedem Satz, den er angefasst hat, wurde aus der
Höflichkeitsform das Du. Das ist bei italienischen Web-Produkten die Regel,
also folgen die restlichen rund 800 Einträge jetzt mit, sonst stünde ein
gemischter Katalog da. Aus "Endorsement" wird "approvazione" statt
"conferma", weil "Conferma" schon "Confirm" übersetzt und beide Bedeutungen
auf denselben Knöpfen landeten; die Fehlermeldungen übernehmen die
Groß-/Kleinschreibung ihres Originals, so wie es der deutsche Katalog tut.
Seine Datei ist nicht wörtlich übernommen: sie stammt von einem älteren
Stand, enthält Tippfehler ("Pafine", "qulli"), verirrte Anführungszeichen
mitten im Text und einen übersetzten Platzhalter ({guidelines} als
{linee guida}), der die Seite zerlegt hätte. Übernommen wurden Wortwahl und
Anrede, geprüft wurde jeder Platzhalter gegen seine msgid.
Die Kataloge allein reichen nicht: 61 Mail-Templates unter templates/email und templates/email_body tragen ihre italienische Prosa direkt im Template, wo kein gettext hinsieht, dazu die beiden Hilfeseiten und ein paar Literale in Elixir (image_kind_label, der Abmelde-Hinweis). Die hätten weiter Lei gesagt, während die Oberfläche du sagt, und das fällt genau da auf, wo man vom Beitrag in die Mail über den Beitrag wechselt. Die Anrede in der Mail beginnt bei der Begrüßung: email_greeting/1 nimmt für Italienisch jetzt die englische Form, Vorname ohne Anrede. "Gentile Sig. Rossi" über einem Text, der danach "hai" sagt, liest sich wie zwei Absender.
"grazie per esserti iscritto" und "se sei stato tu" sind maskulin, und die Du-Form macht das sichtbar, wo die Höflichkeitsform es noch verdeckt hat: eine Frau liest in der Registrierungsmail eine Anrede, die nicht auf sie passt. Wo sich eine geschlechtsneutrale Formulierung ohnehin besser liest, steht sie jetzt da: "grazie per l'iscrizione", "se l'accesso è tuo", "se il tentativo non è tuo". An den übrigen Stellen bleibt die im Italienischen übliche männliche Form stehen; das ist eine Frage für einen Muttersprachler, keine für uns.
wintermeyer
added a commit
that referenced
this pull request
Sep 19, 2026
* Anzeige auf Profil und Feed, höchstens eine pro Stunde je Mitglied Der Streifen unter der Navigation erreichte weder Profil noch Feed, weil beide LiveViews sind. Die Anzeige steht jetzt als Karte in der rechten Spalte und auf dem Handy oben, entschieden pro Request und über die Mount-Session an die LiveView gereicht, die sie nach zwei Minuten selbst ausblendet, damit ein Reconnect sie nicht zurückbringt. Stundensperre und Wegklicken liegen für Mitglieder auf dem Server (users.ad_seen_at, users.ads_dismissed_on) und gelten so auf allen Geräten, Besucher behalten Session und Cookie. Gesehene gebuchte Anzeigen zählt ad_sightings, die Grundlage für die geplante Übersicht. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Regel: push_event an einen Hook, den derselbe Patch entfernt LiveView wendet zuerst den Patch an, zerstört dabei den Hook und verschickt die Ereignisse erst danach, sodass ein handleEvent in diesem Hook still ins Leere läuft. Genau so schrieb das ✕ der Anzeigenkarte für Besucher nie sein Tages-Cookie. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Countdown-Ring an der Anzeige, gezählt wird nur Gesehenes Die Anzeige verschwand bisher nach zwei Minuten Uhrzeit, auch wenn niemand sie angesehen hatte, und die Stunde galt schon beim Ausliefern als verbraucht. Jetzt leert sich ein Ring um das ✕ nur, solange die Karte zur Hälfte im Bild ist und weder Maus noch Fokus auf ihr liegen, und die Stunde zählt erst ab dieser ersten Sichtung, für Mitglieder auf dem Server, für Besucher in einem Cookie statt in der Session. Die Stunde wird nur genommen, wenn sie frei ist, damit zwei früh geöffnete Tabs nicht zwei Anzeigen zeigen. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Gesehene Anzeigen unter /system/ads/seen Ein Mitglied, das auf „Anzeige“ klickt, soll nachlesen können, welche Anzeigen es gesehen hat, wann und wie oft, durchsuchbar und seitenweise. Besucher ohne Konto haben keine Historie, ihr Label führt deshalb zur Angebotsseite statt zu einem öffentlichen Archiv, das eine Tagesbuchung monatelang ausstellen würde. Sichtungen sind personenbezogen: Sie stehen im Datenexport und verschwinden 90 Tage nach der letzten Sichtung. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Anzeigen als Titel, Satz und Link statt Markdown Eine Anzeige soll wie eine klassische Textanzeige aussehen: ein kurzer Titel als Link, ein Satz und die Adresse, zu der der Link führt. Freies Markdown ließ Überschriften, Listen und Erwähnungen zu und machte jede Anzeige anders hoch; jetzt begrenzt das Formular Titel und Satz mit Live-Zählern, und die angezeigte Adresse lässt Parameter wie utm_source weg. Die Spalte content bleibt vorerst und fällt in einem späteren Deploy, eine alte Anzeige ohne Titel wird nicht mehr ausgeliefert. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Anzeigen ohne Cookies Die Anzeige soll bei Besuchern ohne Konto nichts im Browser hinterlassen, damit vutuv weiter ohne Cookie-Banner auskommt. Stundensperre und ✕ gelten deshalb nur noch für angemeldete Mitglieder und stehen in der Datenbank. Besucher sehen die Anzeige auf jedem Profil, ihr ✕ schließt nur diese Karte. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Regel: Beispiel mit dem Anzeigen-Cookie gestrichen Die Anzeigenkarte schreibt kein Tages-Cookie mehr, der Beispielsatz in der push_event-Regel wäre nach dem Merge falsch. Die Regel selbst gilt unverändert. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Anzeigenseiten unter /system/ads Neue Seiten der Plattform gehören unter /system/, weil jedes neue Wort an der URL-Wurzel einen Namen belegt, den Mitglieder sonst als Handle wählen könnten. Angebot, Buchung, Vorschau und „Meine Buchungen“ ziehen deshalb von /ads nach /system/ads, samt Maschinenformaten, Sitemap und llms.txt. Produktion hat die Seiten nie ausgeliefert, eine Weiterleitung braucht es daher nicht; „ads“ bleibt reserviert. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Anzeigen ablehnen, stornieren, zählen und Buchende informieren Bisher konnte eine unpassende Anzeige ihren Tag nur blockieren, Buchende erfuhren nichts, und Zahlen gab es keine. Jetzt lehnt die Abnahme mit einer Begründung ab, Buchende stornieren kostenlos bis zur Freischaltung, Admins danach, und jede dieser Wendungen gibt den Tag wieder frei und schreibt eine Mail. Aufrufe und Klicks zählen nur als Summe pro Anzeige; Daten stehen im Format der Lesenden, und „Meine Buchungen“ zeigt den gebuchten statt des heutigen Preises. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Anzeigen duzen auch auf Italienisch Während dieser Branch lief, hat PR #2240 das italienische vutuv vom Sie auf das Du umgestellt; meine Anzeigen-Texte waren noch in der Lei-Form geschrieben und hätten die Sprache mitten in der Buchungsstrecke gewechselt. Zwölf Katalogeinträge und alle acht italienischen Anzeigen-Mails (Text und HTML) sagen jetzt „la tua pubblicità", „puoi annullare", „ti scriveremo". Die Mail-Templates liegen außerhalb von gettext, also findet sie kein Katalog-Durchlauf — sie mussten einzeln gelesen werden. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Anzeigen kosten 350 € netto, die Woche und der Monat weniger Der Tagespreis steht auf 350 €, und weil jeder genannte Preis netto ist, steht die Mehrwertsteuer überall darunter; der Satz ist ein Schalter, damit eine Installation anderswo ihren eigenen abrechnen kann. Neu sind Blöcke: sieben Tage für 2.000 €, dreißig für 7.500 €, als eine Transaktion aus einer Zeile je Tag mit gemeinsamer `group_id` — fällt ein Tag weg, fällt der ganze Kauf, statt dass jemand vier Tage einer bezahlten Woche hält. Dass eine Entscheidung den ganzen Block bewegt, sitzt allein in `move/3`, also erben Freischalten, Ablehnen und beide Stornowege es zusammen. Die Angebotsseite zeigt das in zwei Spalten mit einer Beispielanzeige, gezeichnet von der Komponente, die auch auf Profil und Feed läuft. Zwei Fallen kamen erst im Browser heraus: die Mails nannten den ersten Tag und den Tagesanteil statt Zeitraum und Blockpreis, und `gettext.extract` hatte alle vier neuen Betreffzeilen mit dem Platzhalter ihres Eintages-Zwillings gefüllt, was beim Rendern geworfen hätte. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Anzeigen buchen in drei Schritten statt in einem Formular Das alte Formular fragte Text, Tag und Rechnungsadresse auf einmal ab und zeigte die Anzeige erst auf einer eigenen Vorschauseite — die einzige Frage, die Kaufende wirklich haben, wurde also beantwortet, nachdem sie alles ausgefüllt hatten. Der Wizard zeichnet die Karte jetzt beim Tippen, mit derselben Komponente, die auf Profil und Feed läuft, und fragt pro Schritt eine Sache. Der Text lässt sich im Konto speichern und wiederverwenden; eine Buchung kopiert ihn, damit ein späteres Ändern keine laufende oder bereits berechnete Anzeige umschreibt. Der Kalender zeigt diesen und die nächsten drei Monate und rechnet in der Einheit, die gekauft wird: bei einer Woche ist ein Tag nur anklickbar, wenn sieben dahinter frei sind, ein Klick markiert alle sieben, und das Überfahren ebenfalls — ohne Serverrunde, weil sonst genau das Suchen nach einer freien Strecke am teuersten wäre. Eine geänderte Laufzeit verwirft einen Starttag, der nicht mehr passt, statt still einen Zeitraum zu buchen, den niemand gewählt hat. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Vor dem Buchen steht, was wir uns vorbehalten, und wohin die Rechnung geht Der letzte Schritt sagt jetzt beides in eigenen Sätzen, dort wo dem Geld zugestimmt wird und nicht in einer Bedingungsseite anderswo: wir können eine Buchung ohne Angabe von Gründen ablehnen, dann läuft sie nicht und kostet nichts, und eine unbezahlte Rechnung nimmt die Anzeige wieder von der Seite. Daneben wählt man die Adresse für den Rechnungsversand, denn ein Mitglied kann mehrere haben und bisher riet die Betreiber-Mail einfach die erste. Die Wahl wird gegen die eigene Adressliste geprüft, nicht dem Formularfeld geglaubt — sonst zeigt „wohin schicken wir die Rechnung" auf jedes fremde Postfach; ein manipulierter Wert landet immer auf der ersten eigenen Adresse. Nebenbei sagt die Link-Prüfung jetzt, was zu tun ist, statt nur „ungültig", und sie zeigt es beim Tippen: ein Changeset ohne action rendert gar keine Fehler, weshalb eine Adresse ohne https:// aussah, als wäre sie angenommen. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Laufende Anzeigen herunternehmen, und Rabattcodes dafür Bisher konnte man eine Buchung nur loswerden, solange sie auf die Freischaltung wartete. Jetzt lässt sich auch eine laufende Anzeige herunternehmen — ab heute, ohne Erstattung, und ein Modal sagt das, bevor die Handlung überhaupt erreichbar ist: zu lesen ist ihr Preis, und dafür gibt ein natives Bestätigungsfenster eine Zeile her. Es ist bewusst eine zweite Funktion neben dem kostenlosen Storno, sonst erreicht ein Aufrufer die teure über einen Zweig. „Meine Anzeigen" steht außerdem im Konto-Menü, denn /system/ads rät niemand. Dazu Rabattcodes im Admin. Der Code ist die Zeilen-ID selbst, eine UUID, also kollidiert nichts und niemand rät einen. Prozent oder Euro, nie beides, geprüft auch als Datenbank-Constraint, weil Geld nicht von einer vergessenen Validierung abhängen darf. Einlösungen sind Zeilen statt eines Zählers: „einmal pro Mitglied" ist eine Aussage über ein Paar, und derselbe partielle Index macht einen personalisierten Code genau einmal gültig. Der Rabatt wird neben dem Preis gestempelt, nicht hineingerechnet, damit eine spätere Löschung keine Rechnung umschreibt. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Die Buchungsmail führt auf, was sonst noch auf Freischaltung wartet Die Mail sagte bisher nur, dass eine Anzeige eingegangen ist, und wer sie weglegt, erfährt nirgends von den vier anderen, die inzwischen ankamen. Also steht die ganze Warteschlange darin, nach Buchungen statt nach Zeilen (eine gebuchte Woche ist eine Sache, nicht sieben) und mit dem nächsten Termin zuerst. Formatiert wird sie einmal im Emailer, damit Text- und HTML-Körper sie nur noch ausgeben; die Betreffzeile setzt ihr Deutsch jetzt ausdrücklich, statt es von der Voreinstellung der Installation zu erben. Nebenbei: „(1 Tage)" stand über jeder Einzeltagsbuchung. Bei einem Tag nennt die Zeile ohnehin nur ein Datum, also entfällt die Klammer dort. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Die Bestätigung geht dorthin, wo auch die Rechnung hingeht Der Wizard fragt, an welche Adresse die Rechnung soll, und die Bestätigung ging trotzdem an die erste Adresse des Kontos. Beide Mails lesen jetzt dieselbe Funktion, die die Wahl auch beim Versand noch einmal gegen die eigenen Adressen prüft: eine Adresse, die das Konto inzwischen verlassen hat, gehört niemandem mehr hier. Die Operator-Mail führt die Rechnung jetzt vollständig auf: Zeitraum, Buchungszeitpunkt in Berliner Zeit, Empfänger, Listenpreis, Rabatt samt Code, Netto, MwSt., Brutto — einmal berechnet, von beiden Bodies nur noch gedruckt. Der Rabatt stand bisher nirgends, also hätte die Rechnung Geld verlangt, das der Code längst abgezogen hatte; aus demselben Grund nennt auch die Bestätigung an das Mitglied den Betrag nach Rabatt. Der Knopf führt direkt auf die Buchung statt auf die Liste. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist. * Eine geänderte .po erreicht den laufenden Server nicht von selbst Gettext kompiliert die Übersetzungen in ein Modul, also serviert der Dev-Server nach einer Handkorrektur weiter den alten Text — und man debuggt eine Übersetzung, die längst stimmt. Das hat bei den Anzeigen-Mails eine ganze Runde gekostet, deshalb steht der Griff (`touch lib/vutuv_web/gettext.ex`) jetzt neben den anderen Gettext-Fallen. Diesen Text hat ein KI-Agent in meinem Namen geschrieben. Ich weiß, dass das problematisch ist.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An Italian member sent a corrected copy of both catalogs. Every sentence he
touched had moved from the polite Lei to tu, which is what Italian web
products do — but he touched about 330 of 4,588 entries, so adopting his file
as-is would have left a mixed catalog. Stefan picked tu for all of it.
What changed: 1,180 entries in
priv/gettext/it/LC_MESSAGES/default.poand 73of the 84 in
errors.po; the 61 Italian mail templates underlib/vutuv_web/templates/email{,_body}/, whose prose sits in the template whereno gettext sees it;
email_greeting/1andimage_kind_label/2inuser_helpers.ex; and the two help pages inpriv/help/. "Endorsement" isapprovazione now, because Conferma already translates "Confirm" and both
meanings were landing on the same buttons. Error messages take the capitalisation
of their own msgid, the way the German catalog does.
His file is not taken verbatim: it is from an older revision and carries typos,
stray quotation marks mid-sentence and one translated placeholder (
{guidelines}as
{linee guida}) that would have broken the page. Every placeholder is checkedagainst its msgid.
Start at
/system/reportor/system/investorswithAccept-Language: it.