Как сделать так, чтобы строки из шаблонов переводились на все появляющиеся страницы?

14

У меня есть несколько звонков t() в * .tpl.php файлах. Для примера, скажем, я говорю о продуктах и ​​файле product.tpl.php.

Строки в шаблонах не распознаются до первого использования. На Drupal.org была ветка об этом, и я нашел ее точной. К сожалению, если я пойду, скажем, на http://example.com/pl/product/200 , то эта строка будет сохранена в {locales_source}таблице с locationустановленным полем /pl/product/200.

Мне нужно, чтобы мои пользователи могли переводить, используя инструмент локального перевода клиентского модуля Локализация , чтобы они могли видеть, что они переводят, в правильном контексте. С исходным местоположением, установленным на /pl/product/200, продукт с идентификатором 200 является единственным, для которого показана строка, которую нужно перевести. И что еще хуже, если я смогу заставить пользователей переводить на этот конкретный продукт, мне нужно, чтобы они также могли переводить на русский язык, и нет продукта с указанным местоположением /ru/product/PID.

Есть ли способ переформатировать строку местоположения в базе данных, чтобы сделать все строки видимыми на всех продуктах, на всех языках в инструменте l10n_client?

Я попытался установить его на:

  • ; sites/default/themes/mytheme/product.tpl.php,
  • sites/default/themes/mytheme/product.tpl.php,
  • sites/default/modules/mymodule/mymodule.module (модуль, который генерирует тематические данные)

Но это только сделало их невидимыми для инструмента перевода.

Я почти уверен, что это не ошибка в клиенте Localization , он показывает строку, в которой, как сообщается, эта строка произошла. И, похоже, это «так же, как это работает» и для системы перевода Drupal 7 - уже обсуждалось и сообщалось, и ничего не изменилось. Так что это не отчет об ошибках, я просто спрашиваю, как работать с тем, с чем мы должны работать.


Я говорю о текстах, которые не имеют ничего общего с модулем данных . Я не хочу переводить продукты, просто строки шаблонов, которые не имеют ничего общего с самим продуктом, как «Предыдущий - Следующий» в шаблоне галереи изображений продуктов.

Например, модуль возвращает 15 миниатюр, и работа темы - показывать 5 раз. И предыдущие / следующие ссылки нужны altи titleатрибуты. В переводе. Но мой модуль этого не знает. И никогда не должно быть.

МОЛОТ
источник
Я не уверен, что полностью понял, что вы хотите, но будет ли достаточно сканирования сайта на всех языках? Вы можете использовать, например. xmlsitemap для создания ссылок на нескольких языках, а затем использовать wgetили что-то еще. Хакиш, но ты же говорил, что разрешено (:
Энди
@Andy Localization Client позволяет пользователям открывать панель внизу страницы и переводить тексты, которые появляются на этой странице, непосредственно, когда они их видят. Я могу хорошо экспортировать все тексты, но это не совсем так.
Молот
1
Я помню из drupal_set_message () и dpm (), что эти сообщения будут помещены в очередь для следующего запроса, если они будут вызваны, например, из page.tpl.php. Это связано с тем, что шаблоны обычно обрабатываются довольно поздно в запросе после обработки сообщений. Нечто подобное может быть и в случае с t () и клиентом локализации.
Donquixote
Хороший вопрос Хорошая проблема.
любительская бариста
Просто предложение ... если вы хотите, чтобы ваши пользователи могли переводить ваши строки tpl t () в любое время на любой язык, вы можете извлечь эти строки с помощью экстрактора шаблона перевода ( drupal.org/project/potx ) и дать им оригинал .po, чтобы их можно было перевести с помощью такого инструмента, как Poedit? ( poedit.net ). Поскольку вы представляете эти строки как несколько статических, каждый переводчик будет выполнять эту работу за один раз ...
Kojo

Ответы:

5

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

Это описание требования даже близко к тому, что вы просите?


ползунки

Как кто-то сказал - сканер теоретически может пройти весь сайт, чтобы форсировать регистрацию всех вызовов t (). Но 1) сканер не знает, какие страницы сканировать; 2) поэтому мы не стремимся вести список страниц для сканирования; 3) мы не хотим использовать сканер, точка. Eww. Просто, фуу. Правильно?


