changeset 91:76baf48ea36b default tip

add translation
author Franklin Schmidt <fschmidt@gmail.com>
date Fri, 02 May 2025 17:17:52 -0600
parents 0dced626778b
children
files src/about.html.luan src/bash.html.luan src/beanshell.html.luan src/books.html.luan src/discussion.html.luan src/existing.html.luan src/freedit.html.luan src/hg_dev.html.luan src/index.html.luan src/init.luan src/java.html.luan src/java_fork.html.luan src/laf.html.luan src/learn.html.luan src/learn_bash.html.luan src/lib/Shared.luan src/lucene.html.luan src/mercurial.html.luan src/nabble.html.luan src/needed.html.luan src/nginx.html.luan src/python.html.luan src/saving.html.luan src/site.css src/site.js src/this.html.luan src/translating.html.luan
diffstat 27 files changed, 245 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/src/about.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/about.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,21 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local header = Shared.header or error()
+local luan_url = Shared.luan_url or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	local luan_url = luan_url()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>About Reactionary Software</title>
@@ -43,7 +47,7 @@
 
 			<p>Today's West is currently at the level of the decaying Greeks, heading toward complete idiocracy.  The programmers in Silicon Valley are like Ptolemy, able to construct and maintain horrible overcomplicated monstrosities, but totally unable to innovate at a fundamental level.  All good programming ideas are rejected because they don't fit into current programming ideologies.  Any programmer like Aristarchus who comes up with a good programming idea will be rejected and ridiculed for violating orthodoxy.  Modern programmers are in love with their own ideas and love complexity.  They hate simplicity and anything that violates their ideologies.</p>
 
-			<p>For a concrete example, consider <a href="https://www.luan.software/goodjava.html#parser">my parser</a>.  It is a basic innovation that massively simplifies parsing.  So what reception did it get?  Of course <a href="https://old.reddit.com/r/Compilers/comments/cv78b3/parsing_for_programmers_who_hate_modern_software/">it was ridiculed</a> by modern programmers.  This is the same story as Aristarchus.  Modern programmers naturally hate everything that is good and only love what is horrible.</p>
+			<p>For a concrete example, consider <a href="<%=luan_url%>/goodjava.html#parser">my parser</a>.  It is a basic innovation that massively simplifies parsing.  So what reception did it get?  Of course <a href="https://old.reddit.com/r/Compilers/comments/cv78b3/parsing_for_programmers_who_hate_modern_software/">it was ridiculed</a> by modern programmers.  This is the same story as Aristarchus.  Modern programmers naturally hate everything that is good and only love what is horrible.</p>
 
 			<p>Given this situation, what should a good reactionary programmer do?  In Matthew 7:6, Jesus said "Do not give what is holy to dogs, and do not throw your pearls before swine, or they will trample them under their feet, and turn and tear you to pieces."  Good software is pearls and modern programmers are swine.  So do not repeat my mistake of showing good software to modern programmers.</p>
 
@@ -57,25 +61,25 @@
 
 			<p>The result is that alt-tech is just as bad as (if not worse than) other modern tech.  A while ago I looked at YouTube alternatives, so I will use this as an example.  BitChute is horrible because its core function, video streaming, is horrible.  Videos often stall or don't play at all.  And BitChute's search is horrible.  BitChute is a technical failure.  Odysee is horrible because they require a password so complex to sign up that I couldn't produce one.  This reflects modern programmers' obsession with security in places where security doesn't matter at all.  Modern programmers, even on the right, hate individual freedom, so they refuse to give users the freedom to choose their own password.  And of course they can't be bothered with making things easier for users by, for example, generating a password for the user.  Since Odysee obviously hates the end user, I won't use Odysee.  Rumble had issues when I looked at this some time ago but seems to have fixed them.  Rumble actually may be okay, which means that they are as good as YouTube.</p>
 
-			<p>An example that I know even better is Reddit alternatives.  Here there really is nothing usable, which why <a href="/freedit.html">a Reddit alternative is needed</a>.  In that post I also go into detail in explaining why software from the Right is no better than other modern software.  And I have looked at all available Reddit alternatives, and as expected they are no good.</p>
+			<p>An example that I know even better is Reddit alternatives.  Here there really is nothing usable, which why <a href="freedit.html">a Reddit alternative is needed</a>.  In that post I also go into detail in explaining why software from the Right is no better than other modern software.  And I have looked at all available Reddit alternatives, and as expected they are no good.</p>
 
 			<p>The problem with alt-tech is the general problem with the Right.  They miss the core issue.  The core issue is not politics.  The core issue is culture.  Modern western culture is evil, so it will always produce bad software, bad politics, and bad everything else.</p>
 
 			<h2>Other Examples</h2>
 
