skip
June 20, 2024, 7:10pm
1
Infos:
Used Zammad version: 6.3.1-1718620481.9d65e987.jammy
Used Zammad installation type: package
Operating system: Ubuntu 22.04
Browser + version: Firefox 127.0 (64-bit)
Expected behavior:
Use rails console to add custom translations for all strings
Actual behavior:
It is possible to translate certain strings but not all of them
e.g. Organization
does not work
Same for
My Organization Tickets
Zammad is currently in maintenance mode. Only administrators can log in. Please wait until the maintenance window is over.
It works for Customer
or custom states
Translation.create_if_not_exists(:locale => 'de-de', :source => 'Customer ', :target => 'DSB', created_by_id: 1, updated_by_id: 1)
Steps to reproduce the behavior:
Open the Rails console zammad run rails c
Try to translate withTranslation.create_if_not_exists(:locale => 'de-de', :source => "Organization", :target => "Schule", created_by_id: 1, updated_by_id: 1)
Any pointer is greatly appreciated
Best,
Skip
skip
June 20, 2024, 7:41pm
2
I also tried to push it through the API but without luck
[
{
"locale": "de-de",
"source": "Organization",
"target": "Schule",
"target_initial": "Organisation",
"is_synchronized_from_codebase": true,
"synchronized_from_translation_file": "i18n/zammad.de-de.po",
"updated_by_id": 1,
"created_by_id": 1,
"created_at": "2024-04-23T10:05:32.212Z",
"updated_at": "2024-04-23T10:05:32.212Z"
}
]
skip:
It is possible to translate certain strings but not all of them
e.g. Organization
does not work
Probably because “Organization
” is an already translated attribute? Have you tried switching your profile language to the target language? “Organization
” gets translated, as well as the maintenance page text.
skip
June 20, 2024, 8:06pm
4
I agree, it is already translated to Organisation
in german.
But I want to change that to Schule
It works with Customer
which is Kunde
but I can translate it to DSB
using the rails console.
That is weird, as this translation should already exist as well. You might need to look into replacing the existing translations instead of trying to create new ones with the create_if_not_exists
function, because it should already exist and fail to create a new one, but that is just my interpretation based on very basic Rails commandline skills.
skip
June 20, 2024, 8:26pm
6
Very weird
Also because Customer
also already exists, but it is possible to change it’s translation with create_if_not_exist
skip
June 20, 2024, 8:43pm
7
Now I tried with create_or_update
but instead of updating the translation with id 120588
and it is generating random translations
skip
June 21, 2024, 6:39am
10
Thank you for the link
Since I am looking to automate, replicate and make installations of Zammad reproducible and auditable, I am looking for a more devops or automated way to do so and going into a GUI and manually adding translation is far from a reproducible way of setting up a system.
Is there no other way at this point to use a script or APIs to add translations? It worked very well for other translations
I was told by developers that the rails console variant is not supported.
Reverse engineer what Zamamd does in the background when you use the UI I guess.
Beside of that there’s just the UI to use. Anything beside of that is technically not supported.
skip
June 21, 2024, 6:45am
12
I see, thanks for the info
skip
June 21, 2024, 9:32am
13
If anyone is interested this is my quick hack to solve this using the API
import csv
import requests
import logging
import os
import urllib3
# Suppress only the single InsecureRequestWarning from urllib3 needed
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
API_URL = 'https://example.com/api/v1/translations'
API_TOKEN = 'yourtoken'
headers = {
'Authorization': f'Token token={API_TOKEN}',
'Content-Type': 'application/json'
}
def fetch_all_translations():
translations = []
page = 1
per_page = 50 # Adjust the per_page value based on the API's pagination settings
while True:
response = requests.get(f"{API_URL}?page={page}&per_page={per_page}", headers=headers, verify=False)
if response.status_code == 200:
data = response.json()
translations.extend(data)
if len(data) < per_page:
break # Exit the loop if we have fetched all pages
page += 1
else:
logger.error(f"Failed to fetch translations. Status code: {response.status_code}, Response: {response.text}")
break
return translations
def find_translation_id(translations, locale, source):
for translation in translations:
if translation['locale'] == locale and translation['source'] == source:
return translation['id']
return None
def update_translation(translation_id, target):
data = {
'target': target
}
response = requests.put(f"{API_URL}/{translation_id}", json=data, headers=headers, verify=False)
if response.status_code == 200:
logger.info(f"Translation ID '{translation_id}' updated successfully.")
else:
logger.error(f"Failed to update translation ID '{translation_id}'. Status code: {response.status_code}, Response: {response.text}")
def add_translation(locale, source, target):
data = {
'locale': locale,
'source': source,
'target': target
}
response = requests.post(API_URL, json=data, headers=headers, verify=False)
if response.status_code == 201:
logger.info(f"Translation for '{source}' added successfully.")
else:
logger.error(f"Failed to add translation for '{source}'. Status code: {response.status_code}, Response: {response.text}")
def add_or_update_translations_from_csv(csv_file):
translations = fetch_all_translations()
with open(csv_file, 'r', encoding='utf-8') as file:
reader = csv.DictReader(file, delimiter=';')
for row in reader:
try:
locale = row['locale']
source = row['source']
target = row['target']
translation_id = find_translation_id(translations, locale, source)
if translation_id:
update_translation(translation_id, target)
else:
add_translation(locale, source, target)
except KeyError as e:
logger.error(f"Missing key {e} in CSV row. Skipping this row.")
except Exception as e:
logger.error(f"An error occurred: {e}")
# Example usage
csv_file_path = 'test.csv'
add_or_update_translations_from_csv(csv_file_path)
Basically is loads the csv file which is set up as
locale;source;target
de-de;Customer;DSB
de-de;Organization;Schule
Looks case sensitively for the source in the whole translations then adds the target as translation for the defined locale
It’s hacky, but it works
Have fun!
2 Likes
system
Closed
June 28, 2024, 9:33am
14
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.