Multi-language Support
To enable support for multiple languages in your SØAD application, you can use the built-in internationalization (i18n) features. These features allow you to deliver localized content tailored to the user's language preferences.
Here’s an example of how to update the messages.properties file to include translations for various languages (using Transaction):
lang.py
from utils import render
from java.io import File
from java.nio.charset import StandardCharsets
from java.util import ResourceBundle
from com.google.common.io import Files
class Lang(object):
def view(self, ctx):
pass
def get_content(self, ctx):
request = ctx.getRequest()
lang = request.getParameter("lang")
if not lang:
lang = "en"
file_name = None
if lang == "en":
file_name = "messages.properties"
elif lang == "ms":
file_name = "messages_ms.properties"
elif lang == "zh":
file_name = "messages_zh.properties"
if file_name:
file_path = request.getServletContext().getRealPath("/WEB-INF/classes/%s" % file_name)
file = File(file_path)
if not file.exists():
file.createNewFile()
if file_path:
content = Files.asCharSource(file, StandardCharsets.UTF_8).read()
ctx.go_to = render.as_string(ctx, content)
return
ctx.go_to = render.as_string(ctx, "")
def save(self, ctx):
request = ctx.getRequest()
lang = request.getParameter("lang")
content = request.getParameter("content")
file = None
if lang == "en":
file = "messages.properties"
elif lang == "ms":
file = "messages_ms.properties"
elif lang == "zh":
file = "messages_zh.properties"
if file and content:
pfile = request.getServletContext().getRealPath("/WEB-INF/classes/%s" % file)
if pfile:
Files.asCharSink(File(pfile), StandardCharsets.UTF_8).write(content)
ctx.go_to = render.as_json(ctx, {"success": True})
ResourceBundle.clearCache()
return
ctx.go_to = render.as_json(ctx, {"success": False})
lang.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Manage Language</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
#my-editor {
height: 750px;
width: 100%;
}
</style>
</head>
<body>
<div id="s0-crud-body">
<div class="row">
<div class="col">
<div class="card">
<div class="card-header">
<div class="d-flex justify-content-between">
<h5 class="heading mb-0">Manage Language</h5>
<div>
<a class="btn btn-default btn-sm b_sel" id="b_sel_en" data-val="en" href="#">
English
</a>
<a class="btn btn-default btn-sm b_sel" data-val="ms" href="#">
Bahasa Melayu
</a>
<a class="btn btn-default btn-sm b_sel" data-val="zh" href="#">
Mandarin
</a>
</div>
</div>
</div>
<div class="card-body">
<div id="my-editor"></div>
</div>
</div>
</div>
</div>
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="liveToast" class="toast" role="alert" aria-live="assertive" aria-atomic="true" data-bs-delay="5000" data-bs-autohide="true">
<div class="toast-body">
<center>Save Success</center>
</div>
</div>
</div>
</div>
<style>
</style>
<!-- JS -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.36.2/ace.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.36.2/mode-properties.min.js"></script>
<script>
var currentLang = "en";
$(function() {
$(".b_sel").click(function() {
if (!window.editorCode.session.getUndoManager().isClean()) {
alert("Unsaved Changes");
return;
}
doLoad($(this).attr("data-val"));
$(".b_sel").each(function(i, elem) {
$(elem).removeClass("btn-primary");
});
$(this).addClass("btn-primary");
});
$("#b_sel_en").click();
window.myToast = new bootstrap.Toast(document.getElementById("liveToast"), {})
});
function doLoad(lang) {
$.get("{{ctxPath}}/t/example/lang/get_content", {"lang":lang}, function(data) {
currentLang = lang;
window.editorCode.session.setValue(data);
window.editorCode.session.getUndoManager().reset();
}, "text");
}
function doSave() {
var opaque = window.editorCode.getValue();
$.post("{{ctxPath}}/t/example/lang/save", {"lang":currentLang, "content":opaque}, function(data) {
if (data.success) {
window.myToast.show();
window.editorCode.session.getUndoManager().reset();
}
});
}
window.editorCode = ace.edit("my-editor");
window.editorCode.session.setMode("ace/mode/properties");
window.editorCode.setAutoScrollEditorIntoView(true);
window.editorCode.setShowPrintMargin(false);
window.editorCode.session.getUndoManager().reset();
window.editorCode.commands.addCommand({
name: 'save',
bindKey: {win: "Ctrl-S", "mac": "Cmd-S"},
exec: function(editor) {
doSave(false);
}
});
</script>
</body>
</html>
To support multiple languages, you need to create separate properties files for each language. Here’s how you can structure your properties files:
Tips
If you're using a containerized environment, consider mounting the properties files to the /app/conf/ directory. This directory is included in the classpath.