-			<p><b>Git versus Mercurial</b> - A great example of modern programmers preferring bad software as described in <a href="/mercurial.html">the Mercurial post</a>.</p>
+			<p><b>Git versus Mercurial</b> - A great example of modern programmers preferring bad software as described in <a href="mercurial.html">the Mercurial post</a>.</p>
 
-			<p><b>The decline of Java</b> - An example of modern programmers destroying good software as I explained in <a href="/java.html">the Java post</a>.</p>
+			<p><b>The decline of Java</b> - An example of modern programmers destroying good software as I explained in <a href="java.html">the Java post</a>.</p>
 
-			<p><b>Java mail library</b> - The original <a href="https://docs.oracle.com/javaee/7/api/javax/mail/package-summary.html">javax.mail</a> was a huge overcomplicated mess.  This JavaMail package has since <a href="https://javaee.github.io/javamail/">moved to GitHub</a> where it belongs along with other horrible modern software.  Googling for alternatives gives you other libraries that are built on top of JavaMail.  Naturally I rejected all the garbage and wrote my own <a href="https://www.luan.software/goodjava.html#mail">goodjava.mail</a> from scratch.  This whole library is a little over 200 lines of code and is a thin layer on top of SMTP and MIME.  Modern programmers hate thin layers because they always think that they can do better than the underlying layer.  But a thick layer actually adds complexity and makes debugging more difficult for the user of the library.  My thin layer lets the user set the headers directly.  Does this mean that the user has to fully understand MIME headers?  No, not at all.  The user can just send himself an email of the type he wants using his favorite mail client, say gmail, and then when he receives the email, he can look at its source (with gmail "Show original").  Then he can just copy the headers into his code.  If the user is doing something complicated, then my thin layer gives him complete control to generate exactly whatever complex email he wants.  With modern libraries with their disgusting thick layers, it is always a struggle to do anything complex.</p>
+			<p><b>Java mail library</b> - The original <a href="https://docs.oracle.com/javaee/7/api/javax/mail/package-summary.html">javax.mail</a> was a huge overcomplicated mess.  This JavaMail package has since <a href="https://javaee.github.io/javamail/">moved to GitHub</a> where it belongs along with other horrible modern software.  Googling for alternatives gives you other libraries that are built on top of JavaMail.  Naturally I rejected all the garbage and wrote my own <a href="<%=luan_url%>/goodjava.html#mail">goodjava.mail</a> from scratch.  This whole library is a little over 200 lines of code and is a thin layer on top of SMTP and MIME.  Modern programmers hate thin layers because they always think that they can do better than the underlying layer.  But a thick layer actually adds complexity and makes debugging more difficult for the user of the library.  My thin layer lets the user set the headers directly.  Does this mean that the user has to fully understand MIME headers?  No, not at all.  The user can just send himself an email of the type he wants using his favorite mail client, say gmail, and then when he receives the email, he can look at its source (with gmail "Show original").  Then he can just copy the headers into his code.  If the user is doing something complicated, then my thin layer gives him complete control to generate exactly whatever complex email he wants.  With modern libraries with their disgusting thick layers, it is always a struggle to do anything complex.</p>
 
-			<p><b>Other Java libraries</b> - All of the libraries in <a href="https://www.luan.software/goodjava.html">my goodjava library collection</a> were written because all other alternatives that I could find were horrible, so I wrote my own.  Besides <a href="https://www.luan.software/goodjava.html#mail">goodjava.mail</a>, I have <a href="https://www.luan.software/goodjava.html#webserver">goodjava.webserver</a>, <a href="https://www.luan.software/goodjava.html#logger">goodjava.logger</a>, <a href="https://www.luan.software/goodjava.html#json">goodjava.json</a>, <a href="https://www.luan.software/goodjava.html#xml">goodjava.xml</a>, and of course <a href="https://www.luan.software/goodjava.html#parser">goodjava.parser</a> as good examples.  In every one of these cases, I challenge you to find an alternative to my library that is as easy to use.</p>
+			<p><b>Other Java libraries</b> - All of the libraries in <a href="<%=luan_url%>/goodjava.html">my goodjava library collection</a> were written because all other alternatives that I could find were horrible, so I wrote my own.  Besides <a href="<%=luan_url%>/goodjava.html#mail">goodjava.mail</a>, I have <a href="<%=luan_url%>/goodjava.html#webserver">goodjava.webserver</a>, <a href="<%=luan_url%>/goodjava.html#logger">goodjava.logger</a>, <a href="<%=luan_url%>/goodjava.html#json">goodjava.json</a>, <a href="<%=luan_url%>/goodjava.html#xml">goodjava.xml</a>, and of course <a href="<%=luan_url%>/goodjava.html#parser">goodjava.parser</a> as good examples.  In every one of these cases, I challenge you to find an alternative to my library that is as easy to use.</p>
 
