Public landing page is now served in English and Italian via path-
prefixed URLs (/en/ and /it/), with the bare / detecting the
visitor's language and 302-ing to the right one.
Routing
-------
* GET / : if authed → dashboard (unchanged). Otherwise the visitor's
language is resolved from (in priority order) the rtm.lang cookie,
the Accept-Language header, the cf-ipcountry geolocation header,
and finally DEFAULT_LANG, then a 302 redirects to /<lang>/.
* GET /en/ + /it/ : render the localised landing template, set the
rtm.lang cookie (1-year, SameSite=Lax) so the next /-visit goes
straight to the same translation. Logged-in users with user.lang
set bypass detection for / (same priority chain — user.lang wins
on every public surface they touch).
Storage
-------
* app/locales/<lang>.yaml — flat-ish nested copy files. YAML chosen
so a future translator can edit without touching Python. Strings
containing inline HTML (<strong>, <em>, <a>) are rendered with the
Jinja `safe` filter in the template.
* app/services/locales.py — loads at startup, exposes get_locale()
and detect_public_lang(). Wraps each YAML tree in a small _Dotted
view so templates can write {{ t.hero.subhead }} (deliberately NOT
a dict subclass — dict's built-in method names would shadow YAML
keys like `items`).
Template + chrome
-----------------
* landing.html ported in full to {{ t.<key> }} references.
* public_base.html gets <html lang="…"> + hreflang link tags (en/it/
x-default) when a route opts in via lang_switch=true. A tiny
EN | IT link group lands in the public header, only visible on
surfaces that opt in.
* public.css picks up the small lang-switch widget styles.
Scope (intentionally narrow)
----------------------------
* Only the landing page is localised. Pricing, terms, privacy,
disclaimer, login, verify all stay English-only for now; their
header chrome stays English too because localising labels there
while the linked content is still EN would be a worse mismatch.
* When other public pages get translated, lang_switch=true on those
routes will surface the same widget there with no template changes.
Tests
-----
* tests/test_locales.py covers YAML load parity (every active
language has a file), dotted access through the tree, the
detection precedence chain, and the unknown-locale fallback.
Deps
----
* pyyaml was already in requirements.lock as a transitive but not
declared. Added to pyproject so it stays pinned as an explicit
direct dependency.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
128 lines
5.5 KiB
YAML
128 lines
5.5 KiB
YAML
# Italian copy for the public landing page.
|
|
#
|
|
# Note: brand names ("Read the Markets") and proper nouns
|
|
# (tickers, currency codes) stay verbatim — they aren't translated.
|
|
|
|
hero:
|
|
tagline: "Capisci i mercati. Non scommetterci sopra."
|
|
subhead: >-
|
|
Pensato per investitori che vogliono <strong>ragionare con
|
|
lucidità</strong> e tagliare fuori il rumore ad alta frequenza
|
|
che nasce dal trattare i mercati come un casinò. Aggreghiamo
|
|
notizie cross-asset e segnali macro, e ne scriviamo una lettura
|
|
in prosa chiara: cosa giustificano i fondamentali sottostanti,
|
|
rispetto a cosa sta facendo la folla. Aggiornato durante la
|
|
giornata di trading. Un servizio editoriale, non finanziario.
|
|
cta_dashboard: "Apri dashboard"
|
|
cta_pricing: "Vedi i piani"
|
|
cta_signup: "Iscriviti gratis"
|
|
|
|
shot_dashboard:
|
|
alt: "Anteprima dashboard"
|
|
zoom_hint: "Clicca per ingrandire"
|
|
caption: >-
|
|
La dashboard. In alto una lettura cross-asset aggregata, sotto
|
|
gruppi di indicatori selezionati a mano. Il toggle del livello
|
|
di lettura (Novice / Pro) cambia il taglio di ogni pannello
|
|
generato dall'IA, da prosa accessibile a registro tecnico
|
|
sintetico.
|
|
|
|
features:
|
|
news:
|
|
tag: "Notizie, aggregate"
|
|
title: "Titoli dall'intero universo macro"
|
|
body: >-
|
|
Feed RSS e per-ticker che coprono azioni, tassi, credito, FX,
|
|
materie prime e geopolitica. Ogni titolo è etichettato
|
|
automaticamente per tema, così il rumore resta rumore e il
|
|
materiale rilevante per i fondamentali è facile da trovare.
|
|
L'ingestione segue il calendario di trading — fuori orario
|
|
tutto resta in pausa.
|
|
shot_alt: "Feed notizie con tag automatici"
|
|
shot_caption: >-
|
|
Il feed delle notizie. Ogni titolo porta uno o più tag tematici
|
|
(tassi, AI, energia, geopolitica, …) per tenere i fili che ti
|
|
interessano e silenziare gli altri. Click su un tag per
|
|
includerlo; shift-click per escluderlo.
|
|
indicators:
|
|
tag: "Segnali macro"
|
|
title: "Una tape cross-asset curata"
|
|
body: >-
|
|
Un set di indicatori selezionato a mano su ogni classe di
|
|
attivo, aggiornato ogni ora durante le sessioni di mercato.
|
|
Ogni gruppo ha una lettura breve che spiega cosa il movimento
|
|
<em>significa</em>, non cosa è stato. Ancorata a utili,
|
|
politica monetaria, valutazione — non a pattern grafici.
|
|
shot_alt: "Pannello indicatori con commento IA"
|
|
shot_caption: >-
|
|
Il pannello indicatori. Tab per classe di attivo (azionario,
|
|
tassi, materie prime, FX, obbligazioni, …); ogni tab porta una
|
|
'lettura' di un paragrafo scritta dal modello sopra i prezzi
|
|
live. I numeri ancorano la prosa, così il commento è
|
|
verificabile, non sospeso nel vuoto.
|
|
strategic:
|
|
tag: "Lettura strategica"
|
|
title: "Razionale vs irrazionale, paragrafo per paragrafo"
|
|
body: >-
|
|
Leghiamo i titoli della giornata e i segnali cross-asset in
|
|
un'unica interpretazione breve. Ogni paragrafo distingue i
|
|
<strong>driver razionali</strong> (utili, politica, valutazione)
|
|
dagli <strong>irrazionali</strong> (posizionamento, narrativa,
|
|
flussi) e dà un nome al divario. Due livelli di lettura: Novice
|
|
e Pro. È commento editoriale su dati pubblici — non una
|
|
previsione e non un consiglio su nessuna decisione di
|
|
investimento.
|
|
shot_alt: "Log strategico — la lettura editoriale IA"
|
|
shot_caption: >-
|
|
Il log strategico. Il modello scrive un'interpretazione
|
|
aggiornata durante la giornata, partendo dalla versione
|
|
precedente come contesto, in modo da aggiornare invece di
|
|
ricominciare. Gli utenti paganti ricevono un refresh ogni ora;
|
|
gli utenti gratuiti uno ogni sei.
|
|
|
|
multilang_callout: >-
|
|
Ogni superficie generata dall'IA — log strategico, letture degli
|
|
indicatori, analisi di portafoglio, chat, digest giornaliero — è
|
|
disponibile in <strong>Inglese</strong> e <strong>Italiano</strong>.
|
|
Usa il selettore di lingua nell'header e i pannelli si aggiornano
|
|
in tempo reale; simboli ticker, codici valuta e numeri restano
|
|
invariati tra le lingue.
|
|
|
|
more_views:
|
|
head: "Altre viste"
|
|
chat:
|
|
alt: "Fai domande di approfondimento su qualunque log passato"
|
|
caption: >-
|
|
Fai domande di approfondimento su qualunque log passato. Il
|
|
pannello chat eredita tutto il contesto del log, così puoi
|
|
tirare un filo senza re-incollare titoli o re-spiegare la
|
|
situazione.
|
|
caption_strong: "Chiedi qualsiasi cosa su un log"
|
|
caption_span: "Domande conversazionali con il contesto della giornata già caricato."
|
|
|
|
portfolio_blurb: >-
|
|
Gli utenti paganti possono anche caricare un CSV di portafoglio
|
|
dal loro broker per un sense-check IA su concentrazione,
|
|
coerenza con il regime di mercato ed esposizione valutaria. Le
|
|
posizioni restano nel browser per impostazione predefinita;
|
|
l'attivazione opzionale del cloud sync (crittografato)
|
|
permette di ritrovarle su un altro dispositivo.
|
|
|
|
not_strip:
|
|
head: "Cosa questo NON è."
|
|
items:
|
|
- "Non è consulenza finanziaria."
|
|
- "Non sono segnali di trading."
|
|
- "Non è uno strumento per day-trading."
|
|
- "Nessuna chiamata buy/sell, mai."
|
|
- "Nessuna previsione basata su pattern grafici."
|
|
- "Non è un servizio regolamentato."
|
|
|
|
footer:
|
|
legal: >-
|
|
Iscrivendoti accetti i nostri <a href="/terms">Termini</a> e
|
|
l'<a href="/privacy">Informativa privacy</a>, e confermi di aver
|
|
letto il <a href="/disclaimer">disclaimer finanziario</a>.
|
|
|
|
meta:
|
|
description: "Capisci i mercati. Non scommetterci sopra."
|