Проблема

  1. У нас нет списка всех строк перевода.
  2. Drupal / PHP - это динамический язык в отличие от C, который компилируется. Поэтому мы не можем пойти и сказать, например: скомпилировать всю эту кодовую базу, затем найти мне все экземпляры этой функции t(), затем зарегистрировать эти экземпляры в базе данных, а затем перевести все эти зарегистрированные экземпляры за t()один раз. Я не думаю, что это вариант, который мы имеем на нашем столе.
  3. Инструмент статического анализа кода был бы беспомощен по той же причине, по которой сканер был бы беспомощен. Я нашел это t()в этом файле. Большой! В каком URL он используется? Какой контекст?

Атака проблемы с текущими инструментами (Drupal, и некоторыми модулями contrib), а также с текущими ограничениями (опирающимися на вызовы тем в реальном времени -> файлы шаблонов -> t()вызовы), выглядит здесь как выход без выхода. Возможно, нам нужно подумать немного нестандартно.


Что нам нужно

  1. Нам нужен источник данных, модель, которая сообщает мне, какие у нас есть текущие строки перевода и каков их контекст -
  2. Проактивная модель данных. Текущая модель данных является реактивной (модель обновляется всякий раз, когда происходит вызов t()). Нам нужна упреждающая модель данных - та, в которой приложение заботится о поиске t()экземпляров до того, как они действительно будут выполнены клиентом.
  3. Нам нужен контекст. t()одно только не сокращает это - потому что - мы не знаем, что мы переводим 'foo', но целевой язык, на который мы переводим, зависит от URL того, где t()происходит. Даже если бы мы могли жестко закодировать целевой язык в t()вызове, скажем, используя вызов-обертку, это не сработало бы для ваших целей.

Я определил некоторые инструменты, которые - если бы они у нас были - помогли бы решить нашу проблему. С помощью этих инструментов мы могли бы перейти к модели данных и сказать: дайте мне все обернутые строки, t()которые еще не были заполнены. Теперь вставьте эти переводы. Спасибо.

И в следующий раз, когда придет клиент, переводы будут на месте.

Как бы мы ... создали эти инструменты?


Ограничения

  1. Целевой язык не может быть в шаблоне, который определяется URL. Предполагая, что строка должна поддерживать любой язык.
  2. Переведенная строка не может быть в шаблоне. Перевод будет находиться в базе данных.

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

Решение мозгового штурма

Мне нужно что-то, что связывает "все" вместе. Как насчет ... сущности?

  • Сущность может содержать продукт, который необходимо перевести.
  • Сущности могут обеспечить связь - клей - между продуктом, который необходимо перевести, и его контекстом.
  • Сущность может указать, скажем, в поле URL-адрес по умолчанию для продукта.
  • Токены можно использовать для указания альтернативных мест (языков?), На которых будет отображаться продукт.
  • Объекты предоставляют нам упреждающую модель данных, которая нам нужна, и ее контекст. Что, в свою очередь, позволяет нам делать такие вещи, как: войти в базу данных, захватить все сущности продукта, и, если у них нет строки перевода для полей X, Y и Z, создать эти строки перевода.

Когда клиент берет /pl/product/200, вы отправляетесь в БД, просматриваете продукт 200 и получаете уже существующий plперевод. У вас есть поле для заголовка и заголовка для этого продукта? Переводы должны быть там же.

Обратите внимание, что я очень расплывчатый и общий в смысле того, какой модуль перевода вы используете. Вы вполне могли бы в конечном итоге использовать свой собственный модуль перевода - скорее всего, это так. Все модели переводов, которые я видел в Drupal до сих пор (начиная с D7, еще не смотрели на D8), являются реактивными, а не проактивными.