-			<p><b>Scripting languages</b> - <a href="https://en.wikipedia.org/wiki/Scripting_language">Scripting languages</a> should be extremely simple.  There is no reason to make them complicated.  Yet all existing usable scripting languages are complicated.  So I wrote my own simple scripting language - <a href="https://www.luan.software/">Luan</a>.</p>
+			<p><b>Scripting languages</b> - <a href="https://en.wikipedia.org/wiki/Scripting_language">Scripting languages</a> should be extremely simple.  There is no reason to make them complicated.  Yet all existing usable scripting languages are complicated.  So I wrote my own simple scripting language - <a href="<%=luan_url%>/">Luan</a>.</p>
 
 			<h2>What you can do</h2>
 
-			<p>Do you want to support reactionary software as an alternative to horrible modern software?  If yes, then join our <a href="/discussion.html">discussions</a> and consider working on <a href="/needed.html">needed reactionary software</a>.</p>
+			<p>Do you want to support reactionary software as an alternative to horrible modern software?  If yes, then join our <a href="discussion.html">discussions</a> and consider working on <a href="needed.html">needed reactionary software</a>.</p>
 
 			<p>You also should consider the fact that if humanity itself becomes worthless, then good software no longer has any value.  To fight the degeneration of humanity, you might also consider my <a href="https://www.arkian.net/">Arkian project</a>.</p>
 		</div>
--- a/src/bash.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/bash.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local existing_header = Shared.existing_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Bash</title>
@@ -23,7 +25,7 @@
 
 			<p><a href="https://www.gnu.org/software/bash/">Bash</a> is a Unix shell or command line.  There are many shells available but Bash is old and standard.  None of the alternatives are better, so stick with Bash.</p>
 
-			<p>Bash is the first programming language that one should learn.  This isn't the conventional approach, but think of human languages like English.  Does one start a new language by having conversations or by writing essays?  The command line is like having a conversation with one's computer while a program is like an essay.  Using the command line will naturally get one used to the right kind of thinking needed for programming.  The next step is to write programs (shell scripts) in Bash to automate what one does from the command line.  Another benefit to learning bash is that it helps one understand one's computer.  Bash deals with basic concepts like files and directories.  Note that the first <a href="/books.html">book</a> recommended here is <a href="https://www.amazon.com/Unix-Programming-Environment-Prentice-Hall-Software/dp/013937681X/">The Unix Programming Environment</a> which introduces the shell.  To learn Bash, see <a href="learn_bash.html">my Bash tutorial</a>.</p>
+			<p>Bash is the first programming language that one should learn.  This isn't the conventional approach, but think of human languages like English.  Does one start a new language by having conversations or by writing essays?  The command line is like having a conversation with one's computer while a program is like an essay.  Using the command line will naturally get one used to the right kind of thinking needed for programming.  The next step is to write programs (shell scripts) in Bash to automate what one does from the command line.  Another benefit to learning bash is that it helps one understand one's computer.  Bash deals with basic concepts like files and directories.  Note that the first <a href="books.html">book</a> recommended here is <a href="https://www.amazon.com/Unix-Programming-Environment-Prentice-Hall-Software/dp/013937681X/">The Unix Programming Environment</a> which introduces the shell.  To learn Bash, see <a href="learn_bash.html">my Bash tutorial</a>.</p>
 
 			<p>The right environment for programming is the command line and a text editor, not an <a href="https://en.wikipedia.org/wiki/Integrated_development_environment">IDE</a>.  IDEs are one of the horrors of modern programming.  They are bloated, overcomplicated, and inflexible.  Reactionary programming should be based on using simple flexible tools like the shell and a text editor.</p>
 		</div>
--- a/src/beanshell.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/beanshell.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -2,7 +2,9 @@
 local error = Luan.error
 local pairs = Luan.pairs or error()
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local header = Shared.header or error()
@@ -558,10 +560,10 @@
 end
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary BeanShell Tutorial</title>
--- a/src/books.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/books.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local header = Shared.header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Programming Books</title>
--- a/src/discussion.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/discussion.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local header = Shared.header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Discussion</title>
--- a/src/existing.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/existing.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,20 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local existing_header = Shared.existing_header or error()
+local luan_url = Shared.luan_url or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Existing Reactionary Software</title>
@@ -21,15 +24,15 @@
 		<div content>
 			<h1>Existing Reactionary Software</h1>
 			<ul links>
