使用zerospam/laravel-gettext自动生成.po文件遇空文件问题求助
问题描述
- 是否可以无需Poedit,通过程序化方式扫描目录中的gettext字符串并添加到.po文件中?
- 已按照zerospam/laravel-gettext文档完成安装配置,但执行
php artisan gettext:create或php artisan gettext:update命令时,仅生成包含头部信息的空.po文件。相关配置文件及生成的.po文件内容如下:
laravel-gettext.php 配置
<?php return [ /** * Translation handlers, options are: * * - symfony: (recommended) uses the symfony translations component. Incompatible with php-gettext * you must uninstall the php-gettext module before use this handler. * * - gettext: requires the php-gettext module installed. This handler has well-known cache issues */ 'handler' => 'symfony', /** * Session identifier: Key under which the current locale will be stored. */ 'session-identifier' => 'laravel-gettext-locale', /** * Default locale: this will be the default for your application. * Is to be supposed that all strings are written in this language. */ 'locale' => 'en_US', /** * Supported locales: An array containing all allowed languages */ 'supported-locales' => [ 'en_US', ], /** * Default charset encoding. */ 'encoding' => 'UTF-8', /** * ----------------------------------------------------------------------- * All standard configuration ends here. The following values * are only for special cases. * ----------------------------------------------------------------------- **/ /** * Locale categories to set */ 'categories' => [ 'LC_ALL', ], /** * Base translation directory path (don't use trailing slash) */ 'translations-path' => '../resources/lang', /** * Relative path to the app folder: is used on .po header files */ 'relative-path' => '../../../../../app', /** * Fallback locale: When default locale is not available */ 'fallback-locale' => 'en_US', /** * Default domain used for translations: It is the file name for .po and .mo files */ 'domain' => 'messages', /** * Project name: is used on .po header files */ 'project' => 'MultilanguageLaravelApplication', /** * Translator contact data (used on .po headers too) */ 'translator' => 'James Translator <james@translations.colm>', /** * Paths where Poedit will search recursively for strings to translate. * All paths are relative to app/ (don't use trailing slash). * * Remember to call artisan gettext:update after change this. */ 'source-paths' => [ 'Http', '../resources/views', 'Console', ], /** * Multi-domain directory paths. If you want the translations in * different files, just wrap your paths into a domain name. * for example: */ /* 'source-paths' => [ // 'frontend' domain 'frontend' => [ 'controllers', 'views/frontend', ], // 'backend' domain 'backend' => [ 'views/backend', ], // 'messages' domain (matches default domain) 'storage/views', ], */ /** * Sync laravel: A flag that determines if the laravel built-in locale must * be changed when you call LaravelGettext::setLocale. */ 'sync-laravel' => true, /** * The adapter used to sync the laravel built-in locale */ 'adapter' => \Xinax\LaravelGettext\Adapters\LaravelAdapter::class, /** * Where to store the current locale/domain * * By default, in the session. * Can be changed for only memory or your own storage mechanism * * @see \Xinax\LaravelGettext\Storages\Storage */ 'storage' => \Xinax\LaravelGettext\Storages\SessionStorage::class, /** * Use custom locale that is not supported by the system */ 'custom-locale' => false, /** * The keywords list used by poedit to search the strings to be translated * * The "_", "__" and "gettext" are singular translation functions * The "_n" and "ngettext" are plural translation functions * The "dgettext" function allows a translation domain to be explicitly specified * * "__" and "_n" and "_i" and "_s" are helpers functions @see \Xinax\LaravelGettext\Support\helpers.php */ 'keywords-list' => ['_', '__', '_i', '_s', 'gettext', '_n:1,2', 'ngettext:1,2', 'dgettext:2'], ];
生成的 messages.po 文件
msgid "" msgstr "" "Project-Id-Version: MultilanguageLaravelApplication\n" "POT-Creation-Date: 2022-09-16 11:59+0200\n" "PO-Revision-Date: 2022-09-16 11:59+0200\n" "Last-Translator: James Translator <james@translations.colm>\n" "Language-Team: James Translator <james@translations.colm>\n" "Language: en_US\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.5.4\n" "X-Poedit-KeywordsList: _;__;_i;_s;gettext;_n:1,2;ngettext:1,2;dgettext:2\n" "X-Poedit-Basepath: ../../../../../app\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-SearchPath-0: Http\n" "X-Poedit-SearchPath-1: ../resources/views\n" "X-Poedit-SearchPath-2: Console\n" "X-Poedit-SearchPath-3: ../storage/framework/messages/\n"
解决方案
1. 无需Poedit生成.po文件的可行性
完全可以,zerospam/laravel-gettext本身就提供了gettext:create和gettext:update这两个Artisan命令,用来程序化扫描代码中的翻译字符串并生成/更新.po文件,不需要依赖Poedit。这些命令底层通过调用gettext工具链或Symfony翻译组件完成扫描工作。
2. 解决空.po文件问题的排查步骤
针对执行命令后仅生成头部信息的情况,按以下步骤逐一排查:
检查代码中是否使用了指定的翻译函数
确认你的代码(app/Http、resources/views、app/Console目录下的文件)确实使用了配置keywords-list中定义的翻译函数包裹需要翻译的字符串,例如:// 控制器示例 return __('Welcome to our application'); // Blade视图示例 <h1>{{ __('Hello World') }}</h1>如果代码中没有任何这类调用,扫描自然无法找到可翻译的字符串。
验证
source-paths路径正确性
配置中的source-paths是相对app目录的路径:Http对应app/Http,路径正确../resources/views相对app目录的实际路径是项目根目录下的resources/views,需确认该目录存在且包含使用翻译函数的文件Console对应app/Console,路径正确
可以尝试改为绝对路径测试,比如将../resources/views替换为/var/www/your-project/resources/views(根据你的项目实际路径调整)。
确认gettext工具链是否安装
虽然你使用的是symfony handler,但部分场景下仍需系统安装gettext工具包(包含xgettext命令)。在终端执行xgettext --version检查是否安装,未安装则按以下方式安装:- Ubuntu/Debian:
sudo apt-get install gettext - macOS:
brew install gettext
- Ubuntu/Debian:
清除缓存后重新执行命令
执行以下命令清除Laravel配置缓存,避免旧配置影响扫描结果:php artisan config:clear php artisan cache:clear之后重新运行
php artisan gettext:update。检查
relative-path配置
你的relative-path设置为../../../../../app,这个路径会写入.po文件头部,用于定位源文件。需确认该相对路径从.po文件所在目录(resources/lang/en_US/LC_MESSAGES/)到app目录是否正确。可以尝试改为../../../../app(从resources/lang/en_US/LC_MESSAGES/messages.po到app目录的相对路径)。检查目录权限
确保Laravel拥有读取source-paths指定目录以及写入translations-path目录的权限。可以执行以下命令调整权限:chmod -R 755 app resources # 服务器环境下可设置所属用户 chown -R www-data:www-data app resources
内容的提问来源于stack exchange,提问作者coderdonezo

