In lesson 2.5.12 you made the booking page bilingual: texts in .resx files, IStringLocalizer<T>, the language from the address, a switch. The seventh milestone carries that through the whole public Kladde. Every page a visitor sees without signing in then exists in English and in German, and the mails of a booking arrive in the language the booking was made in.

That sounds like busywork, and part of it is. The real questions lie elsewhere: Who decides which language a request gets? How do you notice that a page has forgotten its second language? And in which language does a background service write when it has no request at all?

Pull request Branch Brings Where in this lesson
1 feature/m7-language-from-address the address decides the language, <html lang> follows it “Pull request 1”
2 feature/m7-public-layout hreflang and a language switch in the public layout “Pull request 2”
3 feature/m7-all-public-pages all public pages under both addresses, the test over all pages “Pull request 3” and exercise 1
4 feature/m7-mail-language the booking remembers its language, mails and their links follow it exercise 2

Where the Kladde stands

After module 2.5 and milestone 6, the solutions have this:

  • Since lesson 2.5.12, the address decides the language: PathCultureProvider makes /de/… German and everything else English; the Kladde doesn’t ask ?culture= or Accept-Language. For interactive islands it also sets the culture cookie, and <html lang> follows the culture.
  • The texts live in .resx files next to their components (Home, BookAppointment, MainLayout, SkipLink, each in English and in German), the booking’s messages in BookingTexts.resx. ResourceTests checks that every file has a German twin with the same names.
  • Languages builds links in the page’s language (Languages.Link, GermanOf, EnglishOf), and LanguageLinks in the public layout MainLayout from lesson 2.5.3 writes hreflang and the switch. The internal layout stays English.
  • Bilingual are the home page and the booking page at /appointment and /de/appointment. The pages from milestones 3 and 4 are English only: “Almost done” at /appointment/thanks, confirming, canceling, plus “not found” and the rate limiter’s page. The mails are written by BookingMails in English.

The examples in this lesson build pull requests 1 and 2 from scratch and with different names: one shared resource file Resources/Texts.resx for IStringLocalizer<Texts>, KladdeLanguages for the provider, LanguagePaths instead of Languages and a public layout with the switch. With the solution of lesson 2.5.12 you already have most of it. Read the two sections as a checklist, take over only what your Kladde lacks, such as UseRequestLocalization before the rate limiter, and in the examples read Languages.Link for LanguagePaths.Current, the .resx files next to the page for Texts.resx, and MainLayout for the public layout. The real work of this milestone is in pull requests 3 and 4. If your files, classes or folders have other names, keep yours and carry the steps over.