-				<li><a href="https://dad.reactionary.software/">JavaScript Drag and Drop</a> <img src="external_link.svg"></li>
-				<li><a href="/mercurial.html">Mercurial</a></li>
-				<li><a href="/bash.html">Bash</a></li>
-				<li><a href="/java.html">Java 8</a></li>
-				<li><a href="/python.html">Python</a></li>
-				<li><a href="https://www.luan.software/">Luan</a> <img src="external_link.svg"></li>
-				<li><a href="/nginx.html">Nginx</a></li>
-				<li><a href="https://mailer.reactionary.software/">Mailer REST API</a> <img src="external_link.svg"></li>
-				<li><a href="/this.html">This Website</a></li>
+				<li><a href="https://dad.reactionary.software/">JavaScript Drag and Drop</a> <img src="/external_link.svg"></li>
+				<li><a href="mercurial.html">Mercurial</a></li>
+				<li><a href="bash.html">Bash</a></li>
+				<li><a href="java.html">Java 8</a></li>
+				<li><a href="python.html">Python</a></li>
+				<li><a href="<%=luan_url()%>/">Luan</a> <img src="/external_link.svg"></li>
+				<li><a href="nginx.html">Nginx</a></li>
+				<li><a href="https://mailer.reactionary.software/">Mailer REST API</a> <img src="/external_link.svg"></li>
+				<li><a href="this.html">This Website</a></li>
 			</ul>
 		</div>
 	</body>
--- a/src/freedit.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/freedit.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,21 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local needed_header = Shared.needed_header or error()
+local luan_url = Shared.luan_url or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	local luan_url = luan_url()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>FreedIt - A Reddit Alternative</title>
@@ -47,7 +51,7 @@
 
 			<h3>Attempt 1 - Blasma</h3>
 
-			<p>I wrote a page describing my original thoughts on <a href="https://www.luan.software/blasma.html">Blasma</a> and later posted <a href="https://saidit.net/s/PhoenixForum/comments/7i60/my_vision_for_social_forums/">my updated thoughts</a> on SaidIt.  The basic idea was to have a distributed <a href="https://www.luan.software/">Luan</a> program with a flexible architecture that allows adding modules and having different views/templates.  At one point I even offered to pay for someone to do this.  I never got any volunteers, so this died.</p>
+			<p>I wrote a page describing my original thoughts on <a href="<%=luan_url%>/blasma.html">Blasma</a> and later posted <a href="https://saidit.net/s/PhoenixForum/comments/7i60/my_vision_for_social_forums/">my updated thoughts</a> on SaidIt.  The basic idea was to have a distributed <a href="<%=luan_url%>/">Luan</a> program with a flexible architecture that allows adding modules and having different views/templates.  At one point I even offered to pay for someone to do this.  I never got any volunteers, so this died.</p>
 
 			<h3>Attempt 2 - SaidIt clone</h3>
 
--- a/src/hg_dev.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/hg_dev.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local needed_header = Shared.needed_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Mercurial Development</title>
--- a/src/index.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/index.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local header = Shared.header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software</title>
@@ -31,13 +33,13 @@
 			<h3>Make software great again!</h3>
 			<p>For programmers who hate modern software.  Modern software is overcomplicated, bloated, unreliable, incomprehensible, pointlessly ideological, and mostly unusable.  We like the values of older software: simplicity, reliability, and usability.</p>
 			<ul links>
-				<li><a href="/about.html">About Reactionary Software</a></li>
-				<li><a href="/existing.html">Existing Reactionary Software</a></li>
-				<li><a href="/needed.html">Needed Reactionary Software</a></li>
-				<li><a href="/learn.html">Learn Reactionary Programming</a></li>
-				<li><a href="/books.html">Reactionary Programming Books</a></li>
-				<li><a href="/saving.html">Saving Programming from Modern Culture</a></li>
-				<li><a href="/discussion.html">Discussion</a></li>
+				<li><a href="about.html">About Reactionary Software</a></li>
+				<li><a href="existing.html">Existing Reactionary Software</a></li>
+				<li><a href="needed.html">Needed Reactionary Software</a></li>
+				<li><a href="learn.html">Learn Reactionary Programming</a></li>
+				<li><a href="books.html">Reactionary Programming Books</a></li>
+				<li><a href="saving.html">Saving Programming from Modern Culture</a></li>
+				<li><a href="discussion.html">Discussion</a></li>
 			</ul>
 		</div>
 	</body>
--- a/src/init.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/init.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,4 +1,6 @@
 local Hosted = require "luan:host/Hosted.luan"
