Что такое код hw_gettext

Содержание

hw_GetText

hw_GetText — Retrieve text document

Beskrivelse

Returns the document with object >objectID . If the document has anchors which can be inserted, they will be inserted already.

This function will only work for pure text documents. It will not open a special data connection and therefore blocks the control connection during the transfer.

Parametre

The connection identifier.

The object identifier.

If rootID/prefix is an integer and unequal to 0 the link is constructed from all the names starting at the object with the >rootID/prefix separated by a slash relative to the current object.

If for example the above document ‘internet_movie’ is located at ‘a-b-c-internet_movie’ with ‘-‘ being the separator between hierarchy levels on the Hyperwave server and the source document is located at ‘a-b-d-source’ the resulting HTML link would be: . This is useful if you want to download the whole server content onto disk and map the document hierarchy onto the file system.

Всякие разности

среда, 14 марта 2012 г.

Мультиязычное приложение на gcc при помощи gettext

Сделать приложение многоязычным, с неограниченным количеством поддерживаемых локалей, без изменения кода логики программы не просто, а очень просто!

Рассмотрим локализацию приложения пр помощи GNU утилит gettext на конкретном примере. В качестве препарируемого приложения я выбрал roguelike игру Cataclysm (git-hub: https://github.com/Whales/Cataclysm, forum: http://whalesdev.com/forums/). Код написан на c++ и открыт. Текстовые сообщения в ней безобразно размазаны по всему коду, так что код отлично подойдет для примера :)

Для начала немного слов о механизмах, предоставляемых gettext. Для локализации приложения необходимо все текстовые сообщения, выводимые на экран, нужно «обернуть» специальной функцией gettext. Например:

И этого достаточно для неограниченного количества локализаций! необходимо, только инициализировать текущую локаль ОС. Но, как и обещал, будем все рассматривать на конкретном примере.

Описание прототипа функции gettext находится в файле libintl.h поэтому его необходимо подключить в исходниках. Для Cataclysm, наилучшее место его включения, это файл будет «game.h». Добавляем в его начало (разумеется, после #define _GAME_H_):
Мы также определили макрос _(String), чтобы не писать много букв gettext(. ), на каждое сообщение в игре, а просто _(. ). Также нам понадобятся две константы, это название нашего приложения (на самом деле это будет имя файла с локализацией приложения) и директория размещения его локализаций.

в конкретном случае директория «locale» у нас находится в директории самого приложения. По умолчанию же в debian системах это «/usr/share/locale» где лежат локализации для различных языков всех приложений, поэтому, если мы будем размешать локализации в директории по умолчанию, то значение PACKAGE должно быть уникальным.

Далее инициализируем локаль и задаем значения для локализаций. Это необходимо сделать вначале функции main(), в cataclysm она описана в файле «main.cpp»:
Теперь самая нудная часть, необходимо просмотреть ВСЕ исходники и изменить все строки с сообщениями программы. Например в файле game.cpp в строке 110.

После того, как исходный код изменен, создаем директории для русской локали:

создаем темплейтый файл для перевода:

В результате, в директории locale, у нас создастся файл cataclysm.po, содержащий все строки из исходного кода, которые мы обернули макросом _(String).

создаем po файл для русского перевода:

Теперь нам нужно отредактировать полученный файл locale/de/LC_MESSAGES/cataclysm.po, а именно, добавить в него перевод, можно редактировать в любом текстовом редакторе, или же, воспользоваться программой poedit (http://www.poedit.net).

Пример части отредактированного po файла:

После изменения po файла необходимо его скомпилировать в mo файл командой:

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

теперь при запуске приложения из под локали ru_RU и наличии файла locale/ru/LC_MESSAGES/cataclysm.mo текстовые сообщения из исходников будут заменены на сообщения из mo файла. Точно также можно добавить файлы локализации для других языков. При наличии файла локализации под конкретную локаль будет вставляться соответствующий перевод.

Тут стоит упомянуть еще об одном моенте. разумеется, если выставлена по умолчанию английская локаль, то русского перевода мы не увидим. Для того чтобы из под английской локали увидеть наш перевод необходимо запустить приложение из локали ru. Например при помощи следующей команды:
Результат:

Что осталось за кадром

Очевидно, что при внесении изменений в исходные файлы программы, необходимо пересоздать файл темплейтов. Чтобы добавить новые строки из вновь созданного файла темплейтов в существующий вариант перевода, необходимо выполнить команду:

В данном примере мы задавали константы PACKAGE и LOCALEDIR прямо в исходниках, возможно, более правильно было бы их задавать в Makefile. Для cataclysm это бы выглядело так:

Makefile
Также, для того чтобы ncurses нормально отображал многобайтные символы, необходимо при линковке использовать библиотеку ncursesw а не ncurses.

Что такое код hw_gettext

The xgettext program extracts translatable strings from given input files.

5.1.1 Input file location

‘ -f file ’ ‘ —files-from= file ’

Read the names of the input files from file instead of getting them from the command line.

‘ -D directory ’ ‘ —directory= directory ’

Add directory to the list of directories. Source files are searched relative to this list of directories. The resulting .po file will be written relative to the current directory, though.

If inputfile is ‘ — ’, standard input is read.

5.1.2 Output file location

Use name .po for output (instead of messages.po ).

‘ -o file ’ ‘ —output= file ’

Write output to specified file (instead of name .po or messages.po ).

‘ -p dir ’ ‘ —output-dir= dir ’

Output files will be placed in directory dir .

If the output file is ‘ — ’ or ‘ /dev/stdout ’, the output is written to standard output.

5.1.3 Choice of input file language

Specifies the language of the input files. The supported languages are C , C++ , ObjectiveC , PO , Shell , Python , Lisp , EmacsLisp , librep , Scheme , Smalltalk , Java , JavaProperties , C# , awk , YCP , Tcl , Perl , PHP , GCC-source , NXStringTable , RST , RSJ , Glade , Lua , JavaScript , Vala , GSettings , Desktop .

This is a shorthand for —language=C++ .

By default the language is guessed depending on the input file name extension.

5.1.4 Input file interpretation

Specifies the encoding of the input files. This option is needed only if some untranslated message strings or their corresponding comments contain non-ASCII characters. Note that Tcl and Glade input files are always assumed to be in UTF-8, regardless of this option.

By default the input files are assumed to be in ASCII.

5.1.5 Operation mode

Join messages with existing file.

‘ -x file ’ ‘ —exclude-file= file ’

Entries from file are not extracted. file should be a PO or POT file.

‘ -c[ tag ] ’ ‘ —add-comments[= tag ] ’

Place comment blocks starting with tag and preceding keyword lines in the output file. Without a tag , the option means to put all comment blocks preceding keyword lines in the output file.

Note that comment blocks supposed to be extracted must be adjacent to keyword lines. For example, in the following C source code:

The second comment line will not be extracted, because there is one blank line between the comment line and the keyword.

Perform a syntax check on msgid and msgid_plural. The supported checks are:

Prefer Unicode ellipsis character over ASCII .

Prohibit whitespace before an ellipsis character

Prefer Unicode quotation marks over ASCII «‘`

Prefer Unicode bullet character over ASCII * or —

The option has an effect on all input files. To enable or disable checks for a certain string, you can mark it with an xgettext: special comment in the source file. For example, if you specify the —check=space-ellipsis option, but want to suppress the check on a particular string, add the following comment:

The xgettext: comment can be followed by flags separated with a comma. The possible flags are of the form ‘ [no-] name -check ’, where name is the name of a valid syntax check. If a flag is prefixed by no- , the meaning is negated.

Some tests apply the checks to each sentence within the msgid, rather than the whole string. xgettext detects the end of sentence by performing a pattern match, which usually looks for a period followed by a certain number of spaces. The number is specified with the —sentence-end option.

The supported values are:

Expect at least one whitespace after a period

Expect at least two whitespaces after a period

5.1.6 Language specific options

Extract all strings.

This option has an effect with most languages, namely C, C++, ObjectiveC, Shell, Python, Lisp, EmacsLisp, librep, Java, C#, awk, Tcl, Perl, PHP, GCC-source, Glade, Lua, JavaScript, Vala, GSettings.

‘ -k[ keywordspec ] ’ ‘ —keyword[= keywordspec ] ’

Specify keywordspec as an additional keyword to be looked for. Without a keywordspec , the option means to not use default keywords.

If keywordspec is a C identifier id , xgettext looks for strings in the first argument of each call to the function or macro id . If keywordspec is of the form ‘ id : argnum ’, xgettext looks for strings in the argnum th argument of the call. If keywordspec is of the form ‘ id : argnum1 , argnum2 ’, xgettext looks for strings in the argnum1 st argument and in the argnum2 nd argument of the call, and treats them as singular/plural variants for a message with plural handling. Also, if keywordspec is of the form ‘ id : contextargnum c, argnum ’ or ‘ id : argnum , contextargnum c ’, xgettext treats strings in the contextargnum th argument as a context specifier. And, as a special-purpose support for GNOME, if keywordspec is of the form ‘ id : argnum g ’, xgettext recognizes the argnum th argument as a string with context, using the GNOME glib syntax ‘ «msgctxt|msgid» ’.
Furthermore, if keywordspec is of the form ‘ id :…, totalnumargs t ’, xgettext recognizes this argument specification only if the number of actual arguments is equal to totalnumargs . This is useful for disambiguating overloaded function calls in C++.
Finally, if keywordspec is of the form ‘ id : argnum . » xcomment » ’, xgettext , when extracting a message from the specified argument strings, adds an extracted comment xcomment to the message. Note that when used through a normal shell command line, the double-quotes around the xcomment need to be escaped.

This option has an effect with most languages, namely C, C++, ObjectiveC, Shell, Python, Lisp, EmacsLisp, librep, Java, C#, awk, Tcl, Perl, PHP, GCC-source, Glade, Lua, JavaScript, Vala, GSettings, Desktop.

The default keyword specifications, which are always looked for if not explicitly disabled, are language dependent. They are:

  • For C, C++, and GCC-source: gettext , dgettext:2 , dcgettext:2 , ngettext:1,2 , dngettext:2,3 , dcngettext:2,3 , gettext_noop , and pgettext:1c,2 , dpgettext:2c,3 , dcpgettext:2c,3 , npgettext:1c,2,3 , dnpgettext:2c,3,4 , dcnpgettext:2c,3,4 .
  • For Objective C: Like for C, and also NSLocalizedString , _ , NSLocalizedStaticString , __ .
  • For Shell scripts: gettext , ngettext:1,2 , eval_gettext , eval_ngettext:1,2 , eval_pgettext:1c,2 , eval_npgettext:1c,2,3 .
  • For Python: gettext , ugettext , dgettext:2 , ngettext:1,2 , ungettext:1,2 , dngettext:2,3 , _ .
  • For Lisp: gettext , ngettext:1,2 , gettext-noop .
  • For EmacsLisp: _ .
  • For librep: _ .
  • For Scheme: gettext , ngettext:1,2 , gettext-noop .
  • For Java: GettextResource.gettext:2 , GettextResource.ngettext:2,3 , GettextResource.pgettext:2c,3 , GettextResource.npgettext:2c,3,4 , gettext , ngettext:1,2 , pgettext:1c,2 , npgettext:1c,2,3 , getString .
  • For C#: GetString , GetPluralString:1,2 , GetParticularString:1c,2 , GetParticularPluralString:1c,2,3 .
  • For awk: dcgettext , dcngettext:1,2 .
  • For Tcl: ::msgcat::mc .
  • For Perl: gettext , %gettext , $gettext , dgettext:2 , dcgettext:2 , ngettext:1,2 , dngettext:2,3 , dcngettext:2,3 , gettext_noop .
  • For PHP: _ , gettext , dgettext:2 , dcgettext:2 , ngettext:1,2 , dngettext:2,3 , dcngettext:2,3 .
  • For Glade 1: label , title , text , format , copyright , comments , preview_text , tooltip .
  • For Lua: _ , gettext.gettext , gettext.dgettext:2 , gettext.dcgettext:2 , gettext.ngettext:1,2 , gettext.dngettext:2,3 , gettext.dcngettext:2,3 .
  • For JavaScript: _ , gettext , dgettext:2 , dcgettext:2 , ngettext:1,2 , dngettext:2,3 , pgettext:1c,2 , dpgettext:2c,3 .
  • For Vala: _ , Q_ , N_ , NC_ , dgettext:2 , dcgettext:2 , ngettext:1,2 , dngettext:2,3 , dpgettext:2c,3 , dpgettext2:2c,3 .
  • For Desktop: Name , GenericName , Comment , Icon , Keywords .

To disable the default keyword specifications, the option ‘ -k ’ or ‘ —keyword ’ or ‘ —keyword= ’, without a keywordspec , can be used.

‘ —flag= word : arg : flag ’

Specifies additional flags for strings occurring as part of the arg th argument of the function word . The possible flags are the possible format string indicators, such as ‘ c-format ’, and their negations, such as ‘ no-c-format ’, possibly prefixed with ‘ pass- ’.
The meaning of —flag= function : arg : lang -format is that in language lang , the specified function expects as arg th argument a format string. (For those of you familiar with GCC function attributes, —flag= function : arg :c-format is roughly equivalent to the declaration ‘ __attribute__ ((__format__ (__printf__, arg , . ))) ’ attached to function in a C source file.) For example, if you use the ‘ error ’ function from GNU libc, you can specify its behaviour through —flag=error:3:c-format . The effect of this specification is that xgettext will mark as format strings all gettext invocations that occur as arg th argument of function . This is useful when such strings contain no format string directives: together with the checks done by ‘ msgfmt -c ’ it will ensure that translators cannot accidentally use format string directives that would lead to a crash at runtime.
The meaning of —flag= function : arg :pass- lang -format is that in language lang , if the function call occurs in a position that must yield a format string, then its arg th argument must yield a format string of the same type as well. (If you know GCC function attributes, the —flag= function : arg :pass-c-format option is roughly equivalent to the declaration ‘ __attribute__ ((__format_arg__ ( arg ))) ’ attached to function in a C source file.) For example, if you use the ‘ _ ’ shortcut for the gettext function, you should use —flag=_:1:pass-c-format . The effect of this specification is that xgettext will propagate a format string requirement for a _(«string») call to its first argument, the literal «string» , and thus mark it as a format string. This is useful when such strings contain no format string directives: together with the checks done by ‘ msgfmt -c ’ it will ensure that translators cannot accidentally use format string directives that would lead to a crash at runtime.
This option has an effect with most languages, namely C, C++, ObjectiveC, Shell, Python, Lisp, EmacsLisp, librep, Scheme, Java, C#, awk, YCP, Tcl, Perl, PHP, GCC-source, Lua, JavaScript, Vala.

Understand ANSI C trigraphs for input.
This option has an effect only with the languages C, C++, ObjectiveC.

Recognize Qt format strings.
This option has an effect only with the language C++.

Recognize KDE 4 format strings.
This option has an effect only with the language C++.

Recognize Boost format strings.
This option has an effect only with the language C++.

Use the flags c-format and possible-c-format to show who was responsible for marking a message as a format string. The latter form is used if the xgettext program decided, the former form is used if the programmer prescribed it.

By default only the c-format form is used. The translator should not have to care about these details.

This implementation of xgettext is able to process a few awkward cases, like strings in preprocessor macros, ANSI concatenation of adjacent strings, and escaped end of lines for continued strings.

5.1.7 Output details

Specify whether or when to use colors and other text attributes. See The —color option for details.

Specify the CSS style rule file to use for —color . See The —style option for details.

Илон Маск рекомендует:  Что такое код msql_dbname

Always write an output file even if no message is defined.

Write the .po file using indented style.

Do not write ‘ #: filename : line ’ lines. Note that using this option makes it harder for technically skilled translators to understand each message’s context.

‘ -n ’ ‘ —add-location= type ’

Generate ‘ #: filename : line ’ lines (default).

The optional type can be either ‘ full ’, ‘ file ’, or ‘ never ’. If it is not given or ‘ full ’, it generates the lines with both file name and line number. If it is ‘ file ’, the line number part is omitted. If it is ‘ never ’, it completely suppresses the lines (same as —no-location ).

Write out a strict Uniforum conforming PO file. Note that this Uniforum format should be avoided because it doesn’t support the GNU extensions.

Write out a Java ResourceBundle in Java .properties syntax. Note that this file format doesn’t support plural forms and silently drops obsolete messages.

Write out a NeXTstep/GNUstep localized resource file in .strings syntax. Note that this file format doesn’t support plural forms.

Use ITS rules defined in file . Note that this is only effective with XML files.

Write out comments recognized by itstool (http://itstool.org). Note that this is only effective with XML files.

‘ -w number ’ ‘ —w >number ’

Set the output page w >number .

Do not break long message lines. Message lines whose width exceeds the output page width will not be split into several lines. Only file reference lines which are wider than the output page width will be split.

Generate sorted output. Note that using this option makes it much harder for the translator to understand each message’s context.

Sort output by file location.

Don’t write header with ‘ msgid «» ’ entry.

This is useful for testing purposes because it eliminates a source of variance for generated .gmo files. With —omit-header , two invocations of xgettext on the same files with the same options at different times are guaranteed to produce the same results.

Note that using this option will lead to an error if the resulting file would not entirely be in ASCII.

Set the copyright holder in the output. string should be the copyright holder of the surrounding package. (Note that the msgstr strings, extracted from the package’s sources, belong to the copyright holder of the package.) Translators are expected to transfer or disclaim the copyright for their translations, so that package maintainers can distribute them without legal risk. If string is empty, the output files are marked as being in the public domain; in this case, the translators are expected to disclaim their copyright, again so that package maintainers can distribute them without legal risk.

The default value for string is the Free Software Foundation, Inc., simply because xgettext was first used in the GNU project.

Omit FSF copyright in output. This option is equivalent to ‘ —copyright-holder=» ’. It can be useful for packages outside the GNU project that want their translations to be in the public domain.

Set the package name in the header of the output.

Set the package version in the header of the output. This option has an effect only if the ‘ —package-name ’ option is also used.

Set the reporting address for msgid bugs. This is the email address or URL to which the translators shall report bugs in the untranslated strings:

  • — Strings which are not entire sentences; see the maintainer guidelines in Preparing Strings.
  • — Strings which use unclear terms or require additional context to be understood.
  • — Strings which make invalid assumptions about notation of date, time or money.
  • — Pluralisation problems.
  • — Incorrect English spelling.
  • — Incorrect formatting.

It can be your email address, or a mailing list address where translators can write to without being subscribed, or the URL of a web page through which the translators can contact you.

The default value is empty, which means that translators will be clueless! Don’t forget to specify this option.

‘ -m[ string ] ’ ‘ —msgstr-prefix[= string ] ’

Use string (or «» if not specified) as prefix for msgstr values.

‘ -M[ string ] ’ ‘ —msgstr-suffix[= string ] ’

Use string (or «» if not specified) as suffix for msgstr values.

Перевод сайта с помощью gettext

Довольно часто перед веб-разработчиками возникает необходимость перевести сайт на несколько языков, сделать сайт мультиязычным. Многие веб-подмастерья используют для хранения переводов базу данных, тем самым создавая на неё дополнительную и ненужную нагрузку. Обращение к файловой системе имеет более высокую скорость, но создаёт необходимость грамотно огранизовать хранение и считывание переводов. Благо, в PHP уже имеется максимально оптимальный для таких целей механизм gettext, который не просто работает с файловой системой, так ещё и с уже скомпилированными файлами, обеспечивая наилучшую производительность.

Функции gettext реализуют NLS (Native Language Support) API. Официальная документация находится на сайте gnu.org. Для работы модуля требуется пакет gettext. Его можно установить из репозиториев, например в Debian-дистрибутивах это будет так:

sudo apt-get install gettext

Проверить версию установленного пакета можно командой:

Применение

Самый простой пример использования gettext в PHP:

echo _ ( «message» ) ;

Слово «message» ищется в библиотеке переводов и, при его наличии, выводится найденный перевод, иначе выводится исходное слово «message».

Сами переводы хранить неважно где, главное чтоб они были доступны для кода. Для удобства расположим их в корне сайта в папке langs. Пусть будет 3 языка: немецкий, английский и русский. Конечная структура папки langs будет такой:

.
├── de_DE
│ └── LC_MESSAGES
│ ├── de_DE.mo
│ └── de_DE.po
├── en_US
└── ru_RU
└── LC_MESSAGES
├── ru_RU.mo
└── ru_RU.po

Файлы *.po содержат переводы в текстовом виде, *.mo — их компилированные версии. В имени файлов удобно использовать их локаль. Английскому языку эти файлы не обязательны, так как все ключи в коде будем писать на нём. Для ключей можно использовать и любой другой язык, лишь бы кодировка позволяла, но если сайт международный, то крайне желательно использовать английский.

Структура po-файлов простая:

msgid «message»
msgstr «сообщение»

В начале файла пишут служебную информацию, например для русского языка можно написать так:

«POT-Creation-Date: 2020-04-10 17:15+0500\n»
«PO-Revision-Date: 2020-04-29 02:14+0500\n»
«Last-Translator: Sergey\n»
«Language: ru_RU\n»
«MIME-Version: 1.0\n»
«Content-Type: text/plain; charset=UTF-8\n»
«Content-Transfer-Encoding: 8bit\n»
«Plural-Forms: nplurals=3; plural=(n % 10==1 && n % 100!=11 ? 0 : n % 10>=2 && n % 10 =20) ? 1 : 2);\n»

Строка «Plural-Forms» задаёт правила для форм множественных чисел. Ниже в примере она будет разобрана подробнее.

Подключение файлов с переводами к проекту:

define ( ‘BASE_PATH’ , realpath ( dirname ( __FILE__ ) ) ) ;
define ( ‘LANGUAGES_PATH’ , BASE_PATH . ‘/langs’ ) ;

putenv ( «LC_ALL=» . $locale ) ;
setlocale ( LC_ALL , $locale , $locale . ‘.utf8’ ) ;
bind_textdomain_codeset ( $locale , ‘UTF-8’ ) ;
bindtextdomain ( $locale , LANGUAGES_PATH ) ;
textdomain ( $locale ) ;

Здесь подключается русский язык, чтобы подключить другой язык его нужно так же записать в переменную $locale. Брать его из выставленных пользователем настроек или из URL сайта — этот выбор зависит от особенностей Вашего сайта.

Пример использования в коде:

echo mb_ucfirst ( _ ( ‘message’ ) ) . ‘. ‘ . _ ( ‘Message’ ) . ‘. ‘ . _ ( ‘Second message’ ) . ‘. ‘ . sprintf ( _ ( ‘Message #%d’ ) , 3 ) . ‘. 4 ‘ . ngettext ( ‘message’ , ‘messages’ , 4 ) . ‘. 5 ‘ . ngettext ( ‘message’ , ‘messages’ , 5 ) . ‘.’ ;

Здесь шесть обращенией к gettext:

  1. _(‘message’)
  2. _(‘Message’)
  3. _(‘Second message’)
  4. _(‘Message #%d’)
  5. ngettext(‘message’, ‘messages’, 4)
  6. ngettext(‘message’, ‘messages’, 5)

Обращения 1, 2 и 3 максимально просты: есть ключ, ищется перевод. Обращение 4 с этой позиции ничем не отличается от предыдущих, разница лишь в последующем использовании: вставлен %d для подставления туда чисел, например с помощью sprintf. Также можно использовать любые другие ключевые слова для их последующей замены, например «%username%», и заменять их потом с помощью str_replace, главное не перевести их. Обращения 5 и 6 используют множественные формы.

Функция mb_ucfirst самописная, ибо ucfirst плохо работает с юникодом. В надежде что когда-то появится нативная функция mb_ucfirst перед определением функции делается проверка на её существование. Иногда приходится использовать одно и то же слово в разных регистрах, в таких случаях подобные функции помогают.

if ( ! function_exists ( ‘mb_ucfirst’ ) ) <
function mb_ucfirst ( $string ) <
return mb_strtoupper ( mb_substr ( $string , 0 , 1 , ‘UTF-8’ ) , ‘UTF-8’ ) . mb_substr ( $string , 1 , mb_strlen ( $string ) , ‘UTF-8’ ) ;
>
>

В итоге файл langs/ru_RU/LC_MESSAGES/ru_RU.po пусть будет таким (даты будут изменяться автоматически описанным ниже ПО):

msgid «»
msgstr «»
«POT-Creation-Date: 2020-04-10 17:15+0500\n»
«PO-Revision-Date: 2020-04-29 02:14+0500\n»
«Last-Translator: username\n»
«Language: ru_RU\n»
«MIME-Version: 1.0\n»
«Content-Type: text/plain; charset=UTF-8\n»
«Content-Transfer-Encoding: 8bit\n»
«Plural-Forms: nplurals=3; plural=(n % 10==1 && n % 100!=11 ? 0 : n % 10>=2 && n % 10 =20) ? 1 : 2);\n»

msgid «Second message»
msgstr «Второе сообщение»

msgid «Message #%d»
msgstr «Сообщение #%d»

msgid «message»
msgid_plural «messages»
msgstr[0] «сообщение»
msgstr[1] «сообщения»
msgstr[2] «сообщений»

Третья запись («message») покрывает обращения 1, 5 и 6, первая и вторая — 3 и 4. Перевод для обращения 2 не будет найден, т.к. регистрозависимость.

Третья запись здесь самая интересная, т.к. описывает множественные формы. Правила описаны в начале файла в пункте «Plural-Forms».

nplurals — количество форм, в данном случае равно трём.
plural — сами правила, представляют из себя вложенный тернарный оператор, который возвращает число от 0 до 2, в зависимости от этого числа берётся элемент из msgstr. Сравнив эти условия и числа с примером из po-файла всё станет понятно. Правила в разных языках отличаются.

Немецкий файл langs/de_DE/LC_MESSAGES/de_DE.po заполняется по аналогии:

msgid «»
msgstr «»
«POT-Creation-Date: 2020-04-10 17:15+0500\n»
«PO-Revision-Date: 2020-04-29 02:14+0500\n»
«Last-Translator: username\n»
«Language: de_DE\n»
«MIME-Version: 1.0\n»
«Content-Type: text/plain; charset=UTF-8\n»
«Content-Transfer-Encoding: 8bit\n»
«Plural-Forms: nplurals=2; plural=(n != 1);\n»

msgid «Second message»
msgstr «Zweite nachricht»

msgid «Message #%d»
msgstr «Nachricht #%d»

msgid «message»
msgid_plural «messages»
msgstr[0] «nachricht»
msgstr[1] «nachrichten»

В нём множественных форм две, потому и правило заметно проще. Также изменился пункт «Language». Это единственные поля в данном примере которые нужно менять при добавлении новых языков.

Компилирование MO

Из po-файлов получить скомпилированный mo-файл можно несколькими способами.

Первый — с помощью программ вроде Poedit. В ней есть и редактирование po-файлов и возможность автоматически компилировать файл MO при сохранении. Включается/отключается она в общих настройках приложения. Минус — нельзя задать параметры этого компилирования. Плюс — там немало возможностей для редактирования переводов; например, сканирование кода на предмет вызова gettext и добавления их в PO.

Второй способ — консольная команда msgfmt. Полный список параметров доступен в документации по ссылке, но обычно достаточно такой простой команды:

/ usr / bin / msgfmt «ru_RU.po» -f -o «ru_RU.mo»

Здесь файл ru_RU.mo компилируется из находящихся в файле ru_RU.po исходников с использованием fuzzy-записей. Fuzzy — это нечёткие переводы, которые могут быть некорректными. Появляются они, например, при автоматических переводах. Если возникают сомнения в правильности этих переводов, то параметр -f следует убрать.

Чтобы скомпилировать все файлы в папке langs можно воспользоваться bash-скриптом. Предположим, что все bash-скрипты расположены в папке bash в корне сайта:

cd ../langs
for lang_locale in * ; do
if [ ! -f » $lang_locale /LC_MESSAGES/ $lang_locale .po» ] ; then
continue
fi
cd » $lang_locale /LC_MESSAGES»
/ usr / bin / msgfmt » $lang_locale .po» -f -o » $lang_locale .mo»
echo » $lang_locale — compiled»
cd .. / .. /
done

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

$ sh compile.sh
de_DE — compiled
ru_RU — compiled

После этого можно проверить вывод переводов через PHP. Итоговый index.php выглядит так:

define ( ‘BASE_PATH’ , realpath ( dirname ( __FILE__ ) ) ) ;
define ( ‘LANGUAGES_PATH’ , BASE_PATH . ‘/langs’ ) ;

putenv ( ‘LC_ALL=’ . $locale ) ;
setlocale ( LC_ALL , $locale , $locale . ‘.utf8’ ) ;
bind_textdomain_codeset ( $locale , ‘UTF-8’ ) ;
bindtextdomain ( $locale , LANGUAGES_PATH ) ;
textdomain ( $locale ) ;

if ( ! function_exists ( ‘mb_ucfirst’ ) ) <
function mb_ucfirst ( $string ) <
return mb_strtoupper ( mb_substr ( $string , 0 , 1 , ‘UTF-8’ ) , ‘UTF-8’ ) . mb_substr ( $string , 1 , mb_strlen ( $string ) , ‘UTF-8’ ) ;
>
>

echo mb_ucfirst ( _ ( ‘message’ ) ) . ‘. ‘ . _ ( ‘Message’ ) . ‘. ‘ . _ ( ‘Second message’ ) . ‘. ‘ . sprintf ( _ ( ‘Message #%d’ ) , 3 ) . ‘. 4 ‘ . ngettext ( ‘message’ , ‘messages’ , 4 ) . ‘. 5 ‘ . ngettext ( ‘message’ , ‘messages’ , 5 ) . ‘.’ ;

Результатом выполнения кода будет это:

Сообщение. Message. Второе сообщение. Сообщение #3. 4 сообщения. 5 сообщений.

Также самостоятельно проверьте вывод в немецкой локали de_DE.

Если вывод по-прежнему на английском, то, вероятно, в Вашей системе не установлены нужные локали. Список умеющихся можно получить командой:

Недостающие можно добавить командой (на примере немецкой):

sudo locale-gen de_DE.utf8

После добавления новой локали иногда требуется перезапуск апача, иначе он её не увидит.

sudo service apache2 restart

Сканирование кода, добавление новых переводов

Ручное добавление всех новых фраз в po-файлы в процессе разработки — не самый удобный способ, из-за него приходится отвлекаться от самой разработки. Гораздо удобнее сразу писать код так, словно перевод уже есть — когда он появится тогда он и выведется. В таком случае потребуется сканирование кода на предмет новых переводов. Для этих целей используется утилита xgettext.

Добавим в index.php новое слово, пусть будет «Application»:

echo mb_ucfirst ( _ ( ‘message’ ) ) . ‘. ‘ . _ ( ‘Message’ ) . ‘. ‘ . _ ( ‘Second message’ ) . ‘. ‘ . sprintf ( _ ( ‘Message #%d’ ) , 3 ) . ‘. 4 ‘ . ngettext ( ‘message’ , ‘messages’ , 4 ) . ‘. 5 ‘ . ngettext ( ‘message’ , ‘messages’ , 5 ) . ‘. ‘ ;
echo _ ( «Application» ) ;

Bash-скрипт для сканирования кода и добавления новых найденных переводов пусть лежит в той же папке bash. Сначала разберём этот пример сканирования:

LIST = ` find . -name «*.php» `
/ usr / bin / xgettext —language =PHP $LIST —from-code =UTF- 8 —no-location —no-wrap -o / tmp / xgettext.pot

Здесь происходит поиск всех файлов *.php, затем весь этот список отдаётся в xgettext и все найденные в этих файлах фразы (без указания их расположения в файлах (—no-location) и без переносов(—no-wrap)) пишутся в /tmp/xgettext.pot. Дополнительно заданы кодировка файлов (UTF-8) и язык (PHP). Утилита поддерживает немало других языков, включая JavaScript. Название и расположение файла экспорта можно сделать любым другим, но временная папка /tmp подходит для этого дела идеально.

Получившийся файл — это стандартный po-файл, только без настроек и переводов. В нём находятся все используемые в index.php фразы: к трём уже имеющимся в наших файлах добавились две — «Message» и «Application». Добавлять их вручную к имеющимся тоже не вариант, для этих целей лучше подойдёт утилита msgmerge. В итоге со сканированием получится вот такой bash-скрипт:

cd ..
echo «Parsing. »
LIST = ` find . -name «*.php» `
/ usr / bin / xgettext —language =PHP $LIST —from-code =UTF- 8 —no-location —no-wrap -o / tmp / xgettext.pot

echo «Merging. »
cd langs

for lang_locale in * ; do
if [ ! -f » $lang_locale /LC_MESSAGES/ $lang_locale .po» ] ; then
continue
fi
echo $lang_locale
cd » $lang_locale /LC_MESSAGES»
/ usr / bin / msgmerge » $lang_locale .po» / tmp / xgettext.pot -U —backup =off —no-wrap —no-fuzzy-matching
cd .. / .. /
done

Слияние файлов $lang_locale.po и xgettext.pot происходит с обновлением первого (параметр -U), без создания бэкапа (—backup=off; ибо зачем оно когда есть git и аналоги), без переносов длинных строк (—no-wrap; ибо это мешает чтению исходников) и без автоперевода по имеющимся фразам (—no-fuzzy-matching; странный включенный по умолчанию функционал, который ищет по имеющимся переводам похожие и добавляет их к новым фразам с пометкой fuzzy, при этом работает плохо и немного замедляет весь процесс слияния).

$ sh lang.sh
Parsing.
Merging.
de_DE
. завершено.
ru_RU
. завершено.

Количество точек перед «завершено» зависит от времени выполнения.

После выполнения команды оба недостающих ранее слова добавились в po-файлы внутри папки langs. Теперь им стоит добавить перевод (вручную или с помощью Poedit) и затем выполнить компилирование.

Конечное дерево файлов данного проекта выглядит так:

.
├── bash
│ ├── compile.sh
│ └── lang.sh
├── index.php
└── langs
├── de_DE
│ └── LC_MESSAGES
│ ├── de_DE.mo
│ └── de_DE.po
├── en_US
└── ru_RU
└── LC_MESSAGES
├── ru_RU.mo
└── ru_RU.po

Добавление нового языка

Например, нужно добавить испанский язык. Обозначение локали языка можно найти, например, здесь или здесь (но вместо «-» использовать «_»). Интернациональному испанскому (или испанскому из Испании) соответствует обозначение es_ES.

Нужно проделать эти шаги:

  1. Создать папку langs/es_ES/LC_MESSAGES, в ней создать файл es_ES.po.
  2. Заполнить его по аналогии с приведёнными выше языками, подправив поля «Language» и, при необходимости, «Plural-Forms». Сами фразы можно не добавлять:
    msgid «»
    msgstr «»
    «POT-Creation-Date: 2020-04-10 17:15+0500\n»
    «PO-Revision-Date: 2020-04-29 02:14+0500\n»
    «Last-Translator: username\n»
    «Language: es_ES\n»
    «MIME-Version: 1.0\n»
    «Content-Type: text/plain; charset=UTF-8\n»
    «Content-Transfer-Encoding: 8bit\n»
    «Plural-Forms: nplurals=2; plural=(n != 1);\n
  3. Провести сканирование кода — все имеющиеся фразы добавятся в этот файл (bash-скрипт выше)
  4. Заполнить файл переводами (вручную в текстовом редакторе или специальными программами, лучше всего с этой задачей справятся переводчики)
  5. Скомпилировать MO (bash-скрипт выше)

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

Илон Маск рекомендует:  $A - Директива компилятора Delphi

Аналогично можно использовать gettext для любых других проектов с другими языками программирования.

Что такое код hw_gettext

(PHP 3>= 3.0.3, PHP 4)

hw_GetText — запрашивает текстовый документ.

Описание

int hw_gettext (int connection, int objectID [, mixed rootID/prefix])

Возвращает возвращает документ с object ID objectID . Если этот документ имеет якоря, которые могут быть вставлены, они будут вставлены. Необязательный параметр rootID/prefix может быть строкой или целым числом. Целое число определяет, как ссылки вставляются в документ. По умолчанию 0, т.е. ссылки конструируются из имени объекта назначения ссылки. Это используется для web-приложений. Если ссылка указывает на объект с именем ‘internet_movie’, HTML-ссылка будет . Реальное расположение объекта источника и объекта назначения в иерархии документа игнорируется. Вы должны будете настроить ваш web-браузер на перезапись этого URL на, к примеру, ‘/my_script.php3/internet_movie’.
‘my_script.php3’ должен будет вычислять $PATH_INFO и запрашивать документ. Все ссылки будут иметь префикс ‘/my_script.php3/’. Если вам это не нужно, вы можете установить необязательный параметр rootID/prefix на любой необходимый префикс. В этом случае он должен быть строкой.

Если rootID/prefix это целое число, не равное 0, ссылка конструируется из всех имён, начиная с объекта с id rootID/prefix , разделённых слэшем, относительно текущего объекта. Если, к примеру, документ ‘internet_movie’ размещён в ‘a-b-c-internet_movie’ с ‘-‘ в качестве разделителя уровней иерархии на Hyperwave-сервере, а документ-источник размещён в ‘a-b-d-source’, результирующая HTML-ссылка может быть: . Это используется, когда нужно загрузить содержимое всего сервера на диск и отобразить иерархию документов в файловую систему.

Эта функция будет работать только для чисто текстовых документов. Она не открывает специальное соединение данных и, следовательно, не блокирует управление соединением в ходе трансфера.

Что такое код hw_gettext

(PHP 3>= 3.0.3, PHP 4)

hw_GetText — запрашивает текстовый документ.

Описание

int hw_gettext (int connection, int objectID [, mixed rootID/prefix])

Возвращает возвращает документ с object ID objectID . Если этот документ имеет якоря, которые могут быть вставлены, они будут вставлены. Необязательный параметр rootID/prefix может быть строкой или целым числом. Целое число определяет, как ссылки вставляются в документ. По умолчанию 0, т.е. ссылки конструируются из имени объекта назначения ссылки. Это используется для web-приложений. Если ссылка указывает на объект с именем ‘internet_movie’, HTML-ссылка будет . Реальное расположение объекта источника и объекта назначения в иерархии документа игнорируется. Вы должны будете настроить ваш web-браузер на перезапись этого URL на, к примеру, ‘/my_script.php3/internet_movie’.
‘my_script.php3’ должен будет вычислять $PATH_INFO и запрашивать документ. Все ссылки будут иметь префикс ‘/my_script.php3/’. Если вам это не нужно, вы можете установить необязательный параметр rootID/prefix на любой необходимый префикс. В этом случае он должен быть строкой.

Если rootID/prefix это целое число, не равное 0, ссылка конструируется из всех имён, начиная с объекта с id rootID/prefix , разделённых слэшем, относительно текущего объекта. Если, к примеру, документ ‘internet_movie’ размещён в ‘a-b-c-internet_movie’ с ‘-‘ в качестве разделителя уровней иерархии на Hyperwave-сервере, а документ-источник размещён в ‘a-b-d-source’, результирующая HTML-ссылка может быть: . Это используется, когда нужно загрузить содержимое всего сервера на диск и отобразить иерархию документов в файловую систему.

Эта функция будет работать только для чисто текстовых документов. Она не открывает специальное соединение данных и, следовательно, не блокирует управление соединением в ходе трансфера.

Не работает метод getText() в java (примитивный пример)

Изучаю События и все такое, есть програмка в которой конпка, и поле текста в главном классе, при нажатии на кнопку срабатывает событие, обработчик в другом новом классе — открывается окошко с надписью, все норм. Но хотелось чтоб событие читало поле ввода JTextField Data = new JTextField(20); и в окошке выводилось введенная надпись. Но выбивает сообщение, будто У обьекта JTextField Data нет такого метода как Data.getText(); Весь код выглядит так:

1 ответ 1

мне кажется во втором классе вы хотите использовать объект JTextField Data из первого класса, чего делать разумеется нельзя, а по факту у вас импортирован класс javax.xml.crypto.Data , который не содержит статического метода getText()

Полагаю, что лучшим выходом будет передать текст в конструктор CalculatorEngine :

Что такое код hw_gettext

Hyperwave был разработан IICM в Гразе (Graz). Первоначально пакет назывался Hyper-G и был изменен на Hyperwave после коммерциализации (где-то в 1996).

Hyperwave не является свободно распространяемым ПО. Текущая версия, 4.0, доступна www.hyperwave.com. Существует 30-дневная версия.

Hyperwave — это информационная сиситема, похожая на базы данных ( HIS , Hyperwave Information Server). Она напраавлена на хранение документов и управление ими. Документом может быть любая часть данных, которая может быть сохранена в файле. Каждый документ сопровождается своей объектной записью. Объектная запись содержит мета-данные документа. Мета-данные — это список атрибутов, который может быть расширен пользователем. Постоянные атрибуты всегда назначаются сервером Hyperwave, остальные могут меняться пользователем.

Помимо документов, все содержащиеся в документах гиперссылки также сохраняются в виде объектных записей. Гиперссылки, содержащиеся в документе, при его вставке в базу данных удаляются и сохраняются в виде отдельных объектов. объектные записи ссылок содержат информацию о начале и конце ссылки. Для восстановления оригинала документа вым нужно будет получить «плоский» докумет, без ссылок, список ссылок и заново вставить их в документ. Для этого предназаначены функции hw_pipedocument() и hw_gettext() . Преимущества выделения ссылок из документа очевидны. Как только документ, на который указывает ссылка, изменит свое имя, соответствующая ссылка также может быть легко изменена. Документ, содержащий ссылки, не подвержен изменениям. Вы даже можете добавить в документ ссылку, не изменяя его.

Говорят, что hw_pipedocument() и hw_gettext() выполняют вставку ссылок в документ автоматически, однако быстро сказка сказывается, да не просто дело делается. Вставка ссылок предполагает неизменную иерархию документов. На веб-сервере существует иерархия, полученная от файловой системы, но Hyperwave имеет свою собственную иерархию и имена не отражают позицию объекта в этой иерархии. Поэтому оздание ссылок прежде всего требует маппинга имен из иерархии Hyperwave в соотвествующие имена иерархии веб. Фундаментальное отличие между Hyperwave и Веб заключается в том, что в Hyperwave имя и иерархия — суть разные понятия. Имя не содержит никакой информации о положении объекта в иерархии. В Веб имя содержит и информацию о том, гед объект расположен иерархически. Это указывает на два возможных пути маппинга. В URL можно отражать иерархию Hyperwave и имя объекта или только имя. С цель сделать вещи проще, второй вариант более применим. Объект Hyperwave с именем ‘my_object’ мапится в ‘http://host/my_object’ безотносительно к его положению в иерархии Hyperwave. Объект с именем ‘parent/my_object’ может быть порожден ‘my_object’ в иерархии Hyperwave, однако в пространстве имен Веб оно проявится как противоположное и пользователь может быть неприятно удивлен. Это может быть предотвращено только путем оригинального именования объектов.

Применение этого решения порождает вторую проблему. Как вы запускаете php3? URL http://host/my_object не вызовет ни одного скрипта php3 до тех пор, пока вы не укажете вашему веб-скрверу переписать ее подобным образом: ‘http://host/php3_script/my_object’ и переменная $PATH_INFO должна быть равна скрипту ‘php3_script’, и возвращется объект с именем ‘my_object’ от Hyperwave сервера. Это только один недостаток, который может быть исправлен легко. Переписывание URL не дает доступа к другим документам веб-сервера. Скрипт php3 для поиска в Hyperwave сервере принципиально невозможен. По этой причине вам необходимо по меньшей мере два переназначения правила для исключения постоянных URLов, начинающихся с http://host/Hyperwave. Это — основное разделение пространства имен между Hyperwave и веб серверами.

На основе вышеизложенных механизмов ссылки вставляются в документ.

Это получается более сложно, если php3 не запущено как скрипт module/CGI, а как самостоятельное приложение, т.е. дампит содержимое Hyperwave сервера на CD-ROM. В этом случае имеет смысл сохранять иерархию Hyperwave и мапить ее на файловую систему. Это может вызвать конфликты с именамаи объектов если оини отражают свою собственную иерархию (если имена включают символ «/»). Однако, «/» может быть заменен на другой символ, типа «_», и все вроде встенет на свои места.

Сетевой протокол соединяется с Hyperwave сервером HG-CSP (Hyper-G Client/Server Protocol). Он основан на сообщениях, инициирующих определенный события, например получекния объектной записи. Вранних версиях Hyperwave сервера предлагалось два родных клиента (Harmony, Amadeus) для связи с сервером. Оба они исчезли после коммерциализации Hyperwave. На замену пришло нечто, называемое wavemaster. Wavemaster — это нечто протоколоподобное, конвертирующее HTTP в HG-CSP . Идея состоит в том, чтобы все администрирование базами данных и визуализация документов должно осуществляться через Веб-интерфейс. Wavemaster обеспечивает множество плейсхолдеров (placeholders) для постоянных операций по насторйке интерфейса. Эти плейсхолдеры называются языком PLACE . PLACE-у недостает множества преимуществ настоящих языков программирования, и любые расширения — это только увеличение списка плейсхолдеров. Это дает мне основание к использованию JavaScript, который, IMHO, не делает жизнь легче.

Добавление поддержки Hyperwave в PHP3 было введено с целью заполнить пробелы языков програмирования в управлении интерфейсов. Оно выполлняет все сообщения, определенные в HG-CSP , и более сложныве команды по получению завершенных документов.

Hyperwave имеет свою собственную терминологию для именования различных порций информации. Это было заимствовонно и расширенно. Практически все функции оперируют с одним из следующих типов данны:

object ID: уникально целое значение для каждого объекта в Hyperwave сервере. Это также одни из атрибутов объектной записи (ObjectID). ИД объектов часто используются в качестве входных параметров для спецификации объекта.

object record: строка с парами атрибут-значение в фоме атрибут=значение. пары одделены одна от друкой символом возврата каретки. ОБъектная запись может быть просто переконвертирована в объектный массив: hw_object2array() . Несколько функций (их имена заканчиваются на obj) возвращают объектные записи.

object array: ассоциативный массив со всеми атрибутами объекта. Ключ — имя атрибута. Если атрибут встречается в объектной записи несколько раз, это ведет к появлению другого индекса или индексного массива. Атрибуты, определнные в языке, будут иметь множство ключей, аббревиатур языка в ассоциативном массиве. Все другие множественные атрибуты формируют индексные массивы. Функции php3 никогда не возвращают объектных массивов.

hw_document: это совершенно новый тип данных, который описывает наличный документ, напимер HTML, PDF и др. Он несколько оптимизированн под HTML, но может быть использован и с другими форматами.

Несколько функций, возвращающих массивы объектных записей также возвращают ассоциативный массив со статистической информацией о нем. Этот массив — последний элемент массива объектных записей. Статистический массив содержит следующие поля:

Число объектных записей с атрибутом PresentationHints, установленным в Hidden. CollectionHead

Число объектных записей с атрибутом PresentationHints, установлденным в CollectionHead. FullCollectionHead

Число объектных записей с атрибутом PresentationHints, установленным в FullCollectionHead. CollectionHeadNr

Индекс в массиве объектных записей с атрибутом PresentationHints, установленным в CollectionHead. FullCollectionHeadNr

Индекс в массиве объектных записей с атрибутом PresentationHints, установленным в FullCollectionHead. Total

Общее число объектных записей. Интеграция с Apache

Модуль Hyperwave лучьше всего использовать, когда PHP3 скомпилированн в как модуль Apache. В этом случае основной Hyperwave сервер может быть скрыт от пользователя почти полностью, если Apache использует свой движок. Это объясняют следующие инструкции.

С тех пор, как PHP3 с Hyperwave поддерживают встраивание в Апач, предполагается, что родное решение Hyperwave — wavemaster — автоматически замещается. Т.е. Апач примет на себя функции веб-интерфейса к Hyperwave. Это не есть необходимость, но конфигурация упрощается. Идея достаточно проста. Перво-наперво вам необходим PHP3-скрипт, который оценивает переменную PATH_INFO и рассматривает ее значение как имя Hyperwave объекта. Пусть скрипт называется ‘Hyperwave’. URL http://your.hostname/Hyperwave/name_of_object возвратит Hyperwave объект с именем ‘name_of_object’. Реакция скрипта зависит от типа объекта. Если это коллекция, он возможно вернет список наследников. Если это документ, он возвратит mime-тип и содержание. Небольшое улучшение может быть достигнуто, если используется движок перезаписи Апача. С точки зрения пользователя, это более прямой путь, если URL http://your.hostname/name_of_object будет возвращать объект. Правило перезаписи достаточно простое:

для возврвта самого объекта

для разрешения проблемы поиска

для идентификации вас

для установки профиля

один для каждой дополнительной функции, как то показа атрибутов объекта. показа информации о пользователе, показа статуса сервера и др.

Замечания

Еще несколько заечаний:

Функция hw_InsertDocument расщеплена на hw_InsertObject() и hw_PutDocument() .

Имена некоторых функций пока еще не подтверждены.

Мольшинство функций требуют текущее соединение как первый параметр. Это ведет к достаточно большому количеству лишнего набора, что в большинстве случев излищне, поскольку существует только одно соединение. Соединение по умолчанию предоставляет улучшенный вариант решения.

hw_Changeobject

Описание

int hw_changeobject (int connection, int object_to_change, string commands);

Команда позволяет удалить, добавить или модифицировать индивидуальные атрибуты объектной записи. Объекты указываются идентификатором оюъекта, object_to_change ; команды придерживаются следующего синитаксиса:

Возвращает True при отсутствии ошибок, иначе False.

hw_Children

Описание

array hw_children (int connection, int objectID);

Возвращает массив идентификаторов объектов. Каждый иденитификатор — часть коллекции с идентификатором objectID . Массив содержит всех наследников, документы и коллекции.

hw_ChildrenObj

Описание

array hw_childrenobj (int connection, int objectID);

Возвращает массив объектных записей. Каждая запись — часть коллекции с идентификатором objectID . Массив содержит всех наследников, документы и коллекции.

hw_Close

Описание

int hw_close (int connection);

Возвращет false, если соединение не является действующим, в противном случае — true. Closes закрывает соединение с Hyperwave сервером с указанным номером соединения connection.

hw_Connect

Описание

int hw_connect (string host, int port, string username, string password);

Открывает соединение с Hyperwave сервером и возвращает номер соединение при успешном открытиии, или False, ели слединение не может быть установлено. Каждый аргумент должен быть «закавыченой» строкой, исключая номер порта. Аргумент username и password опциональны и могут не указываться. В случае ошибки идентификации, сервер завершит работу. Проще использовать идентификацию как пользователь anonymous. Функция возращает индекс соединения, необходимы для других функций Hyperwave. Вы можете открыть несколько соединений. Помните, что пароли не шифруются.

hw_Cp

Описание

int hw_cp (int connection, array object_id_array, int destination id);

Копирует объекты с идентификаторами, указанными во втором параметре в коллекцию с идентификатором destination id .

Возвращается число скопированных объектов.

hw_Deleteobject

Описание

int hw_deleteobject (int connection, int object_to_delete);

Удаляет объект с идентификатором, указанным во втором параметре. Будут удалены все экземпляры объекта.

При отсутствии ошибок возвращает true, инача — false.

hw_DocByAnchor

Описание

int hw_docbyanchor (int connection, int anchorID);

Возвращает идентификатор оъекта документа, который относится к якорю anchorID .

hw_DocByAnchorObj

Описание

string hw_docbyanchorobj (int connection, int anchorID);

Возвращает объектную запись объекта документа, относящегося к якорю anchorID .

hw_DocumentAttributes

Описание

string hw_documentattributes (int hw_document);

Возвращает объектную запись документа.

hw_DocumentBodyTag

Описание

string hw_documentbodytag (int hw_document);

Возвращает тег BODY для документа. Если документ в формате HTML, тег BODY должен быть напечатен перед документом.

hw_DocumentSize

Описание

int hw_documentsize (int hw_document);

Возвращает размер документа в байтах.

hw_ErrorMsg

Описание

string hw_errormsg (int connection);

Возвращает строку, содержащую последнее сообщени об ошибке или ‘No Error’. Если возвратилось False, функция не выполнилась. Сообщение относится к последней команде.

hw_EditText

Описание

int hw_edittext (int connection, int hw_document);

Загружет текстовый документ на сервер. Объектная запись документа не должна модифицироваться, пока документ редактируется. Эта функция работает только с чисто текстовыми документами. Она не отрывает специальных соединений для данных, поэтому управление соединением во время передачи данных блокируется.

hw_Error

Описание

int hw_error (int connection);

Возвращет номер последней ошибки. Если 0 — ошибок не было. Ошибка относится к последней команде.

hw_Free_Document

Описание

int hw_free_document (int hw_document);

освобождает память, занятую hw-документом.

hw_GetParents

Описание

array hw_getparentsobj (int connection, int objectID);

Возвращает индексированный массив идентификаторов объектов. Каждый ИД объекта относится к родителям объекта с идентификатором objectID .

hw_GetParentsObj

Описание

array hw_getparentsobj (int connection, int objectID);

Возвращает индексированный массив объектных записей плюс ассоциативный массив со статистической информацией об объектных записях. Ассоциативный массив — последний член возвращенного массива. Каждая объектная запись относится к родителю объекта с ИД objectID .

hw_GetChildColl

Описание

array hw_getchildcoll (int connection, int objectID);

Возвращает массив идентификаторов оюъектов. Каждый ИД объекта относится к наследной коллекции, коллекции с идентификатором objectID . Функция не возвращает наследуемые документы.

hw_GetChildCollObj

Описание

array hw_getchildcollobj (int connection, int objectID);

Возвращает массив объектных записей. Каждая запись относится к наследной коллекции, коллекции с идентификатором objectID . Функция не возвращает наследуемые документы.

hw_GetSrcByDestObj

Описание

array hw_getsrcbydestobj (int connection, int objectID);

Возвращает объектные записи всех якорных точек объекта с ИД objectID . Объект может быть как документом, так и якорем.

hw_GetObject

Описание

array hw_getobject (int connection, int objectID);

Возвращает объектную запись объекта с идентификатором objectID .

hw_GetAndLock

Описание

string hw_getandlock (int connection, int objectID);

Возвращает объектную запись объекта с ИД objectID . Объект также запирается, поэтому другие позователи не имеют к нему доступа, пока объект не будет разблокирован.

hw_GetText

Описание

int hw_gettext (int connection, int objectID, int rootID);

Возвращается документ с идентификатором объекта objectID . Если документ имеет якоря, которые можно вставить, то они будут сразу вставлены. Опциональный параметр rootID определяет, как ссылки будут вставляться в документ. По умолчанию подставляется 0, что означает конструирование ссылок из имен объктов назначения ссылок. Это применимо для веб-приложений. Если ссылка указывает на объект с именем ‘internet_movie’, ссылка HTML будет выглядеть как . Настоящее положение исходного объекта и объекта назначения в иерархии документа полностью игнорируется. Вы будете вынуждены установить ваш браузер, переписать URL приблизительно так: example ‘/my_script.php3/internet_movie’. ‘my_script.php3’ обработает $PATH_INFO и выдаст документ.

Илон Маск рекомендует:  Dos fn 14h читать последовательный файл через fcb

Если rootID не равен 0, ссылка конструируется из всех имен, начиная с объекта с ИД rootID , разделенных слешами от текущего объекта. Если для предидущего примера документ ‘internet_movie’ расположен в ‘a-b-c-internet_movie’, где ‘-‘ — разделители между уровнями иерархии, и исходный документ расположен по пути ‘a-b-d-source’, результирующая HTML-ссылка будет: . Это используется, если вы хотите утянуть се содержание сервера на диск и мапить иерархию докмента на файловую систему.

Эта функция работает только с чисто текстовыми документами. Она не отрывает специальных соединений для данных, поэтому управляющее соединение во время передачи данных блокируется.

hw_GetObjectByQuery

Описание

array hw_getobjectbyquery (int connection, string query, int max_hits);

Ищет объекты по всему серверу и возвращает массив идентификаторов объектов. Максимальное число найденных димитируется в max_hits . Если max_hits установлен в -1, то максимальное число ответов не ограниченно.

hw_GetObjectByQueryObj

Описание

array hw_getobjectbyqueryobj (int connection, string query, int max_hits);

Ищет объекты по всему серверу и возвращает массив объектных записей. Максимальное число найденных димитируется в max_hits . Если max_hits установлен в -1, то максимальное число ответов не ограниченно.

hw_GetObjectByQueryColl

Описание

array hw_getobjectbyquerycoll (int connection, int objectID, string query, int max_hits);

Ищет объект в коллекции с идентификатором objectID и возвращает массив идентификаторов объектов. Максимальное число найденных димитируется в max_hits . Если max_hits установлен в -1, то максимальное число ответов не ограниченно.

hw_GetObjectByQueryCollObj

Описание

array hw_getobjectbyquerycollobj (int connection, int objectID, string query, int max_hits);

Ищет объект в коллекции с идентификатором objectID и возвращает массив объектных записей. Максимальное число найденных димитируется в max_hits . Если max_hits установлен в -1, то максимальное число ответов не ограниченно.

hw_GetChildDocColl

Описание

array hw_getchilddoccoll (int connection, int objectID);

Возвращает массив идентификатров объектов наследуемых документов коллекции.

Смотри также hw_GetChildren() , hw_GetChildColl() .

hw_GetChildDocCollObj

Описание

array hw_getchilddoccollobj (int connection, int objectID);

Возвращает массив идентификатров объектов наследуемых документов коллекции.

hw_GetAnchors

Описание

array hw_getanchors (int connection, int objectID);

Возвращает массив идентификаторов объектов для якорей документа с ИД objectID .

hw_GetAnchorsObj

Описание

array hw_getanchorsobj (int connection, int objectID);

Возвращает массив объектных записей для якорей документа с ИД objectID .

hw_Mv

Описание

int hw_mv (int connection, array object id array, int source id, int destination id);

Перемещает объект с объектным идентификатром, указанным во втором параметре, из коллекции с идентификатором source id в коллекцию с идентификатором destination id . Если исходный ИД равен 0, объекты будут «отвязаны» от исходной коллекции. Если это последний экземпляр этого объекта, он будет удален.

Возвращется число перемещенных объектов.

hw_ >hw_Identify — идентификация пользователя

Описание

int hw_identify (string username, string password);

Идентификация пользователя с именем username и паролем password . Идентификация имеет силу только для текущей сессии. Я не думаю, что данная функция так уж часто используется. В большинстве случаев будет проще проводить идентификацию при установлении соединения.

hw_InCollections

Описание

array hw_incollections (int connection, array object_id_array, array collection_id array, int return_collections);

Проверяет, является ли множество объектов (документов или коллекций), определенное в object_id_array , частью коллекций, определенных в коллекции id_array . Если четвертый параметр return_collections равен 0, подмножество идентификаторов объектов, которое является частью коллекций (т.е. документы или коллекции, которые являются наследниками одной или более коллекций идентификаторов коллекции или их подколлекций, рекурсивно) возвращается как массив. Когда четвертый праметр равен 1, однако, множество соллекций, которые имеют наследников в этом подмножестве, возвращается как массив. Это позволяет пользователю, например, подчеркнуть часть иерархии коллекции, которая содержит находки предидущего запроса, в графическом виде.

hw_Info

Описание

string hw_info (int connection);

Возвращает сведения о текущем соединении. Возвращаемая строка имеет следующий формат: , ,

hw_InsColl

Описание

int hw_inscoll (int connection, int objectID, array object_array);

Вставить новую коллекцию с атрибутами как в object_array в коллекцию с идентификатором objectID .

hw_InsDoc

Описание

int hw_insdoc (int connection, int parentID, string object_record, string text);

Вставить новый документ с атрибутами как в object_array в коллекцию с идентификатором objectID . Эта функци может добавить как отдельную объектную запись, так и чистый ascii текст из text , если text получен. Если вы хотите добавить документ в общем, используйте hw_insertdocument() .

hw_InsertDocument

Описание

int hw_putdocument (int connection, int parent_id, int hw_document);

Загружает документ в коллекцию parent_id . Перед этим документ должен быть создан hw_NewDocument() . Удостоверьтесь, что объектная запись нового документа содержит следующие атрибуты: Type, DocumentType, Title и Name. Возможно, вы захотите также установить MimeType.

hw_New_Document

Описание

int hw_new_document (string document_data, string object_record, int document_size);

Возвращает новый hw-документ с данными, установленными по document_data и объектной записью object_record . Длина данных документа document_data передается в document_size . Эта функция не добавляет документ в Hyperwave сервер.

hw_Objrec2Array

Описание

array hw_objrec2array (string object_record);

Преобразует object_record в объектный массив.

hw_OutputDocument

Описание

int hw_outputdocument (int hw_document);

Печатает документ без тега BODY.

hw_pConnect

Описание

int hw_pconnect (string host, int port, string username, string password);

Возвращает индекс соединения в случае удачи, или false, если соединение не может быть установлено. Открывает устойчивое соединение с Hyperwave сервером. Каждый аргумент должен быть «заавыченной» строкой, исключая номер порта. Аргументы username и password опциональны и могут быть опущены. В случае ошибки идентификации, сервер будет остановлен. Проще применять вход пользователя anonymous. В ыможете открыть множество устойчивых соединений.

hw_PipeDocument

Описание

int hw_pipedocument (int connection, int objectID);

Возвращает hw-документ с идентификатором objectID . Если документ имеет якоря, которые можно вставить, то данная операция произойдет автоматически. Документ передается через специальное соединение для данных, поэтому управляющее соединение не блокируется.

hw_Root

Описание

Возвращает объектный идентификатор для гиперкоренной коллекции. Обычно это 0. Наследная коллекция от гиперкорневой — корневая, на сервере, с которым установлено соединение.

hw_Unlock

Описание

int hw_unlock (int connection, int objectID);

Разблокирует документ для доступа другим пользователям.

Как можно использовать gettext, чтобы помочь мне здесь?

Я пытаюсь создать способ разрешить членам переводить строки на другие языки. Здесь вы можете увидеть пример: ИСПЫТАНИЕ ПЕРЕВОДОВ

Кто-то рекомендовал, чтобы я использовал собственную функцию gettext () php для этого, вместо того, что я уже использую для загрузки языковых файлов, что и есть:

Строки содержатся в файле, который называется так: ManageDPModules.english.php DreamPortal.english.php и т. Д.

Эти файлы могут выглядеть следующим образом: при открытии в любом php-редакторе и могут иметь много из этих переменных $ txt:

Для сохранения переводов я использую следующую функцию:

Я не вижу, как gettext поможет. Невозможно обновить текстовый каталог без перезагрузки сервера каждый раз. Может быть, если кто-то может создать демо для меня?

Кроме того, хотелось бы, чтобы он поддерживал UTF-8. Данные должны быть согласованными.

Итак, что не так с этой реализацией? Зачем использовать gettext? Как его можно использовать для улучшения перевода для работы как с языковыми строками UTF-8, так и с языком UTF-8, чтобы он мог быть переведен.

EDIT: Обратите внимание, что файлы в конечном итоге должны быть переименованы в: ManageDPModules.[language].php , DreamPortal.[language].php и т. Д. И т. Д., Чтобы переводы работали. Итак, как каталоги помогут мне в этом отношении? Если вы хотите увидеть возможные END-RESULT Translations, вы можете скачать языковой пакет, расположенный здесь, и открыть языковые файлы .german.php, чтобы посмотреть, как он будет выглядеть после того, как участник отправит язык в файл по файлу. Отмечено, что некоторые из этих пакетов имеют строки UTF-8, а некоторые нет. Имя файла пакета сообщит вам об этом. Было бы неплохо, если бы я мог также поддержать его UTF-8, но это не является обязательным требованием. Обратите внимание: я не собираюсь создавать полные пакеты здесь. Я просто хочу создать языковой файл. [Language] .php со всеми переведенными строками внутри них (что мой код уже делает).

Хорошо, я предоставил ENTIRE файл index.php для этого, чтобы вы могли видеть, что именно он делает, когда выполняете переводы. Вот файл index.php для этого, и вам понадобятся некоторые файлы на английском языке: DreamPortal.english.php , ManageDPModules.english.php и DreamHelp.english-utf8.php . Теперь, чтобы увидеть это, вам нужно загрузить на сервер, index.php, создать несколько папок, где указан index.php, вызвать 1 английский и создать там папку для каждого дополнительного языка (я сделал 2 папки, испанский и французский), чем загрузить 3 языковых файла в английскую папку. Запустите index.php в своем браузере, и вы увидите, что он работает.

Теперь, как я мог использовать gettext для каталогов с этим SAME. Мне нужно включить онлайн-перевод файлов. Мне нужно создать PHP-файлы переводов в стиле SAME, которые имеют файлы .english.php с тем же PREFIX, что и раньше .english.php , и мне нужно изменить язык в имени файла на тот же язык, определенный для имя папки. Онлайн-переводы – это единственный способ. Необходимость переводчика ТОЛЬКО для перевода строк. Они не должны сосредотачиваться на установке программ, их упаковке, переименовании файлов и т. Д. И т. Д. Это делает этот процесс настолько безболезненным, насколько это возможно, позволяя делать это онлайн. И я знаю, что есть способ сделать это и даже для поддержки UTF-8. Но я использую лучший метод, который я знаю как на данный момент. Но многие из вас МНОГО умнее в этом, чем я, поэтому я прошу помощи у вас, ребята.

Есть ли кто-нибудь, кто может показать мне лучший способ? Пример, подобный тому, который я дал вам в этом вопросе?

Мне нужно, чтобы переводы выполнялись ONLINE от переводчиков, а также хотели бы, чтобы он поддерживал файлы UTF-8, а также файлы без UTF-8. Мне нравится, как у меня есть настройка для ссылки, приведенной выше ( TRANSLATIONS TEST ), чтобы переводчик мог просто выполнять переводы онлайн и не беспокоиться ни о чем другом, и он автоматически создавал нужные файлы. Который будет совпадать с английским именем файла языка с именем папки (представляющим язык) после первого . (точка), и он должен иметь расширение .php (как в коде, который я использую в настоящее время). Поэтому в основном мне нужна адаптация текущего index.php для поддержки UTF-8 и не UTF-8 для всех или большинства языков, и ему сказали, что с помощью gettext () и файлов каталога это поможет.

Ищете модифицированную версию моего текущего index.php для использования gettext () таким образом, чтобы он поддерживал большинство, если не все, языков и переводов. REGEX, который я получил для preg_replace, не является полностью удовлетворительным, потому что он, кажется, помещает переднюю косую перед двойными кавычками при сохранении / отправке переводов. Поэтому, возможно, также потребуется улучшение на preg_replace.

Я представил полный пример с ACTUAL CODE bytheway. Я бы хотел, чтобы кто-то изменил этот пример, с КОДОМ, который я предоставил вместо USE GETTEXT, и поддерживаю UTF-8. Или на самом деле предоставить АКТУАЛЬНЫЙ МЕТОД, чтобы я сделал это сам. Не ищите кучу ссылок, которые я могу найти самостоятельно!

Когда вам рекомендуется использовать gettext, на самом деле рекомендуется использовать gettext- like систему перевода. Ваш текущий код сложный из-за мнемонических текстовых указаний. И проблема, с которой вы столкнулись с регулярными выражениями для редактирования, вызвана путаницей переменных. Позвольте мне предложить альтернативный код для переходных целей.

Красота gettext заключается в использовании ненавязчивого API. Вызов функции _() достаточно прост, чтобы полностью использоваться без добавления синтаксиса или раздувания кода. Он предпочитает такие вещи, как getTextTrans(‘ABBR_TXT_ID’) . Использование таких мнемонических текстовых идентификаторов является широко распространенной ошибкой; потому что на практике не часто повторяются слова и _(«Raw english original text.») . Однако, поскольку у вас уже есть мнемонические ключи, держите их, если это слишком много для изменения. Это всего лишь рекомендация.

Реальная проблема заключается в использовании встроенных выражений PHP для создания строк перевода. Именно поэтому регулярные выражения для вашего редактора переводов стали непрозрачными. Поэтому я настоятельно рекомендую использовать статические строки и предоставить заполнители. Функция перевода должна быть поручена с ее обработкой. (Не беспокойтесь о микрооптимизации здесь!) – Я бы использовал, например, <$url_xy>заполнители стиля PHP / Smarty:

И функция перевода, которая ищет глобальную таблицу-заполнитель или параметры ($ context) для замены:

Оптимизируемое. Но таким образом вы можете использовать статический мнемонический-> текстовый или английский-> текстовый набор трансляционных массивов. Вы используете только статические строки в текстовом редакторе-редакторе. Эти статические строки отображаются как-есть, и ваши переводчики редактируют текст на английском языке, но не в <$placeholders>.

Следовательно, ваш код для функции перевода не будет нуждаться в каких-либо сложных регулярных выражениях (в этом случае они не являются полезными) для сопоставления строк и встроенных переменных PHP. Фактически гораздо более простая комбинация include() и var_export() теперь может занять свое место:

Обработка файлов и многое другое нужно настраивать, конечно. Но все же это более простой подход.

И это также позволит вам перейти к одному из вариантов gettext как backend. Сохраните свою пользовательскую функцию-обертку __() и используйте, например, Zend_Translate в качестве backend. Это позволяет вам использовать файлы перевода .php $ txt = array () (или, я думаю, так), или перейти к файлам .mo / .po gettext-style. Преимущество этого заключается в том, что есть богатая поддержка инструмента в отличие от доморощенных решений.

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

Вначале было бы желательно перейти от клавиш short_txt к англо-английским> чужеродным текстам, но теоретически любой из бэкэндов из ответа dvbs будет применим. Теперь вы уже сказали, что родной gettext не является для вас вариантом (для PHP, не относящихся к fastcgi, сопротивление памяти является недостатком). Но PHP-возможности для встроенных функций INTL могут вам помочь. В частности, http://www.php.net/manual/en/class.messageformatter.php может быть более полезной, чем простая оболочка замены <$ var>, которую я вам дал. Но я никогда не использовал его, и я думаю, что Zend_Translate, скорее всего, более полезен. В частности, любой из этих бэкендов дает вам независимость от набора символов. Лично я бы просто придерживался UTF-8, несмотря ни на что. Но, например, файлы gettext .mo / .po могут иметь свою собственную кодировку.

Зачем изобретать колесо? Может быть, я не понимаю, но я уверен, что то, что вы пытаетесь сделать, было сделано раньше.

Просто используйте одно из многих существующих решений.

  • Посетите каждый из них и отфильтровывайте нерелевантные проекты
  • Изучите различия между остальными и выберите тот, который вам подходит лучше всего.
  • Продолжайте разрабатывать и настраивать свои собственные потребности на основе существующего проекта
  • Если вы обнаружили ошибку или если вы считаете, что исходный проект принесет пользу из ваших дополнений, свяжитесь с автором и сообщите ему

Вот о чем подумать, когда принимаете решения:

  • Язык, который использует проект
  • Возможность расширения, добавления функций и настройки в соответствии с вашими потребностями
  • Это услуга? или с открытым исходным кодом, который вы можете загрузить и использовать на своем собственном сервере
  • Поддерживает ли он перевод множественных чисел?
  • Сообщество и ресурсы, доступные для этого проекта
  • Имеет ли он также веб-интерфейс, как вы просили?

Вот некоторые (случайным образом упорядоченные):

  • entrans
  • Pootle
  • glotpress
  • Розеттский
  • globalsight
  • tcktranslator
  • kartouche
  • subtitrans
  • tmsphp
  • i18nedit
  • Открытый механизм перевода
  • Переводчик GNU GetText
  • SiteTranslator
  • phptrans
  • Строка myGengo
  • NetBabel
  • translatewiki

Обновление: спасибо, Эль-Йобо. Я отметил это как вики сообщества, любой может отредактировать или ответить другим проектам, если найдет что-то еще.

В чем разница между getString() и getText()?

Я попытался использовать getString() , чтобы получить строку из моего string.xml
Однако. Я просто нашел, что метод getText() может извлекать теги HTML из моих ресурсов!

это меня удивило, потому что мне пришлось использовать Html.fromHtml() для извлечения тегов HTML, которые устарели.

В чем разница между двумя методами?
Есть ли какие-либо преимущества или недостатки?

Из документа doc

Возвращает строковое значение, связанное с определенным идентификатором ресурса. Это будут лишены любой текстовой информации в стиле.

Возвращает строковое значение, связанное с определенным идентификатором ресурса. Возвращаемый объект будет String, если это простая строка; это будет некоторый другой тип CharSequence, если он оформлен.

[Обратите внимание, что Context.getText() и Context.getString() внутренне вызывает методы из Resources .]

Док говорит, что getText() сохраняет стиль, а getString() — нет. Но вы можете использовать один из них, чтобы получить строковый ресурс с тегами HTML из strings.xml , но способ отличается.

Использование Resource.getText():

Вы можете просто вызвать getText() (обратите внимание, что он возвращает CharSequence не a String , поэтому он имеет свойства стилизации) и установите текст в TextView . Нет необходимости в Html.fromHtml() .

Но doc говорит, что этот метод поддерживает только ограниченные теги HTML, такие как , , . исходный код, похоже, предполагает, что он поддерживает больше: , , , , , , , ,
, , , and

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL