working on translation system
This commit is contained in:
@@ -1,11 +1,21 @@
|
||||
/* © SRSoftware 2025 */
|
||||
package de.srsoftware.umbrella.core.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public interface Translator {
|
||||
public default String translate(String language, String text){
|
||||
return translate(language, text, Map.of());
|
||||
var parts = text.split("\\|");
|
||||
var fills = new TreeMap<String,String>();
|
||||
if (parts.length>1) for (var idx=1;idx<parts.length;idx++){
|
||||
var nested = parts[idx].split("=",2);
|
||||
if (nested.length<2){
|
||||
fills.put("{"+idx+"}",nested[0]);
|
||||
} else fills.put(nested[0],nested[1]);
|
||||
}
|
||||
return translate(language, parts[0], fills);
|
||||
}
|
||||
public String translate(String language, String text, Map<String,String> fills);
|
||||
}
|
||||
|
||||
24
core/src/test/java/TranslatorTest.java
Normal file
24
core/src/test/java/TranslatorTest.java
Normal file
@@ -0,0 +1,24 @@
|
||||
import de.srsoftware.umbrella.core.api.Translator;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static java.text.MessageFormat.format;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class TranslatorTest {
|
||||
|
||||
private static final Translator translator = new Translator() {
|
||||
@Override
|
||||
public String translate(String language, String text, Map<String, String> fills) {
|
||||
return format("lang: {0}, text: {1}, fills: {2}",language,text, new JSONObject(fills).toString());
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testTranslate(){
|
||||
var translated = translator.translate("none","dies {verb} ein {subject}|subject=test|verb=ist");
|
||||
assertEquals("lang: none, text: dies {verb} ein {subject}, fills: {\"verb\":\"ist\",\"subject\":\"test\"}",translated);
|
||||
}
|
||||
}
|
||||
@@ -355,7 +355,7 @@ public class DocumentApi extends BaseHandler {
|
||||
.filter(filter)
|
||||
.findAny();
|
||||
if (optDoc.isEmpty()) throw UmbrellaException.notFound("Cannot render {0} {1}: Missing template \"{2}\"",type,document.number(),template);
|
||||
Function<String,String> translate = text -> translator.translate(user.language(),"document."+text.replaceAll(" ","_"));
|
||||
Function<String,String> translate = text -> translator.translate(user.language(),text);
|
||||
var pdfData = new HashMap<String,Object>();
|
||||
pdfData.put(FIELD_DOCUMENT,document.renderToMap());
|
||||
pdfData.put("translate",translate);
|
||||
|
||||
@@ -64,6 +64,11 @@ public abstract class TemplateDoc implements Document {
|
||||
var config = new JsonConfig(new JSONObject(data));
|
||||
source = renderPositions(source,config.subset("document.positions"),price);
|
||||
source = renderTaxes(source,config.subset("document.taxes"),price);
|
||||
|
||||
var opt = data.get("translate");
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<String,String> translate = opt instanceof Function<?,?> fun ? (Function<String,String>) fun : s -> s;
|
||||
|
||||
var tokens = findTokensIn(source);
|
||||
for (var token : tokens){
|
||||
var val = config.get(token).map(Object::toString);
|
||||
@@ -74,13 +79,10 @@ public abstract class TemplateDoc implements Document {
|
||||
default -> value;
|
||||
};
|
||||
if (MIME_HTML.equals(mimeType())) value = value.replace("\n","<span class=\"break\"></span>\n");
|
||||
source = source.replace("<? "+token+" ?>",value);
|
||||
source = source.replace("<? "+token+" ?>",translate.apply(value));
|
||||
}
|
||||
}
|
||||
tokens = findTokensIn(source);
|
||||
var opt = data.get("translate");
|
||||
@SuppressWarnings("unchecked")
|
||||
Function<String,String> translate = opt instanceof Function<?,?> fun ? (Function<String,String>) fun : s -> s;
|
||||
for (var token : tokens){
|
||||
var value = translate.apply(token);
|
||||
if (MIME_HTML.equals(mimeType())) value = value.replace("\n","<span class=\"break\"></span>\n");
|
||||
|
||||
@@ -132,13 +132,13 @@
|
||||
<div class="sender data">
|
||||
<? document.sender.name ?><br/>
|
||||
<br/>
|
||||
<? delivery date ?>: <? document.delivery ?>
|
||||
<? delivery_date ?>: <? document.delivery ?>
|
||||
</div>
|
||||
</header>
|
||||
<h1><? document.type ?></h1>
|
||||
<h2>
|
||||
<span class="left"><? document.type ?> <? document.number ?></span>
|
||||
<span class="center"><? customer id ?>: <? document.customer.id ?></span>
|
||||
<span class="center"><? customer_id ?>: <? document.customer.id ?></span>
|
||||
<span class="right"><? document.date ?></span>
|
||||
</h2>
|
||||
<hr/>
|
||||
@@ -147,10 +147,10 @@
|
||||
<tr>
|
||||
<th><? position ?></th>
|
||||
<th><? description ?></th>
|
||||
<th><? price per unit ?></th>
|
||||
<th><? unit_price ?></th>
|
||||
<th><? amount ?></th>
|
||||
<th><? price ?></th>
|
||||
<th><? tax rate ?></th>
|
||||
<th><? tax_rate ?></th>
|
||||
</tr>
|
||||
|
||||
<!-- positions -->
|
||||
@@ -171,7 +171,7 @@
|
||||
<!-- positions -->
|
||||
|
||||
<tr>
|
||||
<th class="right" colspan="5"><? net sum ?>:</th>
|
||||
<th class="right" colspan="5"><? net_sum ?>:</th>
|
||||
<th class="right"><? document.net_sum ?></th>
|
||||
</tr>
|
||||
|
||||
@@ -181,13 +181,13 @@
|
||||
<td></td>
|
||||
<td><? net_sum ?> + <? rate ?> =</td>
|
||||
<td><? gross_sum ?></td>
|
||||
<td colspan="2"><? contained tax ?>:</td>
|
||||
<td colspan="2"><? contained_tax ?>:</td>
|
||||
<td><? amount ?></td>
|
||||
</tr>
|
||||
|
||||
<!-- tax list -->
|
||||
<tr>
|
||||
<th class="right" colspan="5"><? gross sum ?>:</th>
|
||||
<th class="right" colspan="5"><? gross_sum ?>:</th>
|
||||
<th class="right"><? document.gross_sum ?></th>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -196,29 +196,15 @@
|
||||
<tr>
|
||||
<td><? document.sender.name ?></td>
|
||||
<td>
|
||||
<? tax id ?>: <? document.sender.tax_id ?><br/>
|
||||
<? local court ?>: <? document.sender.court ?><br/><br/>
|
||||
<div class="ad"><? document.type ?> <? created with ?> <a href="https://umbrella.srsoftware.de">Umbrella</a> <? by ?> <a href="https://srsoftware.de">SRSoftware</a></div>
|
||||
<? tax_id ?>: <? document.sender.tax_id ?><br/>
|
||||
<? local_court ?>: <? document.sender.court ?><br/><br/>
|
||||
<div class="ad"><? document.type ?> <? created_with|tool=<a href="https://umbrella.srsoftware.de">Umbrella</a>|producer=<a href="https://srsoftware.de">SRSoftware</a> ?></div>
|
||||
</td>
|
||||
<td>
|
||||
<? bank account ?>:<br/>
|
||||
<? bank_account ?>:<br/>
|
||||
<? document.sender.bank_account ?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- <div class="bottom">
|
||||
<div class="company">
|
||||
<? document.sender.name ?>
|
||||
</div>
|
||||
<div class="tax_data">
|
||||
<? Tax id ?>: <? document.sender.tax_id ?><br/>
|
||||
<? local court ?>: <? document.sender.court ?><br/><br/>
|
||||
<div class="ad"><? document.type ?> <? created with ?> <a href="https://umbrella.srsoftware.de">Umbrella</a> <? by ?> <a href="https://srsoftware.de">SRSoftware</a></div>
|
||||
</div>
|
||||
<div class="bank_account">
|
||||
<? bank account ?>:<br/>
|
||||
<? document.sender.bank_account ?>
|
||||
</div>
|
||||
</div> -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -9,6 +9,7 @@
|
||||
"bank_account": "Bankverbindung",
|
||||
"base_url": "Basis-URL",
|
||||
"bookmark": "Lesezeichen",
|
||||
"by": "von",
|
||||
"client_id": "Client-ID",
|
||||
"client_secret": "Client-Geheimnis",
|
||||
"code": "Code",
|
||||
@@ -23,6 +24,7 @@
|
||||
"create_new_user": "Neuen Benutzer anlegen",
|
||||
"CREATE_USERS": "Nutzer anlegen",
|
||||
"create_pdf": "PDF erzeugen",
|
||||
"created_with": "erzeugt mit {tool} von {producer}",
|
||||
"customer_address": "Adresse",
|
||||
"customer_email": "Emailadresse des Kunden",
|
||||
"customer": "Kunde",
|
||||
|
||||
Reference in New Issue
Block a user