+local Shared = require "site:/lib/Shared.luan"
+
 
 Hosted.set_https and Hosted.set_https(true)
 
--- a/src/java.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/java.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local existing_header = Shared.existing_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Java 8</title>
--- a/src/java_fork.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/java_fork.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local needed_header = Shared.needed_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Java Fork</title>
@@ -26,7 +28,7 @@
 		<div content>
 			<h1>Java Fork</h1>
 
-			<p><a href="/java.html">Java 8</a> is good reactionary software but is essentially unsupported.  So someone should fork it and maintain and improve it.  I suggest these improvements:</p>
+			<p><a href="java.html">Java 8</a> is good reactionary software but is essentially unsupported.  So someone should fork it and maintain and improve it.  I suggest these improvements:</p>
 
 			<ul>
 				<li>Fix inner classes as described <a href="https://mikraite.arkian.net/Jave-inner-classes-tp3503.html">here</a>.</li>
--- a/src/laf.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/laf.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local needed_header = Shared.needed_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Swing Look and Feel</title>
--- a/src/learn.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/learn.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -2,10 +2,13 @@
 local error = Luan.error
 local pairs = Luan.pairs or error()
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local header = Shared.header or error()
+local luan_url = Shared.luan_url or error()
 
 
 local content = {
@@ -189,7 +192,7 @@
 		title = [[Java 8]]
 		content = function()
 %>
-<p><a href="/java.html">Java</a> is not an easy language to learn and if you later use Python or Luan then you won't use Java much.  So why learn it first?  Because it will give you a core understanding of programming.  Also, ChatGPT understands Java very well, so this can help you learn it.  And lastly because Java will help you understand Luan.</p>
+<p><a href="java.html">Java</a> is not an easy language to learn and if you later use Python or Luan then you won't use Java much.  So why learn it first?  Because it will give you a core understanding of programming.  Also, ChatGPT understands Java very well, so this can help you learn it.  And lastly because Java will help you understand Luan.</p>
 
 <p>To learn Java, you will need the following resources:</p>
 <ul>
@@ -228,7 +231,7 @@
 		title = [[Luan]]
 		content = function()
 %>
-<p>See <a href="https://www.luan.software/learn.html">Learning Luan</a>.</p>
+<p>See <a href="<%=luan_url()%>/learn.html">Learning Luan</a>.</p>
 <%
 		end
 	}
@@ -327,10 +330,10 @@
 end
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Learn Reactionary Programming</title>
--- a/src/learn_bash.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/learn_bash.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -2,7 +2,9 @@
 local error = Luan.error
 local pairs = Luan.pairs or error()
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local header = Shared.header or error()
@@ -13,7 +15,7 @@
 		title = [[Introduction]]
 		content = function()
 %>
-<p>I really don't want to write this tutorial, but all the existing Bash tutorials are so horrible that I have no choice.  I looked at books, websites, and YouTube - all horrible.  They don't start with the basics.  They include all kinds of useless crap.  And they don't explain core concepts.  So I have no choice but to write this for my <a href="/learn.html#bash">Learn Reactionary Programming</a> Bash lesson.</p>
+<p>I really don't want to write this tutorial, but all the existing Bash tutorials are so horrible that I have no choice.  I looked at books, websites, and YouTube - all horrible.  They don't start with the basics.  They include all kinds of useless crap.  And they don't explain core concepts.  So I have no choice but to write this for my <a href="learn.html#bash">Learn Reactionary Programming</a> Bash lesson.</p>
 
 <p><a href="bash.html">Bash</a> is a <a href="https://en.wikipedia.org/wiki/Unix_shell">shell</a>, one of many, but the one I prefer.  I will focus on Mac and Windows.  I don't have Linux, and I hate Linux, so I won't discuss it.  Most of Bash is the same on Mac and Windows, but where they differ, I will discuss both.</p>
 <%
@@ -557,7 +559,7 @@
 ~/learn $ 
 </code>
 
-<p>Here I edit the file <code>file1</code> with <a href="/learn.html#editor">Sublime Text</a>, first by using the full path, and then by adding the directory to <code>PATH</code> so that Bash can find <code>subl</code>.</p>
+<p>Here I edit the file <code>file1</code> with <a href="learn.html#editor">Sublime Text</a>, first by using the full path, and then by adding the directory to <code>PATH</code> so that Bash can find <code>subl</code>.</p>
 
 <p>I have Microsoft Word on Windows.  From the Windows Command Prompt (not Bash):</p>
 
