PHPackages                             kunststube/potools - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Localization &amp; i18n](/categories/localization)
4. /
5. kunststube/potools

ActiveLibrary[Localization &amp; i18n](/categories/localization)

kunststube/potools
==================

Tools for working with gettext PO files.

0.4.1(12y ago)132.9k4[1 PRs](https://github.com/deceze/Kunststube-POTools/pulls)1PHPPHP &gt;=5.3.0

Since Dec 24Pushed 12y ago4 watchersCompare

[ Source](https://github.com/deceze/Kunststube-POTools)[ Packagist](https://packagist.org/packages/kunststube/potools)[ Docs](https://github.com/deceze/Kunststube-POTools)[ RSS](/packages/kunststube-potools/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (8)Used By (1)

Kunststube\\POTools
===================

[](#kunststubepotools)

A collection of tools for working with gettext PO files in PHP.

Classes
-------

[](#classes)

### `POString`

[](#postring)

Models one entry in a PO file with all its possible attributes.

### `Catalog`

[](#catalog)

Groups and categorizes `POString` objects by category, domain and context. Merges attributes of strings occurring more than once. Can use a `POWriter` to output the catalog to disk.

### `POWriter`

[](#powriter)

Writes a `POString` instance to a stream in gettext PO format.

Scripts
-------

[](#scripts)

### `update`

[](#update)

Merges a directory structure of POT files into PO files.

Usage/workflow
--------------

[](#usageworkflow)

The gettext workflow requires/expects that you have the gettext tools () for your platform installed, including the `msginit`, `msgmerge` and `msgfmt` command line utilities. For the full manual, see .

On OS X, the easiest way to install these tools in through Homebrew ():

```
$ brew install gettext

```

Most Linux package managers should make it similarly simple.

The Kunststube\\POTools are designed for situations where the gettext `xgettext` utility does not work or is not sufficient, for example for templates whose syntax `xgettext` does not support. In these cases a custom parser/extractor can quickly be written, while the Kunststube\\POTools can be used to handle the minutiae of the gettext file format. For the rest of the workflow the regular gettext utilities can be used.

The full workflow looks something like this:

1. Prepare strings in source code by wrapping them in gettext functions.
2. Extract strings from source using appropriate parser, create `POString` objects for each.
3. Add `POString` objects to `Catalog`.
4. Write `Catalog` to locale directory as source/master locale POT files.
    - 4b. First time only: create localization PO files using `msginit` utility.
5. Translate PO files.
6. Keep PO files in sync with updated POT files using `update` script.
7. Quality check and compile PO files to MO files using `msgfmt` utility.
8. Rinse, repeat.

### Creating master catalog POT files

[](#creating-master-catalog-pot-files)

```
// Extraction of strings from source is not part of Kunststube\POTools,
// bring your own extractor specific to your needs.
$extractedStrings = my_string_extractor('template.php');

$catalog = new Kunststube\POTools\Catalog('My Project 1.0', 'en_US');

foreach ($extractedStrings as $extractedString) {
    $POString = new Kunststube\POTools\POString($extractedString);

    // set as many additional attributes as you can extract
    $POString->setDomain('errors');
    ...

    $catalog->add($POString);
}

$catalog->writeToDirectory('locale/en_US');
```

This process creates a directory structure which should look something like this:

```
locale/
    en_US/
        ...
        LC_MESSAGES/
            messages.pot
            ...
        LC_MONETARY/
            messages.pot
            ...

```

### Creating and updating PO files

[](#creating-and-updating-po-files)

Initially, use the `msginit` utility to create PO files for all your target locales. When you subsequently change and update the source files, repeat the extraction process to recreate the master POT files, then use the `update` script to propagate those updates to each locale. Assuming a directory structure like this:

```
locale/
    en_US/
        LC_MESSAGES/
            messages.pot
        LC_MONETARY/
            messages.pot
    de_DE/
        LC_MESSAGES/
            messages.po
        LC_MONETARY/
            messages.po
    fr_FR/
        LC_MESSAGES/
            messages.po
        LC_MONETARY/
            messages.po

```

Run the `update` script like this:

```
update path/to/locale en_US

```

The first parameter (`path/to/locale`) is the path to the whole `locale` directory, the second parameter (`en_US`) the name of the directory containing the master POT files within the locale directory. The `update` script will iterate through all POT files in the master locale directory and merge the changes into identically named PO files in other locale directories.

It requires the `msgmerge` utility to be in the shell `$PATH`.

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity29

Limited adoption so far

Community15

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 93.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~68 days

Recently: every ~85 days

Total

6

Last Release

4549d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/07608e79148cc603ea851ef6f62daa4a19e1b32a97a9d62f14a2d97f5e985f19?d=identicon)[deceze](/maintainers/deceze)

---

Top Contributors

[![deceze](https://avatars.githubusercontent.com/u/137217?v=4)](https://github.com/deceze "deceze (15 commits)")[![twoixter](https://avatars.githubusercontent.com/u/88262?v=4)](https://github.com/twoixter "twoixter (1 commits)")

---

Tags

i18nl10ngettextpo

### Embed Badge

![Health badge](/badges/kunststube-potools/health.svg)

```
[![Health](https://phpackages.com/badges/kunststube-potools/health.svg)](https://phpackages.com/packages/kunststube-potools)
```

###  Alternatives

[symfony/intl

Provides access to the localization data of the ICU library

2.6k199.8M1.1k](/packages/symfony-intl)[gettext/gettext

PHP gettext manager

70130.2M102](/packages/gettext-gettext)[sepia/po-parser

Gettext \*.PO file parser for PHP.

1271.5M19](/packages/sepia-po-parser)[gettext/languages

gettext languages with plural rules

7530.3M11](/packages/gettext-languages)[maxakawizard/po-parser

Gettext \*.po parser for PHP

1771.5k](/packages/maxakawizard-po-parser)[fisharebest/localization

A lightweight localization database and translation tools, with data from the CLDR, IANA, ISO, etc.

3191.1k2](/packages/fisharebest-localization)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
