DeepL Translation System Guide
This guide explains the full process of transferring translations to the new e-shop. All translation-related functions are located in the ServerPresenter. It also includes instructions on how to properly check and translate the e-shop using DeepL
Prerequisites
IMPORTANT: If the DeepL model is not in the project, add it via Composer:
composer require deeplcom/deepl-php
1. Pre-Translation Preparation
1.1 Transfer Functions
Transfer all translation-related functions from the original project (e.g., Fencee/Dogtrace) to the new project.
1.2 Database Copying
In Zeroadmin, copy the database to the new language mutation (e.g., DE) using the "Kopirovat Data do jine jazykove mutace" form.
1.3 DeepL API Configuration
Verify that the DeepL API key is correctly configured in your settings_config table.
1.4 RouterFactory Configuration
In RouterFactory.php, you need to add locale parameter to each route where locale is used. This ensures proper URL generation for different language mutations.
// Example route configuration
$frontRoutes[] = new Route('//<domain>/<locale cs|en|de|ru|sk>/p-<product_id [0-9]+>[-<product_name>]', [
'presenter' => 'Homepage',
'action' => 'product',
null => [
Route::FILTER_IN => function (array $params) {
$params = $this->checkOwnDomain($params);
$params = $this->checkProductName($params);
$this->checkLocale($params);
return $params;
},
],
]);
Note: Make sure to add all language codes that your website supports (e.g., cs, en, de) to the locale parameter in routes.
2. Configuring Supplements for Translation
Review which supplements exist in the database for the CS mutation and uncomment only those that actually exist. You may need to add some manually.
2.1 MenuItem Supplements
In ServerPresenter.php constructor, define the $menuItemXSupplementArray:
$this->menuItemXSupplementArray = [
// Uncomment gradually in batches of 3-4 supplements
// MenuRepository::getSupplements()['Nadpis_h1'] => [],
// MenuRepository::getSupplements()['Perex'] => [
// 'options' => [TranslateTextOptions::TAG_HANDLING => 'html']
// ],
// ...
];
IMPORTANT: Uncomment supplements gradually in batches of 3-4 to translate in smaller chunks.
2.2 Product Supplements
Similar to MenuItem supplements, define the $productXSupplementArray in ServerPresenter.php constructor:
$this->productXSupplementArray = [
// Uncomment gradually in batches of 3-4 supplements
// ProductRepository::getSupplements()['Nadpis_h1'] => [],
// ProductRepository::getSupplements()['Perex'] => [
// 'options' => [TranslateTextOptions::TAG_HANDLING => 'html']
// ],
// ...
];
IMPORTANT:
- Uncomment supplements in batches of 3-4
- You'll need to push changes to production multiple times as you uncomment new supplements and comment out completed ones
2.3 Excluded Supplement IDs
Define excluded IDs in the createComponentConvertValues() method. For example, to exclude all headings:
$excludeIds = [1, 4, 26, 31];
These supplements are automatically skipped during replacing operation (prepsat nejake hodnoty jinymi). Add more IDs to this list as needed.
Recommendation: Before trying to batch replace values, identify which supplements to avoid that shouldn't be replaced and add them to the excluded IDs list.
3. Excluded Property IDs
In ServerPresenter.php within the processDeeplTranslateOption() method, define excluded property IDs:
$excludedProperties = [3];
These properties are automatically skipped when translating property values.
Important: Before transferring to a new website, identify which properties contain certain data that should not be translated and add them to the excluded properties list.
4. Local Testing
- First, try translating everything without using DeepL, just to verify that the system works. You should see products, menu items, supplements—whatever you’re translating—with the word ‘test’ appended to the end of each value. If you see that, you can proceed to the next steps.
- when you comment out
IsProduction()it starts using DeepL so be careful.
4.1 Testing a Single Product
IMPORTANT: Always test on one product before running batch translations!
- In
ServerPresenter, use thedeeplTranslateform to translate existing content (NEVER create new content during translation) - Enter the ID of one product in the "IDs for translating specific products" field (e.g.,
123) - Check only "products"
- Select source (always CS) and target language
- Run the translation
- Verify results in the database and frontend
4.2 Testing a Single MenuItem
Follow the same process as for products, but:
- Enter the MenuItem ID in the "ids" field (e.g.,
456) - Check only "menu items"
4.3 Verifying Results
After test translation, verify:
- ✅ Name translation
- ✅ Content translation (text)
- ✅ Text contains elements that shouldn't be translated (anchors, etc.) - verify regex is excluding them
5. Batch Translation in Production
Important: Create a BACKUP after each table translation
Ensure you've copied the database from CS language to the target language using "Copy data to another language mutation". Always verify you're translating to the correct language.
5.1 Translation Order
It does not really matter but I recommend to follow this sequence:
- Translate basic entities first:
- Properties
- Options
- Then translate content:
- Messages/mutations (settings_translations) - WARNING: Verify that
JS_IS_ESHOPhas an empty value in the new mutation - Menu items (menuitems)
- Products
- Messages/mutations (settings_translations) - WARNING: Verify that
- Next translate supplements:
- Menu supplements (menu_supplements)
- Product supplements (product_supplements)
- Finally translate order_states, form, form_item, all of that is most of the time translated manually
5.2 Batch Translation Process
- Copy Database:
- Use the
copyDbform inServerPresenter - Select source and target language
- Use the
- Translate Individual Parts:
- Use the
deeplTranslateform - Leave the "ids" field empty to translate everything
- For tables with high record counts, translate gradually by specifying individual IDs - typically 100-150 records works well
- For supplements, uncomment usually 3-4 at a time
- You'll need to push changes to production multiple times as you uncomment supplements and comment out completed ones
- Use the
- Monitor Progress:
- Check for errors
- Monitor logs in
log/exception.log
6. Translating Properties and Options
6.1 Translating New Properties
- Check "properties" to translate properties
- Check "options" to translate options
6.2 Translating Property Values in Products
Property values in products are automatically translated when translating the product using ProductTranslator->translateProductPropertiesValues().
Note: Properties with IDs in $excludedProperties are not translated.
7. Currency Conversion and Pricing
7.1 Exchange Rate Configuration
In settings_translation for the target language, set:
EXCHANGE_RATE- base exchange rateEXCHANGE_RATE_DECREASION- rate reduction (optional)
7.2 Automatic Price Conversion
When translating a product, ProductTranslator->convertPriceByCs() is automatically called, which:
- Loads the exchange rate from configuration
- Applies rate reduction (if set)
- Updates product prices in the target language
- If you dont set it up during translations it does not matter you can change the price of all producrs later
8. Transferring to a New Website
8.1 Pre-Transfer Checklist
- Copy Configurations:
menuItemXSupplementArrayandproductXSupplementArrayfromServerPresenterconstructor- Excluded IDs (supplements and properties)
- Exchange rates
- Copy Code:
ServerPresenter.phpProductTranslator.phpMenuItemTranslator.phpPropertyTranslator.phpLanguages.phpProductSettings.phpMenuItemSettings.php- All related classes and utilities
- Configure Environment:
- DeepL API key
- Language mutations in database
IsProductionaccording to environment (comment out for testing)
- Test:
- Translation of one product
- Translation of one MenuItem
- Verify results (including regex for anchors, etc.)
- Run Batch Translation:
- Gradually uncomment supplements in batches of 3-4
- For large tables, translate in batches of 100-150 records
9. Troubleshooting
9.1 Translation Not Executing or adding just test
- Verify
IsProductionis commented out - Check DeepL API key and limit
- Review logs in
log/exception.log
9.2 Some Supplements Not Translating
- Verify supplements are uncommented in
menuItemXSupplementArray/productXSupplementArray - Verify supplement ID is not in excluded IDs
9.3 Properties Not Translating
- Verify property ID is not in
$excludedProperties
9.4 Prices Not Converting
- Verify
EXCHANGE_RATEandEXCHANGE_RATE_DECREASIONsettings insettings_translation - Verify
convertPriceByCs()is called when translating products - If not, you can batch convert all product prices afterward
9.5 Anchors and HTML Elements Being Translated
- Review regex in text filtering methods
- Ensure
TAG_HANDLING => 'html'is correctly set for HTML content
10. Important Notes
10.1 Transactions
All translations occur within database transactions, so changes are rolled back on error.
10.2 Foreign Keys
When copying the database, foreign keys are temporarily disabled (SET FOREIGN_KEY_CHECKS=0) to prevent errors.
10.3 Gradual Translation
IMPORTANT:
- For large tables (more than 100-150 records), translate gradually by specifying individual IDs
- Uncomment supplements gradually in batches of 3-4
- Push changes to production each time you uncomment supplements
10.4 Local Testing
ALWAYS test locally first with IsProduction commented out and one product/MenuItem before running batch translations!
Best Practices Summary
- ✅ Always create database backups before major operations
- ✅ Test with a single item before batch processing
- ✅ Gradually uncomment supplements in small batches
- ✅ Monitor logs and verify results at each step
- ✅ Keep excluded IDs lists up to date
- ✅ Document any project-specific configurations
- ✅ Verify exchange rates before price conversions
- ✅ Use transactions for data safety