- Adopted postcss and tailwind config to new version - renamed colors bluegray->slate etc to not have custom definitions (hope to reduce migration next time) - tailwind now doesn't build the complete css anymore, so the `dev-ui-build` script must compile both
12 KiB
+++ title = "Translating Web-UI" weight = 10 +++
Help with translating the web-ui is greatly appreciated. I can only provide translations for English and German, and these may be wrong - so pointing out mistakes is also appreciated :).
Here is a detailed walkthrough for adding a new language. It requires to code in Elm. But even if you're not a programmer, you will be comfortable as it's not difficult for this task. Elm is also a nice and friendly language, provding helpful error messages.
This guide assumes no knowledge about Elm at all.
TL;DR
If you are already familiar with Elm, here is the TL;DR:
- Goto
Messages.UiLanguage
inmodules/webapp/src/main/elm
and add another language to the union type and also to theall
list. - Fix all compile errors by providing a different
Texts
value for the new language.
Prepare
You need to install git,
sbt, Elm and
nodejs (for the npm
command) to
compile and run the project.
It is also recommended to install elm-format
as it will help you to
format the elm source code. Look
here for how to install it with
your editor of choice.
Checkout the source code
Note: These steps are only required to do once. If you come back to translating, just start the application.
Use git to clone the docspell repository to your machine. In a terminal type:
❯ git clone https://github.com/eikek/docspell.git
Cloning into 'docspell'...
remote: Enumerating objects: 1861, done.
remote: Counting objects: 100% (1861/1861), done.
remote: Compressing objects: 100% (861/861), done.
remote: Total 30276 (delta 821), reused 1604 (delta 668), pack-reused 28415
Receiving objects: 100% (30276/30276), 60.89 MiB | 23.62 MiB/s, done.
Resolving deltas: 100% (14658/14658), done.
/tmp took 4s
❯
This creates a new directory docspell
. Change into it, create a
DOCSPELL_ENV
environment variable and run sbt:
❯ cd docspell
docspell on master via 🌳 v0.19.1 via ☕ v11.0.9 via ⬢ v12.21.0
❯ export DOCSPELL_ENV=dev
❯ sbt
[info] welcome to sbt 1.5.0 (Oracle Corporation Java 1.8.0_212)
[info] loading settings for project global-plugins from plugins.sbt ...
[info] loading settings for project docspell-build from plugins.sbt ...
[info] loading project definition from /tmp/docspell/project
[info] compiling 6 Scala sources to /tmp/docspell/project/target/scala-2.12/sbt-1.0/classes ...
[info] loading settings for project root from build.sbt,version.sbt ...
[info] resolving key references (24191 settings) ...
[info] set current project to docspell-root (in build file:/tmp/docspell/)
[info] sbt server started at local:///home/eike/.sbt/1.0/server/3cf61b9ad9af43ee6032/sock
[info] started sbt server
sbt:docspell-root>
This downloads some stuff and puts you in the sbt shell. Now compile everything (only needed the first time after checkout):
sbt:docspell-root> make
This will take a while, you need to wait until this is finished.
Start the application
If sbt is not started, start sbt from within the source root. Also
export the DOCSPELL_ENV
variable before starting sbt:
> export DOCSPELL_ENV=dev
> sbt
Then start the application:
sbt:docspell-root> reStart
This starts docspell (joex and the restserver). Once the output gets a
bit quiter, open a browser and navigate to http://localhost:7880
.
You can create a new account (if not already done so) and login.
Note that the database is created in your /tmp
directory, so it
might be cleared once you restart your machine. For translating this
should not be a problem.
Make webui updates faster
The sbt build tool could be used to watch the elm sources and
re-compile everything on change. This however also restarts the server
and takes quite long. When only coding on the webui the server can be
just left as is. Only the new compiled webapp must be made available
to the running server. For this, a script is provided in the
project/
folder.
Now open two more terminals and cd
into the docspell folder as before
and run the following in one:
❯ ./project/dev-ui-build.sh watch-js
Compile elm to js …
Success!
Main ───> /tmp/docspell/modules/webapp/target/scala-2.13/classes/META-INF/resources/webjars/docspell-webapp/0.22.0-SNAPSHOT/docspell-app.js
Watching elm sources. C-c to quit.
Setting up watches. Beware: since -r was given, this may take a while!
Watches established.
And in the other run this:
❯ ./project/dev-ui-build.sh watch-css
Watching css …
Once you have this, you're all set. The docspell application is running and changes to elm and css files are detected, the webapp is compiled and the resulting javascript and css file is copied to the correct location. To see your changes, a refresh in the browser is necessary.
If this script is not working, install inotify-tools. The
inotifywait
command is required.
You'll notice that compiling elm and css is very fast.
Find the webapp sources
The web-ui is implemented in the webapp
module. The sources can be
found in the folder modules/webapp/src/main/elm
.
All translated strings are in the files below Messages
directory.
You should start with the file UiLanguage.elm
to add a new language
to the list. Then start with App.elm
to provide transalations. See
below for details.
Example: Add German
Add the new language
Start by editing UiLanguage.elm
and add another language to the
list:
type UiLanguage
= English
| German
More languaes are simply appended using the |
symbol. Use the
English name here, because this is source code.
Also add it to the list of all languages below. Simply add the new
language separated by a comma ,
.
all : List UiLanguage
all =
[ English
, German
]
If you make a mistake, the elm compiler will tell you with usually quite helpful messages. Now, after adding this, there will be errors when compiling the elm files. You should see something like this:
Detected problems in 1 module.
-- MISSING PATTERNS ------------------- modules/webapp/src/main/elm/Messages.elm
This `case` does not have branches for all possibilities:
45|> case lang of
46|> English ->
47|> gb
Missing possibilities include:
German
I would have to crash if I saw one of those. Add branches for them!
Hint: If you want to write the code for each branch later, use `Debug.todo` as a
placeholder. Read <https://elm-lang.org/0.19.1/missing-patterns> for more
guidance on this workflow.
So around line 45 in Messages.elm
there is something wrong. This is
the place where a record of all strings is returned given some
lanugage. Currently, there is only one set of strings for English.
Open this file, you see at the and a value of name gb
for English.
Copy it to another name, de
for this example (it's good practice to
stick to the two letter country code).
de : Messages
de =
{ lang = German
, iso2 = "de"
, label = "Deutsch"
, flagIcon = "flag-icon flag-icon-de"
, app = Messages.App.gb
, collectiveSettings = Messages.Page.CollectiveSettings.gb
, login = Messages.Page.Login.gb
, register = Messages.Page.Register.gb
, newInvite = Messages.Page.NewInvite.gb
, upload = Messages.Page.Upload.gb
, itemDetail = Messages.Page.ItemDetail.gb
, queue = Messages.Page.Queue.gb
, userSettings = Messages.Page.UserSettings.gb
, manageData = Messages.Page.ManageData.gb
, home = Messages.Page.Home.gb
}
Change lang
, iso2
, label
and flagIcon
appropriately. For the
label
use the native language name (not English), as this is the
label shown to users when selecting a language. The flag icon can be
copied and only the last two letters need to be changed to the country
code. You may look here for
additional information.
Now the error can be fixed. Go to line 45 and add another branch to
the case
expression:
get : UiLanguage -> Messages
get lang =
case lang of
English ->
gb
German ->
de
This makes the compiler happy again. If you refresh the browser, you should see the new language in the dropdown menu. You can already choose the new language, but nothing happens in the application. Of course, we just copied the English strings for now. So now begins the translation process.
Translating
Now translation can begin. If you look at the newly created value
de
, you'll see some entries in the record. Each corresponds to a
page: login
is for the login page, home
for the "home page" etc;
and app
is for the top menu.
Take one of them and start translating. For the example, I use the
first one which is Messages.App
. The file to this is
Messages/App.em
. You can always replace the dots with slashes to
find a file to an elm module. Open this file and you'll see again a
gb
value at the end. Copy it to de
and start translating:
de : Texts
de =
{ collectiveProfile = "Kollektiv-Profil"
, userProfile = "Benutzer-Profil"
, lightDark = "Hell/Dunkel"
, logout = "Abmelden"
, items = "Dokumente"
, manageData = "Daten verwalten"
, uploadFiles = "Dateien hochladen"
, processingQueue = "Verarbeitung"
, newInvites = "Neue Einladung"
, help = "Hilfe (English)"
}
Then go to the beginning of the file and add the new de
value to the
list of "exposed" values. This is necessary so it can be used from
within the Messages.elm
module.
module Messages.App exposing
( Texts
, de {- the new value -}
, gb
)
Now you can go back to Messages.elm
and exchange Messages.App.gb
with Messages.App.de
.
de : Messages
de =
{ lang = German
, iso2 = "de"
, label = "Deutsch"
, flagIcon = "flag-icon flag-icon-de"
, app = Messages.App.de
, collectiveSettings = Messages.Page.CollectiveSettings.gb
, login = Messages.Page.Login.gb
, register = Messages.Page.Register.gb
, newInvite = Messages.Page.NewInvite.gb
, upload = Messages.Page.Upload.gb
, itemDetail = Messages.Page.ItemDetail.gb
, queue = Messages.Page.Queue.gb
, userSettings = Messages.Page.UserSettings.gb
, manageData = Messages.Page.ManageData.gb
, home = Messages.Page.Home.gb
}
If you refresh the browser, you should now see the new values. Then take the next entry and start over. It happens that some files contain other string-sets of certain components. Then just follow this guide recursively.
Publishing
You can publish your work to this repo in various ways:
Github PR
This is the preferred way, because it means less work for me :). If you have a github account, you can create a pull request. Here is a quick walk-through. There is a thorough help at github.
- Fork this repository in the github webapp
- Go to the docspell source root you checked out in the terminal. Run:
git remote rename origin upstream git remote add origin git@github.com:<your-github-name>/docspell.git git fetch --all
- Create a new git branch:
git checkout -b translate origin/master
- Make a commit of your changes:
Modify the message to your needs.git config user.name "Your Name" git config user.email "Your Email" #(note that this email will be publicly viewable! a dummy address is fine, too) git commit -am 'Add translation for German'
- Push the change to your fork:
git push origin translate
- Go to the github webapp and create a pull request from your branch.
You can send me the patch via e-mail. You can use git send-email
or
your favorite e-mail client. For this do step 4 from above and then:
git bundle create translation.bundle origin/master..HEAD
Then send the created translate.bundle
file. If this command doesn't
work, try:
git format-patch origin/master..HEAD
This results in one or more 0001-…
files that you can send.
Any other
Contact me by mail or create an issue.