This library gives users the ability to use gettext in a friendlier way.
- PHP 8.2 or higher
- CodeIgniter 4.3 or higher
- PHP gettext extension enabled
composer require michalsn/codeigniter-gettext
In the example below we will assume, that files from this project will be located in app/ThirdParty/gettext directory.
Download this project and then enable it by editing the app/Config/Autoload.php file and adding the Michalsn\CodeIgniterGettext namespace to the $psr4 array, like in the below example:
<?php
namespace Config;
use CodeIgniter\Config\AutoloadConfig;
class Autoload extends AutoloadConfig
{
// ...
public $psr4 = [
APP_NAMESPACE => APPPATH, // For custom app namespace
'Config' => APPPATH . 'Config',
'Michalsn\CodeIgniterGettext' => APPPATH . 'ThirdParty/gettext/src',
];
// ...Run the publish command to create the configuration file:
php spark gettext:publishThis will create a Gettext.php config file in the app/Config/ folder with the following options:
<?php
namespace Config;
use Michalsn\CodeIgniterGettext\Config\Gettext as BaseGettext;
class Gettext extends BaseGettext
{
// Directory where translation files are stored
public string $dir = APPPATH . 'Gettext' . DIRECTORY_SEPARATOR;
// Default domain name (usually 'messages')
public string $domain = 'messages';
// List of allowed domains
public array $allowedDomains = ['messages'];
// Character encoding
public string $codeset = 'UTF-8';
// Locale mapping - maps CodeIgniter locales to system locales
public array $locales = [
'en' => 'en_US.utf8',
'pl' => 'pl_PL.utf8',
'de' => 'de_DE.utf8',
'fr' => 'fr_FR.utf8',
];
}You also need to configure supported locales in app/Config/App.php:
public array $supportedLocales = ['en', 'pl', 'de', 'fr'];This is how your folder structure should look like.
app/
├── Gettext/ # Base directory for all gettext locales
│ ├── pl_PL/ # Polish locale
│ │ └── LC_MESSAGES/
│ │ ├── messages.po # Editable source file
│ │ └── messages.mo # Compiled binary file for PHP
│ │
│ └── de_DE/ # Example: German locale
│ └── LC_MESSAGES/
│ ├── messages.po
│ └── messages.mo
│
├── Controllers/
│ └── Home.php
├── Views/
│ └── welcome_message.php
└── ...
// In your controller
service('gettext')->setLocale('pl');
echo _('Hello'); // Outputs: Cześć// Set locale based on user preference
service('gettext')->setLocale('de');
echo _('Hello'); // Outputs: Hallo
echo _('Goodbye'); // Outputs: Auf Wiedersehenservice('gettext')->setLocale('de');
echo pgettext('verb', 'Post'); // "Veröffentlichen"
echo pgettext('noun', 'Post'); // "Beitrag"// npgettext($context, $singular, $plural, $count)
$count = 3;
// Insert values with sprintf()
echo sprintf(npgettext('email', '%d message', '%d messages', intval($count)), $count);
// Email context: "3 messages"
echo sprintf(npgettext('chat', '%d message', '%d messages', intval($count)), $count);
// Chat context: "3 chats" or "3 texts"// dpgettext($domain, $context, $message)
// Using different translation domains
echo dpgettext('admin', 'button', 'Delete'); // "Remove permanently"
echo dpgettext('frontend', 'button', 'Delete'); // "Move to trash"// dnpgettext($domain, $context, $singular, $plural, $count)
$files = 5;
// Insert values with sprintf()
echo sprintf(dnpgettext('filesystem', 'trash', '%d file', '%d files', intval($files)), $files);
// Result: "5 files in trash"
echo sprintf(dnpgettext('filesystem', 'upload', '%d file', '%d files', intval($files)), $files);
// Result: "5 files uploaded"// If you need to change both locale and domain
service('gettext')->setLocale('pl')->setDomain('messages');
echo _('Hello');If you want to organize translations into different domains (e.g., 'messages', 'errors', 'emails'):
- Update
app/Config/Gettext.php:
public array $allowedDomains = ['messages', 'errors', 'emails'];- Create corresponding
.poand.mofiles:
app/Gettext/pl_PL/LC_MESSAGES/
├── messages.po
├── messages.mo
├── errors.po
├── errors.mo
├── emails.po
└── emails.mo
- Switch domains as needed:
service('gettext')->setLocale('pl')->setDomain('errors');
echo _('File not found');Create a .po (Portable Object) file for each locale in the appropriate directory:
app/Gettext/pl_PL/LC_MESSAGES/messages.po
You can edit .po files manually or use tools like Poedit, which provides a user-friendly interface.
Example .po file structure:
msgid ""
msgstr ""
"Project-Id-Version: MyApp 1.0\n"
"Language: pl_PL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "Hello"
msgstr "Cześć"
msgid "Goodbye"
msgstr "Do widzenia"After editing .po files, compile them to binary .mo (Machine Object) files for PHP to use.
msgfmt app/Gettext/pl_PL/LC_MESSAGES/messages.po -o app/Gettext/pl_PL/LC_MESSAGES/messages.mofind app/Gettext -name "*.po" -execdir msgfmt {} -o messages.mo \;After compiling new translations, you may need to restart your web server or PHP-FPM to clear the gettext cache.
-
Check if gettext extension is installed:
php -m | grep gettext -
Verify locale is installed on your system:
locale -a | grep pl_PLIf not found, install the locale package for your OS.
-
Check locale format: Ensure your locale strings in
app/Config/Gettext.phpmatch your system's locale format. Common formats:- Linux:
pl_PL.utf8orpl_PL.UTF-8 - macOS:
pl_PL.UTF-8
- Linux:
-
Verify .mo files exist and are up-to-date: Ensure you've compiled
.pofiles to.mofiles after making changes. -
Clear gettext cache: Restart your web server or PHP-FPM after updating translations.