@@ -1123,10 +1125,10 @@
 end
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Bash Tutorial</title>
--- a/src/lib/Shared.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/lib/Shared.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,27 +1,52 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local ipairs = Luan.ipairs or error()
+local pairs = Luan.pairs or error()
+local Time = require "luan:Time.luan"
+local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local languages = Site_translator.languages or error()
 
 
 local Shared = {}
 
+Http.not_found_handler = Site_translator.not_found_handler or error()
+
+local started = Time.now()
+
 function Shared.head()
 %>
 		<meta name="viewport" content="width=device-width, initial-scale=1">
 		<style>
-			@import "/site.css";
+			@import "/site.css?s=<%=started%>";
 		</style>
+		<script src="/site.js?s=<%=started%>"></script>
 <%
 end
 
 local function header(crumbs)
+	local lang = get_lang()
+	local home
+	if lang == "en" then
+		home = "/"
+	else
+		home = "/"..lang.."/"
+	end
 %>
 		<div header>
 			<span breadcrumbs>
-				<a href="/">Reactionary Software</a>
+				<a href="<%=home%>">Reactionary Software</a>
 <%	for _, crumb in ipairs(crumbs or {}) do %>
 				/ <%=crumb%>
 <%	end %>
+				- <select onchange="setLanguage(value)">
+<%	for code, name in pairs(languages) do
+		local selected = code==lang and "selected" or ""
+%>
+					<option value="<%=code%>" <%=selected%> ><%=name%></option>
+<%	end %>
+				</select>
 			</span>
 			<span>by <a href="https://linkmy.style/fschmidt">fschmidt</a></span>
 		</div>
@@ -30,11 +55,20 @@
 Shared.header = header
 
 function Shared.existing_header()
-	header{[[<a href="/existing.html">Existing</a>]]}
+	header{[[<a href="existing.html">Existing</a>]]}
 end
 
 function Shared.needed_header()
-	header{[[<a href="/needed.html">Needed</a>]]}
+	header{[[<a href="needed.html">Needed</a>]]}
+end
+
+function Shared.luan_url()
+	local url = "https://www.luan.software"
+	local lang = get_lang()
+	if lang ~= "en" then
+		url = url.."/"..lang
+	end
+	return url
 end
 
 return Shared
--- a/src/lucene.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/lucene.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,20 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local needed_header = Shared.needed_header or error()
+local luan_url = Shared.luan_url or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Lucene Fork</title>
@@ -21,7 +24,7 @@
 		<div content>
 			<h1>Lucene Fork</h1>
 
-			<p>My <a href="https://www.luan.software/">Luan</a> uses <a href="https://lucene.apache.org/core/">Lucene</a> as its database, but uses an <a href="https://lucene.apache.org/core/4_9_0/">old version</a> because everything that is maintained by modern programmers only gets worse over time.  While the core idea of Lucene is very good, modern programmers have been steadily making Lucene worse and more complicated.</p>
+			<p>My <a href="<%=luan_url()%>/">Luan</a> uses <a href="https://lucene.apache.org/core/">Lucene</a> as its database, but uses an <a href="https://lucene.apache.org/core/4_9_0/">old version</a> because everything that is maintained by modern programmers only gets worse over time.  While the core idea of Lucene is very good, modern programmers have been steadily making Lucene worse and more complicated.</p>
 
 			<p>There is no good reactionary database that I know of.  Lucene seems like the best starting point.  The two options are forking Lucene or rewriting it.  Either way, this is badly needed because any serious application needs a database.  I would be glad to help in any way that I can if someone would take this project.</p>
 
--- a/src/mercurial.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/mercurial.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local existing_header = Shared.existing_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Mercurial</title>
--- a/src/nabble.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/nabble.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,20 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local needed_header = Shared.needed_header or error()
+local luan_url = Shared.luan_url or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Forum</title>
@@ -21,15 +24,15 @@
 		<div content>
 			<h1>Forum - Nabble Rewrite</h1>
 
-			<p><a href="https://www.nabble.com/">Nabble</a> is ancient forum software that I helped write that I still use for many forums.  For example the <a href="/discussion.html">discussion</a> forum for this site uses Nabble.  Nabble allows threads to be assigned to users, making it useful for managing work.  Nabble is written is Java and is overcomplicated code.  Here is <a href="https://hg.reactionary.software/repo/nabble/">the source</a>.</p>
+			<p><a href="https://www.nabble.com/">Nabble</a> is ancient forum software that I helped write that I still use for many forums.  For example the <a href="discussion.html">discussion</a> forum for this site uses Nabble.  Nabble allows threads to be assigned to users, making it useful for managing work.  Nabble is written is Java and is overcomplicated code.  Here is <a href="https://hg.reactionary.software/repo/nabble/">the source</a>.</p>
 