В двух словах

Теоретически, инструменты для создания того, что вам нужно, есть сущности, являющиеся ключевым компонентом, который связал бы все воедино: - данные (строка перевода), - целевые языки. Не обязательно быть в самой организации, желательно словарь таксономии, скажем, для языков продукта. или, возможно, общая таксономия для других организаций. - Контекст. URL, на котором появляется объект. URL будет содержать токен, а токен в свою очередь будет ссылаться на таксономию целевого языка.

С помощью этих трех ингредиентов вы можете сказать: захватить все productсущности, перейти к URL aliasполю, получить жетон таксономии, просмотреть все возможные комбинации терминов, представить все комбинации текущему пользователю с использованием очень большой уродливой формы - или AJAX - и многоэтапные формы (что-то в этом роде), и поскольку вошедший в систему пользователь переводит различные языки для продукта 200, сохраните их где-нибудь в базе данных

Где-то в базе данных может быть поле Field API в объекте, поле настроек, принадлежащее каждому объекту (не только Field API, но он все еще может содержать данные), или отдельная таблица, которую вы используете для этого. Я думаю, что сохранение данных в Entity сделает код и данные аккуратнее и проще.


Строительство это: возможные решения

  • D8MI (многоязычная инициатива Drupal 8)
  • Пользовательский код: «индексные» переводы, доступные в шаблонах с помощью t (), программным путем запрашивая и отображая доступные пакеты и связанные с ними реализации ловушек тем.

ПСЕВДОКОД

Сущность Foreach (типа x),
Найти все языки (таксономия или основной язык, связанный с продуктом),
Визуализировать сущность,
- чтобы обнаружить ее t () строк перевода
- выполнить вызовы theme (), который обрабатывает многоязычный уровень представления продукт, а не сама модель данных продукта.

Результат:
- Первый вызов для отображения шаблона сущности на каждом языке возвращает реализацию языка по умолчанию для каждого вызова.
- Параметры t () в шаблоне теперь кэшируются в Drupal и готовы к переводу (для каждого экземпляра языка, а не для каждого экземпляра продукта).
- Пользователь с ролью «переводчик» теперь может перейти в интерфейс перевода и перевести все доступные параметры t () для каждого языка.
- Владельцу сайта не нужно ждать, пока клиенты посетят каждую страницу продукта, или посетить каждую страницу продукта вручную, поскольку это было сделано программно для него.

Открытые вопросы:
- Каков контекст? Если я выполняю программный вызов theme () для каждого пакета сущностей «product», записывает ли он местоположение, из которого был сделан вызов? Записывает ли URL-адрес узла? Можно ли изменить «контекст»? Где записан контекст? Что происходит, когда у вас есть «динамические» шаблоны - то есть, когда у вас есть более одного шаблона для каждого продукта и как вы обнаруживаете эти варианты?

Как всегда, теоретизирование и псевдокод хороши только для мозгового штурма. Но в процессе разработки мы вряд ли узнаем, с чем мы действительно столкнулись, пока не начнем создавать прототипы. Итак, разработав пару ограничений, возможных решений и возможных проблем или вопросов, я теперь могу приступить к реализации концепции или рабочего прототипа. На некоторые открытые вопросы, приведенные выше, можно ответить только таким образом, и как только мы создадим прототип (независимо от успеха или неудачи), мы сможем начать отвечать на некоторые из этих вопросов или вообще изменить подход. Оставайтесь с нами ~

