# GNU Gettext PO > Localization format for GNU Gettext URL: https://store.crowdin.com/gnu-gettext Category: File Formats Type: System Author: Crowdin GNU Gettext is a widely used internationalization (i18n) system that has implementations for a majority of programming languages and frameworks. It is commonly used for [internationalizing PHP](https://store.crowdin.com/php) and Python, but it can also be found as a recommended technology for localizing games and JavaScript frameworks. Gettext offers different resource file formats for externalizing translatable texts. The most common human- and machine-readable file format is Portable Object (.po), which Crowdin supports. Gettext itself does not have any recommendations for variable (placeholder) syntax. The variable's syntax will vary depending on the underlying technology and can be anything from `%s`, `%d` to `${var}`, `{var}` or `[[var]]`. Crowdin supports the most commonly used variable formats and will automatically detect, highlight, and validate them in the editor. ## File Format Details | Attribute | Value | | --------- | ----- | | File Extension | .po, .pot | | [API Type](https://developer.crowdin.com/api/v2/#operation/api.projects.files.post) | gettext | | Source can be edited in Crowdin | Yes | | Generating translated files via [Bundles](https://support.crowdin.com/bundles/) | [Search Crowdin Store](https://store.crowdin.com/tags/string-exporter) | | Supports pluralization | Yes | | WYSIWYG Preview in the editor | No | | Supported types of contextual information | Text comments, Screenshots, In-Context | | Custom attributes | Yes | | Existing translations import possibility | Key-value mapping | ## Sample File ```auto msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2008-09-03 10:09+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: simple string sample msgid "Text for translation" msgstr "" #. sample with translated string msgid "Text for translation" msgstr "Translated string" #, long string with new line msgid "" "Very long string.\n" "Even longer string" msgstr "" "translation\n" "translation_2" #: plurals #, string with plurals forms msgid "Time: %1 second" msgid_plural "Time: %1 seconds" msgstr[0] "Czas: %1 sekunda" msgstr[1] "Czas: %1 sekundy" msgstr[2] "Czas: %1 sekund" ``` ## Translating GNU Gettext PO **Custom Attributes** Source text will be taken from the **msgstr** node: ``` "X-Crowdin-SourceKey: msgstr\n" ``` ### Comments PO files support multiple types of comments that provide additional context for translators or tools. Each type is indicated by a specific character or combination of characters at the beginning of the line: * **`#` (Translator comment)** – Added manually by the translator or localization team. These comments are displayed in the Editor and are intended to guide the translation. * **`#.` (Extracted comment)** – Usually generated by tools, often from code annotations. Useful for passing context from developers to translators. * **`#:` (Reference)** – Shows the source code location(s) where the string appears (e.g., filename and line number). Helps translators understand the context. * **`#,` (Flag)** – Contains flags used by translation tools (e.g., `fuzzy` to indicate uncertain translations). Not shown to translators. * **`#|` (Previous context or original string)** – Used to preserve the previous `msgctxt`, `msgid`, or `msgid_plural` values before they were updated. Helps track changes during translation updates. * **`#~` (Obsolete entry)** – Marks entries that were removed from the source but are kept for reference. #### Example ``` # Translator comment #. Extracted comment from code #: src/example.py:12 #, fuzzy #| msgctxt "Old context" #| msgid "Old source" #| msgid_plural "Old plural" msgid "New source" msgid_plural "New plural" msgstr[0] "" msgstr[1] "" ``` Use translator and extracted comments to give helpful context for translation. Reference comments are especially useful when the same string appears in multiple places with different meanings. Flags and previous values are mostly managed by tools and help track the translation process. **Plurals** ``` msgid "Time: %1 second" msgid_plural "Time: %1 seconds" msgstr[0] "Czas: %1 sekunda" msgstr[1] "Czas: %1 sekundy" msgstr[2] "Czas: %1 sekund" ```