-			<p>I developed a macro language for Nabble that I ended up hating.  I developed <a href="https://www.luan.software/">Luan</a> as a reaction to the problems with Nabble.  I had planned to rewrite Nabble in Luan, but I never got around to it.</p>
+			<p>I developed a macro language for Nabble that I ended up hating.  I developed <a href="<%=luan_url()%>/">Luan</a> as a reaction to the problems with Nabble.  I had planned to rewrite Nabble in Luan, but I never got around to it.</p>
 
-			<p>Later I thought of developing a Reddit alternative in Luan to support free speech.  This idea was called <a href="/freedit.html">FreedIt</a>.  But now that I have given up on humanity, I no longer care about free speech.</p>
+			<p>Later I thought of developing a Reddit alternative in Luan to support free speech.  This idea was called <a href="freedit.html">FreedIt</a>.  But now that I have given up on humanity, I no longer care about free speech.</p>
 
 			<p>So why rewrite Nabble in Luan?  I would benefit from no longer having to support Nabble.  Users would benefit from having a supported forum platform.  There are still Nabble users who would benefit from this.  In addition, any programming project involving multiple people could use Nabble to manage the project.  I haven't seen a better way of managing online projects than Nabble.</p>
 
-			<p>This is a mid-size programming project, not nearly as involved as something like <a href="/lucene.html">forking Lucene</a>.  You would learn a lot about programming from doing this project, and of course I would support you.  If you are crazy enough to believe in free speech for humanity, or masochistic enough to have an interest in business, then you could later add social elements to Nabble as I discussed for FreedIt.</p>
+			<p>This is a mid-size programming project, not nearly as involved as something like <a href="lucene.html">forking Lucene</a>.  You would learn a lot about programming from doing this project, and of course I would support you.  If you are crazy enough to believe in free speech for humanity, or masochistic enough to have an interest in business, then you could later add social elements to Nabble as I discussed for FreedIt.</p>
 
 		</div>
 	</body>
--- a/src/needed.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/needed.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local needed_header = Shared.needed_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Needed Reactionary Software</title>
@@ -21,11 +23,11 @@
 		<div content>
 			<h1>Needed Reactionary Software</h1>
 			<ul links>
-				<li><a href="/lucene.html">Lucene Fork</a></li>
-				<li><a href="/nabble.html">Forum - Nabble Rewrite</a></li>
-				<li><a href="/hg_dev.html">Mercurial Development</a></li>
-				<li><a href="/laf.html">Swing Look and Feel</a></li>
-				<li><a href="/java_fork.html">Java Fork</a></li>
+				<li><a href="lucene.html">Lucene Fork</a></li>
+				<li><a href="nabble.html">Forum - Nabble Rewrite</a></li>
+				<li><a href="hg_dev.html">Mercurial Development</a></li>
+				<li><a href="laf.html">Swing Look and Feel</a></li>
+				<li><a href="java_fork.html">Java Fork</a></li>
 			</ul>
 		</div>
 	</body>
--- a/src/nginx.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/nginx.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local existing_header = Shared.existing_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Nginx</title>
@@ -21,7 +23,7 @@
 		<div content>
 			<h1>Nginx</h1>
 
-			<p>As a disclaimer, I haven't worked with <a href="https://nginx.org/en/">Nginx</a> directly.  My sysadmin manages it.  But I believe that it is good reactionary software.  Nginx works reliably.  It doesn't seem to be based on any senseless modern ideology.  Its developers are from Russia, outside of the depraved West.  And most tellingly, its <a href="http://hg.nginx.org/nginx/">source code</a> is on <a href="/mercurial.html">Mercurial</a>.</p>
+			<p>As a disclaimer, I haven't worked with <a href="https://nginx.org/en/">Nginx</a> directly.  My sysadmin manages it.  But I believe that it is good reactionary software.  Nginx works reliably.  It doesn't seem to be based on any senseless modern ideology.  Its developers are from Russia, outside of the depraved West.  And most tellingly, its <a href="http://hg.nginx.org/nginx/">source code</a> is on <a href="mercurial.html">Mercurial</a>.</p>
 		</div>
 	</body>
 </html>