любитель бариста
источник
1
Даже не читая весь пост, такой ответ заслуживает одобрения
Олег Виденов
Дело в том, что инструмент, который утверждает, что он делает именно то, что мне нужно для Drupal 7, уже существует. Проблема в том, что Drupal сохраняет эти строки с неверными метаданными. Но я могу изменить указанные метаданные в БД после сбора строк, нет проблем. Мне просто нужно знать, на что их установить, чтобы инструмент мог это видеть. Или, по крайней мере, я верил, что это то, что мне нужно. И самое важное: я не хочу переводить продукты, просто строки шаблонов, которые не имеют ничего общего с самим продуктом, как «Предыдущий - Следующий» в шаблоне галереи изображений продуктов.
Молот
2

Хорошо, потратил еще немного времени на локализацию клиента и модуля перевода сущностей, чтобы воспроизвести тот же сценарий. Так как этот ответ полностью отличается от моего предыдущего, добавив в качестве отдельного комментария:

  1. Перевод, добавленный для языка в одном / первом узле, доступен для всех узлов.

    Вот пример:

    • Если я добавлю новый продукт того же типа, что и nid 200, и перейду к переводу pl ​​в новый узел (скажем, pl / product / 204), я бы увидел ту же строку перевода в pl / product / 200.

    • Разница лишь в том, что он не отображается в клиенте локализации. Мы можем запросить эту функцию в очереди выдачи модуля, однако это приведет к еще большей путанице, поскольку перевод не относится только к текущей странице и повлияет на все страницы (т. Е. Оба - pl / product / 200 и pl / product / 204).

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

  2. Строка доступна в клиенте локализации для первого языка, который вы посещаете для того же узла

    Вот пример:

    • Если я добавлю новый продукт nid 199 и создам перевод для языка 'pl' (nid 200) и перевод для языка 'rs' (nid 201), вы можете увидеть строку только на странице 'pl', но не на странице 'rs'. Опять же, это похоже на ограничение в клиентском модуле локализации.
vijaycs85
источник
1

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

Очевидно, что если у вас есть русская версия продукта 200, это будет новый узел, например, / ru / product / 201, где вы можете переводить с помощью клиента локализации.

Просто подумайте: найдите строку, которую можно перевести для всех языков в интерфейсе перевода интерфейса, и попросите клиента перевести уровень продукта, когда это действительно необходимо. Вот пример:

«Это продукт категории бар»

и если мы уверены, что кроме 'foo' и 'bar' могут быть общие, мы можем добавить

$vars['product_title'] = t('This is product @product of category @category')

в препроцессе.

и файл .tpl.php будет

<?php t($product_title, array('@product' => t('foo'),  '@category' => t('bar')); ?>
vijaycs85
источник
Это больше о titleтекстах для стрелок в ротаторе изображений. Моему модулю все равно, как тема будет отображать 15 изображений. И тема отображает 5 одновременно, с стрелками «предыдущая» и «следующая», которые нуждаются altи title, и нуждаются в их переводе. Изменение модуля каждый раз, когда мой интерфейс будет меняться, возможно, но, конечно, не нужно. Эти строки не имеют ничего общего с самим модулем. И последнее, но не менее важное: я могу просто не знать, какие строки в теме изменены. Или недоступно для миграции их в модуль.
Молот
ИМХО, этот случай должен обрабатываться в интерфейсе перевода интерфейса вместо клиента локализации.
vijaycs85
Цель клиента локализации - разрешить «исправлять переводы на вашем сайте, когда вы видите проблемы». - почему это не должно применяться к файлам шаблонов? Строки в TPL еще более чувствительны к контексту, они появляются, во всяком случае.
Молот
1

AFAIK с помощью экстрактора шаблонов перевода вы можете извлечь строку во всех ваших вызовах t()функции.

Средство извлечения шаблона перевода предоставляет веб-интерфейс и интерфейс извлечения шаблона перевода Gettext для командной строки для Drupal, а также многоразовый API для поиска переводимых строк и ошибок в переводимости. Этот инструмент используется под капотом на http://localize.drupal.org/, а также в качестве механизма разбора для релизов проекта Drupal.org.

Читать это Как перевести модуль?

Адриан Сид Альмагуер
источник