Translation Notes

Interested in translating CS Circles to your language? We'd love to help you do it!

You have two options:

  1. host your translation on
    • we are hosting french, german, dutch, lithuanian
    • it will stay "private" until you are ready for it to be publicized
    • your work will be Creative Commons licensed unless you desire otherwise
  2. host everything on your own site

The instructions below are for option 1 (hosting here). If you host yourself, you have lots of flexibility, but we don't have documentation right now beyond the two links above.

How is it done?

We use the WordPress "polylang" package that allows a fairly flexible way of creating translations of different pages, plus "gettext" which is a standard GNU utility for translation.

The various components involved in doing a translation are:

  • Done in WordPress:
    • translating the prose in each lesson
    • translating the descriptions for the exercises
    • translating the literal text or variable names in the exercises' programs
    • translating the names of pages
  • Done with a gettext .po file (emacs is a good editor for this):
    • translating the "gettext" file that contains the across-site UI elements like button labels such as "Run Program" and the across-exercise grader text like "Program crashed."
  • Done separately:
    • translating images or other standalone files
    • translating the error message hints
  • Also:
    • when you provide a translation, we might start getting "Help" questions in your language, that we will redirect to your account (or someone else you know who speaks your language)

You can translate it in part or whole, depending on how much effort you are able to invest. Not all the sites have to mirror each other: they can have extra or missing lessons, different menu layouts, etc.

How to Get Started

The first step is to create an account and tell us you want to translate it to your language, and your account name.

We will have to grant your account editor access, change some settings, and create empty pages for you to fill in.

WordPress Editing in a Nutshell

If you are a translator, you will see extra languages like "nl" on the green title bar at the top of the website. Clicking here will take you to view the translated version of the current page, when it is available. To edit pages, click on "Editor" on the same green title bar. This will bring you a list of all of the pages which you have access to edit.

The editor has two modes, Visual and HTML; sometimes one mode is easier to use than the other, you can use whichever one you prefer. Normally you'll use the visual editor for the most part and the HTML one when you have to do precise formatting.

In the editor, you can also access the Revision History (you may first need to click on Screen Options in the top right). The revision history shows previous versions, and who edited each one. Additionally, WordPress will try to tell you if you are about to edit a page that someone else is currently editing. For these reasons, you don't need to exercise too much caution about breaking things, since problems are generally fixable.

Starting to Translate


Ask Dave to create an up-to-date "translation package." The most important directories are pages-translation-stubs, which give you a translator's template for each page, and pages-english-originals, which is the actual English source for each page (needed mostly for fine-tuning pyRecall as explained below).

Translating the pages in WordPress

Our pages are written in a slightly-extended version of HTML using "WordPress shortcodes". Skim through the authoring page to see how they work. To edit shortcodes, it is pretty important to know how quotes are escaped (see again the authoring page). In brief, you can contain arguments with either single or double quotes, and you must backslash-escape that quote symbol.

To actually translate a page, open up a file such as pages-translation-stubs/0-introduction.txt on your computer and copy it into the appropriate WordPress page. Translating the prose should be straightforward.

Translating examples is also relatively straightforward if you understand the shortcode syntax. The same is true for pyWarn/pyHint. If you don't just let us know for help.

Translating exercises is the trickiest part, because sometimes you'll want to translate everything, and other times you might only want to translate a few words. This is what we designed the pyRecall shortcode for. It finds an English exercise from the database and allows you to

  • selectively override any option,
  • and/or provide problem-wide translation strings.

Here's the first exercise, in pages-translation-stubs/0-introduction.txt:

[pyRecall slug="0.bonjour" title="Bonjour"]
Write a program which prints
<pre>Bonjour, tout le monde!</pre>
(Hint: if you get stuck, copy the 
[pyHint hint='The first program was <pre>print("Hello, World!")</pre> <em>You can drag this hint box to move it.</em>']
first program above[/pyHint]
and then edit it.)[/pyRecall]
  • The slug option controls which pre-existing shortcode you are translating. Don't change that.
  • You can change the title
  • You should change all the other text.

What about all the other options? What if you want the student to have to write "سلام جهان" instead of "Bonjour, tout le monde!"? Then it makes sense to look at how we originally defined the problem in English. If you go into that other directory from the zip file and open pages-english-originals/0-introduction.txt then you'll see the pyBox with slug 0.bonjour; it uses additional options called grader, rows, and answer (specifically, grader="@file:graders/" answer="Bonjour, tout le monde!" rows=2) The answer one seems relevant. There are two ways to proceed.

  1. Override it. Add answer="سلام جهان" to your pyRecall.
  2. Use the translate option. Add translate="Bonjour, tout le monde!\nسلام جهان" to your pyRecall.
    • This approach is extremely useful if you want to change variables name or anything that occurs multiple times or in multiple options. The translation pair will be applied to all arguments (and loaded helper files).
    • If you have multiple strings to translate, the argument should be translate="en1\ntr1\nen2\ntr2..." where enx and trx are the English and translated versions of some string. See French lesson 7C, which uses translate, e.g. for 7c.skip.

Technical note about pyRecall: In translation, you will be given templates that include the epilogue, wrong, right, and defaultcode options when they exist, since they're normally large blocks of text that aren't well-handled with the translate="..." option. If you don't want an option (say defaultcode) translated and just want to use the original text, you can delete the defaultcode="..." option (or the other ones). Only title and slug are truly mandatory.

Additional Translation Steps

  • (.po file) Copy the French .po file to create one for your language; we recommend editing it in emacs, but many other tools exist. You'll send us the completed version.
  • (lesson_files directory) In the WordPress pages, sometimes you will want to replace an @file reference (see the authoring page) with a translated version of that file. (The @file references refer to the files in the lesson_files subdirectory of the translation package.) For example, look at the French translation of lesson 3, and compare the @file references with those in the English version. Send us the files you want uploaded and change your @file reference to point to the renamed file. Only some files in the "lesson_files" directory benefit from translation. The ones that have a copy named *-fr or *-de are ones we found useful to translate for French or German.
  • (error hints) If you want the clickable links that appear with common error messages to give explanations in your language, change the values in this PHP file and send us a copy.
  • Add your name as translator to the hidden "authorship info" blurb at the top of each page.
  • Once things are up and running, we will create your language's menu layout, populate the lesson database (for the Progress page and prev/next lesson buttons), and make it public!

Supporting Users

The "CS Circles Assistant" feature allows students to ask questions when they are stuck. For every new language that we translate to, we will need to have someone who is capable of fulfilling this role (or multiple people who wish to split the work). This involves:

  • Designating a CS Circles account as that language's assistant.
  • It will get an email whenever there's a new question from someone using that language version of the site.
  • They should answer in the website's mail interface.
  • This work can be split among multiple people by setting the account's email to a mailing list and having them all know the account password to log in.

If you have any questions or if anything looks broken, you can let Dave know. Thanks for helping! We have very promising feedback so far and we're super happy to reach people in new languages.