Можно ли использовать xgettext для извлечения только определенных строк домена? - PullRequest
3 голосов
/ 27 июля 2010

(Действительно удивлен, что нигде в Интернете нет ответа; пара сообщений за последние несколько лет с похожим вопросом, но никогда не отвечал. Будем надеяться, что команда Stackoverflow может прийти на помощь)

Положение:

При использовании gettext для поддержки локализации приложения иногда требуется указать «домен» с помощью dgettext («домен», «некоторая текстовая строка»). Однако при запуске xgettext все строки, заключенные в dgettext (...), выводятся в один файл (по умолчанию: messages.po).

С учетом следующего примера:

dgettext('menus', 'login link');
dgettext('menus', 'account link');
dgettext('footer', 'copyright notice');
dgettext('footer', 'contact form');

есть ли способ закончить с

menus.po
footer.po

с использованием экстрактора, такого как xgettext?

Требуется ответ PHP, хотя я считаю, что он должен быть применим ко всем языкам

Ответы [ 3 ]

2 голосов
/ 18 марта 2011

Единственный способ сделать это - переопределить функции gettext ...

пример:

function _menus ($str) {
    return dgettext('menus', $str);
}

function _footer ($_str) {
    return dgettext('footer', $str);
}

_menus('login link');
_menus('account link');
_footer('copyright notice');
_footer('contact form');

В противном случае вам нужно будет выполнить только следующие команды:

xgettext [usual options] -k --keyword=_menus:1 -d menus
xgettext [usual options] -k --keyword=_footer:1 -d footer

Пока!

1 голос
/ 01 апреля 2015

Достижение этого лучше всего сделать с помощью разделения кода или использования неоднозначности контекста.

Если вы можете отделить код своего меню от кода нижнего колонтитула, то вы действительно можете рассматривать их как разные домены и извлекать их соответственно из известных местоположений.

Если модульное разделение невозможно и весь код живет вместе, то на самом деле вы должны использовать контекст вместо доменов. например

translate( 'A string', 'myproject', 'some module' ) 

Где "myproject" - ваш домен, а "some module" устраняет неоднозначность строки.

Однако реальность не всегда совпадает с передовой практикой, поэтому, если вы не можете реорганизовать свой код, как предлагает Асевере (и это, вероятно, лучший ответ), тогда у меня есть огромный взлом, чтобы предложить.


Вы могли бы использовать флаг контекста, упомянутый в ответе Бориса. Мы можем использовать это повторно, но только если мы не собираемся использовать контексты.

Я повторю это. Этот хак будет работать, только если ваш код не использует контексты .

Некоторый PHP, содержащий два домена (включая одну строку, используемую в обоих) -

<?php // test.php
dgettext( 'abc', 'foo' );
dgettext( 'abc', 'bar' );
dgettext( 'xyz', 'bar' );

Мы можем обмануть и принять аргумент домена, как если бы мы предполагали, что он является контекстом сообщения (поле msgctxt). Извлечение из командной строки:

xgettext -LPHP --keyword=dgettext:1,2c -o - test.php \
         | sed 's/CHARSET/utf-8/' \
         > combined.pot

Создает файл combined.pot, содержащий все строки с нашим контекстным хаком. (обратите внимание, мы также исправили поле набора символов заполнителя, которое сломало бы следующий бит)

Теперь мы можем отфильтровать все сообщения данного контекста в отдельные файлы, используя msggrep. Обратите внимание, что мы также удаляем контекстное поле, поскольку мы его не используем.

msggrep -J -e foo -o - combined.pot | sed '/^msgctxt/d' > foo.pot
msggrep -J -e bar -o - combined.pot | sed '/^msgctxt/d' > bar.pot

Неправильно, но работает.

1 голос
/ 08 мая 2012

Я не знаю, как поместить разные контексты в разные файлы, но я обнаружил, что xgettext может извлекать доменные имена в поля msgctxt в po-файле.Для PHP это не сделано по умолчанию.Чтобы включить это, используйте, например, --keyword = dgettext: 1c, 2 (в poedit добавьте «dgettext: 1c, 2») в список ключевых слов.

См. Также:

http://developer.gnome.org/glib/2.28/glib-I18N.html

https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/xgettext-Invocation.html

...