mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-01-14 06:09:33 +00:00
232 lines
7.3 KiB
Markdown
232 lines
7.3 KiB
Markdown
|
|
---
|
||
|
|
title: Translation System
|
||
|
|
layout: default
|
||
|
|
parent: Development
|
||
|
|
nav_order: 1
|
||
|
|
---
|
||
|
|
|
||
|
|
# Translation System for Contributors
|
||
|
|
|
||
|
|
This document explains how Part-DB's translation system works and how contributors can effectively use it.
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Part-DB uses Symfony's translation system with XLIFF format files. Translations are managed through [Crowdin](https://part-db.crowdin.com/part-db), but understanding the system's features is important for contributors working on code or translations.
|
||
|
|
|
||
|
|
## Basic Translation Approach
|
||
|
|
|
||
|
|
Part-DB uses translation keys rather than translating English strings directly. For example:
|
||
|
|
|
||
|
|
- Translation key: `part.info.title`
|
||
|
|
- English: "Part Information"
|
||
|
|
- German: "Bauteil-Informationen"
|
||
|
|
|
||
|
|
This approach has several advantages:
|
||
|
|
- Keys remain stable even if the English text changes
|
||
|
|
- The same key can have different translations in different contexts
|
||
|
|
- Keys are organized hierarchically by feature/context
|
||
|
|
|
||
|
|
### Using Translations in Code
|
||
|
|
|
||
|
|
In PHP/Twig:
|
||
|
|
```twig
|
||
|
|
{{ 'part.info.title'|trans }}
|
||
|
|
```
|
||
|
|
|
||
|
|
In PHP:
|
||
|
|
```php
|
||
|
|
$translator->trans('part.info.title')
|
||
|
|
```
|
||
|
|
|
||
|
|
## Type Synonyms and Placeholders
|
||
|
|
|
||
|
|
Part-DB includes a powerful synonym system that allows customizing the names of entity types (like "Category", "Part", "Manufacturer") throughout the interface. This is particularly useful for organizations that prefer different terminology.
|
||
|
|
|
||
|
|
### How Synonyms Work
|
||
|
|
|
||
|
|
Administrators can define custom names for entity types in the settings (Settings → Synonyms). These custom names are then automatically substituted throughout the application using translation placeholders.
|
||
|
|
|
||
|
|
### Placeholder Syntax
|
||
|
|
|
||
|
|
The synonym system uses special placeholders in translation strings that get replaced with the appropriate entity type name:
|
||
|
|
|
||
|
|
| Placeholder | Meaning | Example Output (Default) | Example Output (with synonym) |
|
||
|
|
|------------|---------|-------------------------|------------------------------|
|
||
|
|
| `[Type]` | Singular, capitalized | "Category" | "Product Group" |
|
||
|
|
| `[[Type]]` | Plural, capitalized | "Categories" | "Product Groups" |
|
||
|
|
| `[type]` | Singular, lowercase | "category" | "product group" |
|
||
|
|
| `[[type]]` | Plural, lowercase | "categories" | "product groups" |
|
||
|
|
|
||
|
|
Where `Type` is the element type name (e.g., `category`, `part`, `manufacturer`, etc.).
|
||
|
|
|
||
|
|
### Available Element Types
|
||
|
|
|
||
|
|
The following element types support synonyms:
|
||
|
|
|
||
|
|
- `category` - Part categories
|
||
|
|
- `part` - Electronic parts/components
|
||
|
|
- `manufacturer` - Component manufacturers
|
||
|
|
- `supplier` - Component suppliers
|
||
|
|
- `storage_location` - Physical storage locations (also called `storelocation`)
|
||
|
|
- `footprint` - PCB footprints
|
||
|
|
- `attachment_type` - File attachment types
|
||
|
|
- `measurement_unit` - Units of measurement
|
||
|
|
- `currency` - Currencies
|
||
|
|
- `project` - Projects
|
||
|
|
- And many others (see `ElementTypes` enum in code)
|
||
|
|
|
||
|
|
### Examples
|
||
|
|
|
||
|
|
#### Basic Usage
|
||
|
|
|
||
|
|
Translation string:
|
||
|
|
```
|
||
|
|
"Click here to create a new [Category]"
|
||
|
|
```
|
||
|
|
|
||
|
|
Default output:
|
||
|
|
```
|
||
|
|
"Click here to create a new Category"
|
||
|
|
```
|
||
|
|
|
||
|
|
With custom synonym (Category → "Product Type"):
|
||
|
|
```
|
||
|
|
"Click here to create a new Product Type"
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Multiple Placeholders
|
||
|
|
|
||
|
|
Translation string:
|
||
|
|
```
|
||
|
|
"This [part] belongs to [category] 'Electronics'"
|
||
|
|
```
|
||
|
|
|
||
|
|
Default output:
|
||
|
|
```
|
||
|
|
"This part belongs to category 'Electronics'"
|
||
|
|
```
|
||
|
|
|
||
|
|
With custom synonyms:
|
||
|
|
```
|
||
|
|
"This component belongs to product group 'Electronics'"
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Plural Usage
|
||
|
|
|
||
|
|
Translation string:
|
||
|
|
```
|
||
|
|
"You have 5 [[part]] in 3 [[category]]"
|
||
|
|
```
|
||
|
|
|
||
|
|
Default output:
|
||
|
|
```
|
||
|
|
"You have 5 parts in 3 categories"
|
||
|
|
```
|
||
|
|
|
||
|
|
With custom synonyms (Part → "Component", Category → "Group"):
|
||
|
|
```
|
||
|
|
"You have 5 components in 3 groups"
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Case Variations
|
||
|
|
|
||
|
|
Translation string:
|
||
|
|
```
|
||
|
|
"Select a [Category] to view its [[part]]"
|
||
|
|
```
|
||
|
|
|
||
|
|
This demonstrates:
|
||
|
|
- `[Category]` - Capitalized singular (starts sentence or emphasizes)
|
||
|
|
- `[[part]]` - Lowercase plural (mid-sentence)
|
||
|
|
|
||
|
|
### Technical Implementation
|
||
|
|
|
||
|
|
The synonym system is implemented through several components:
|
||
|
|
|
||
|
|
1. **SynonymSettings** (`src/Settings/SynonymSettings.php`): Stores user-defined synonyms
|
||
|
|
2. **ElementTypeNameGenerator** (`src/Services/ElementTypeNameGenerator.php`): Generates localized labels
|
||
|
|
3. **RegisterSynonymsAsTranslationParametersListener** (`src/EventListener/RegisterSynonymsAsTranslationParametersListener.php`): Registers placeholders globally
|
||
|
|
|
||
|
|
The system automatically:
|
||
|
|
- Generates placeholders for all element types at application startup
|
||
|
|
- Handles capitalization properly for different languages
|
||
|
|
- Falls back to default translations if no synonym is defined
|
||
|
|
- Caches placeholder values for performance
|
||
|
|
|
||
|
|
### Guidelines for Using Synonyms in Translations
|
||
|
|
|
||
|
|
When writing or updating translation strings:
|
||
|
|
|
||
|
|
1. **Use synonyms for entity type references**: When referring to entity types like categories, parts, manufacturers, etc., use the synonym placeholders instead of hardcoding the type name.
|
||
|
|
|
||
|
|
✅ Good: `"Delete this [category]?"`
|
||
|
|
|
||
|
|
❌ Bad: `"Delete this category?"`
|
||
|
|
|
||
|
|
2. **Match the case to context**:
|
||
|
|
- Use capitalized forms (`[Type]`, `[[Type]]`) at the start of sentences or for emphasis
|
||
|
|
- Use lowercase forms (`[type]`, `[[type]]`) in the middle of sentences
|
||
|
|
|
||
|
|
3. **Choose singular vs. plural appropriately**:
|
||
|
|
- Use singular for single items: `"Create new [part]"`
|
||
|
|
- Use plural for multiple items or lists: `"Available [[part]]"`
|
||
|
|
|
||
|
|
4. **Consistency**: Be consistent with placeholder usage across similar translation strings
|
||
|
|
|
||
|
|
5. **Don't overuse**: Only use placeholders for actual entity type names. Don't use them for:
|
||
|
|
- Action verbs (use regular translations)
|
||
|
|
- Specific feature names
|
||
|
|
- UI element names that aren't entity types
|
||
|
|
|
||
|
|
### Testing Synonyms
|
||
|
|
|
||
|
|
To test how your translations work with synonyms:
|
||
|
|
|
||
|
|
1. Go to Settings → Synonyms in Part-DB
|
||
|
|
2. Define custom synonyms for the types you're testing
|
||
|
|
3. Navigate to pages that use your translation strings
|
||
|
|
4. Verify the synonyms appear correctly with proper capitalization and plurality
|
||
|
|
|
||
|
|
## Translation Parameters
|
||
|
|
|
||
|
|
In addition to synonym placeholders, Part-DB uses standard Symfony translation parameters for dynamic values:
|
||
|
|
|
||
|
|
```
|
||
|
|
"You have %count% parts selected"
|
||
|
|
```
|
||
|
|
|
||
|
|
Parameters are passed when calling the translation:
|
||
|
|
```php
|
||
|
|
$translator->trans('parts.selected', ['%count%' => 5])
|
||
|
|
```
|
||
|
|
|
||
|
|
Important: Parameters use `%paramName%` syntax, while synonym placeholders use `[Type]` or `[[Type]]` syntax.
|
||
|
|
|
||
|
|
## Translation Files
|
||
|
|
|
||
|
|
Translation files are located in the `translations/` directory and use XLIFF format:
|
||
|
|
|
||
|
|
- `messages.en.xlf` - English translations
|
||
|
|
- `messages.de.xlf` - German translations
|
||
|
|
- `messages.{locale}.xlf` - Other languages
|
||
|
|
|
||
|
|
The XLIFF format includes:
|
||
|
|
- Source key (translation key)
|
||
|
|
- Target (translated text)
|
||
|
|
- Notes (file locations where the key is used)
|
||
|
|
|
||
|
|
## Best Practices
|
||
|
|
|
||
|
|
1. **Use translation keys, not hardcoded text**: Always use translation keys for any user-facing text
|
||
|
|
2. **Organize keys hierarchically**: Use dots to namespace keys (e.g., `part.info.title`)
|
||
|
|
3. **Use synonym placeholders for entity types**: This gives administrators flexibility
|
||
|
|
4. **Test with different synonym configurations**: Ensure your text works with custom names
|
||
|
|
5. **Be consistent**: Follow existing patterns for similar functionality
|
||
|
|
6. **Check other languages**: Look at how similar keys are translated in other languages (via Crowdin's "Other languages" dropdown)
|
||
|
|
|
||
|
|
## Resources
|
||
|
|
|
||
|
|
- [Crowdin Part-DB Project](https://part-db.crowdin.com/part-db)
|
||
|
|
- [Symfony Translation Documentation](https://symfony.com/doc/current/translation.html)
|
||
|
|
- [Contributing Guide](../../CONTRIBUTING.md)
|