--- a/src/python.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/python.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,19 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local existing_header = Shared.existing_header or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - Python</title>
--- a/src/saving.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/saving.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,20 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local header = Shared.header or error()
+local luan_url = Shared.luan_url or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Saving Programming from Modern Culture</title>
@@ -30,7 +33,7 @@
 
 			<p>I found what I think is <a href="https://map.churchindex.org/church-profile.php?id=c7797e65-90ff-11ee-b0e9-00163eb3bc90">the optimal church</a> <a href="https://maps.app.goo.gl/FKj2uoSBV3QiomS79">in north Mexico</a>.  When I visited them, I didn't have a clear plan of what to do.  A number of them are carpenters and they expressed an interest in better carpentry software.  So now my plan is to develop good tools for programming carpentry software, and then try to get a Mennonite from this church to work with me on implementing a carpentry program.  If he can make money by selling this program to other Mennonites, then I hope that this becomes a seed that encourages other Mennonites to learn good programming.</p>
 
-			<p>My recent programming has been web development, so my programming tools are designed for this.  But for carpentry software, I need to support a desktop user interface and 3D rendering.  It will take me some time to develop these tools.  First I will implement a text editor in <a href="https://www.luan.software/">Luan</a> as a real application that requires a desktop user interface.  Then I will implement basic 3D rendering.  Only after these are done will I go back to the Mennonite church to discuss my plan with them.</p>
+			<p>My recent programming has been web development, so my programming tools are designed for this.  But for carpentry software, I need to support a desktop user interface and 3D rendering.  It will take me some time to develop these tools.  First I will implement a text editor in <a href="<%=luan_url()%>/">Luan</a> as a real application that requires a desktop user interface.  Then I will implement basic 3D rendering.  Only after these are done will I go back to the Mennonite church to discuss my plan with them.</p>
 
 			<h2>Japan</h2>
 
--- a/src/site.css	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/site.css	Fri May 02 17:17:52 2025 -0600
@@ -37,7 +37,7 @@
 	margin: 12px 0;
 }
 
-img[src="external_link.svg"] {
+img[src="/external_link.svg"] {
 	height: 12px;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/site.js	Fri May 02 17:17:52 2025 -0600
@@ -0,0 +1,11 @@
+'use strict';
+
+function setLanguage(lang) {
+	console.log(lang);
+	let path = location.pathname;
+	if( path.match(/^\/[a-z]{2}\//) )
+		path = path.substring(3);
+	if( lang !== 'en' )
+		path = "/" + lang + path;
+	location = path;
+}
--- a/src/this.html.luan	Wed Apr 23 20:10:03 2025 -0600
+++ b/src/this.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -1,17 +1,20 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
 local Io = require "luan:Io.luan"
-local Http = require "luan:http/Http.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
 local Shared = require "site:/lib/Shared.luan"
 local head = Shared.head or error()
 local existing_header = Shared.existing_header or error()
+local luan_url = Shared.luan_url or error()
 
 
 return function()
-	Io.stdout = Http.response.text_writer()
+	Io.stdout = text_writer()
 %>
 <!doctype html>
-<html>
+<html lang="<%=get_lang()%>">
 	<head>
 <%		head() %>
 		<title>Reactionary Software - This Website</title>
@@ -21,7 +24,7 @@
 		<div content>
 			<h1>This Website</h1>
 
-			<p>This website is a tiny example of reactionary software.  The UI is clean and simple, not fashionable.  View the HTML source in the browser.  Unlike all modern websites, the HTML here is readable.  Now look at <a href="https://hg.reactionary.software/repo/reactionary">the source</a> which is in <a href="/mercurial.html">Mercurial</a>.  And the code is written in <a href="https://www.luan.software/">Luan</a> which makes it simple.</p>
+			<p>This website is a tiny example of reactionary software.  The UI is clean and simple, not fashionable.  View the HTML source in the browser.  Unlike all modern websites, the HTML here is readable.  Now look at <a href="https://hg.reactionary.software/repo/reactionary">the source</a> which is in <a href="mercurial.html">Mercurial</a>.  And the code is written in <a href="<%=luan_url()%>/">Luan</a> which makes it simple.</p>
 		</div>
 	</body>
 </html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/translating.html.luan	Fri May 02 17:17:52 2025 -0600
@@ -0,0 +1,29 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local Io = require "luan:Io.luan"
+local Site_translator = require "luan:gpt/Site_translator.luan"
+local get_lang = Site_translator.get_lang or error()
+local text_writer = Site_translator.text_writer or error()
+local Shared = require "site:/lib/Shared.luan"
+local head = Shared.head or error()
+local header = Shared.header or error()
+
+
+return function()
+	Io.stdout = text_writer()
+%>
+<!doctype html>
+<html lang="<%=get_lang()%>">
+	<head>
+<%		head() %>
+		<title>Luan</title>
+	</head>
+	<body>
+<%		header() %>
+		<div content>
+			<p>Translating, please try again in a minute...</p>
+		</div>
+	</body>
+</html>
+<%
+end