Ваше требование:
чтобы мой сайт работал на нескольких языках
как аутентифицированный пользователь
мне нужно иметь возможность переводить сразу все переводы, найденные в базе кода моего сайта, которые были выполнены с помощью функции t ().
Это описание требования даже близко к тому, что вы просите?
ползунки
Как кто-то сказал - сканер теоретически может пройти весь сайт, чтобы форсировать регистрацию всех вызовов t (). Но 1) сканер не знает, какие страницы сканировать; 2) поэтому мы не стремимся вести список страниц для сканирования; 3) мы не хотим использовать сканер, точка. Eww. Просто, фуу. Правильно?
Проблема
- У нас нет списка всех строк перевода.
- Drupal / PHP - это динамический язык в отличие от C, который компилируется. Поэтому мы не можем пойти и сказать, например: скомпилировать всю эту кодовую базу, затем найти мне все экземпляры этой функции
t()
, затем зарегистрировать эти экземпляры в базе данных, а затем перевести все эти зарегистрированные экземпляры за t()
один раз. Я не думаю, что это вариант, который мы имеем на нашем столе.
- Инструмент статического анализа кода был бы беспомощен по той же причине, по которой сканер был бы беспомощен. Я нашел это
t()
в этом файле. Большой! В каком URL он используется? Какой контекст?
Атака проблемы с текущими инструментами (Drupal, и некоторыми модулями contrib), а также с текущими ограничениями (опирающимися на вызовы тем в реальном времени -> файлы шаблонов -> t()
вызовы), выглядит здесь как выход без выхода. Возможно, нам нужно подумать немного нестандартно.
Что нам нужно
- Нам нужен источник данных, модель, которая сообщает мне, какие у нас есть текущие строки перевода и каков их контекст -
- Проактивная модель данных. Текущая модель данных является реактивной (модель обновляется всякий раз, когда происходит вызов
t()
). Нам нужна упреждающая модель данных - та, в которой приложение заботится о поиске t()
экземпляров до того, как они действительно будут выполнены клиентом.
- Нам нужен контекст.
t()
одно только не сокращает это - потому что - мы не знаем, что мы переводим 'foo', но целевой язык, на который мы переводим, зависит от URL того, где t()
происходит. Даже если бы мы могли жестко закодировать целевой язык в t()
вызове, скажем, используя вызов-обертку, это не сработало бы для ваших целей.
Я определил некоторые инструменты, которые - если бы они у нас были - помогли бы решить нашу проблему. С помощью этих инструментов мы могли бы перейти к модели данных и сказать: дайте мне все обернутые строки, t()
которые еще не были заполнены. Теперь вставьте эти переводы. Спасибо.
И в следующий раз, когда придет клиент, переводы будут на месте.
Как бы мы ... создали эти инструменты?
Ограничения
- Целевой язык не может быть в шаблоне, который определяется URL. Предполагая, что строка должна поддерживать любой язык.
- Переведенная строка не может быть в шаблоне. Перевод будет находиться в базе данных.
Теперь, когда я обдумал проблему и выявил некоторые проблемы и ограничения, я могу подумать о том, чтобы посмотреть на любые доступные решения или на создание любых собственных решений.
Решение мозгового штурма
Мне нужно что-то, что связывает "все" вместе. Как насчет ... сущности?
- Сущность может содержать продукт, который необходимо перевести.
- Сущности могут обеспечить связь - клей - между продуктом, который необходимо перевести, и его контекстом.
- Сущность может указать, скажем, в поле 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-адрес узла? Можно ли изменить «контекст»? Где записан контекст? Что происходит, когда у вас есть «динамические» шаблоны - то есть, когда у вас есть более одного шаблона для каждого продукта и как вы обнаруживаете эти варианты?
Как всегда, теоретизирование и псевдокод хороши только для мозгового штурма. Но в процессе разработки мы вряд ли узнаем, с чем мы действительно столкнулись, пока не начнем создавать прототипы. Итак, разработав пару ограничений, возможных решений и возможных проблем или вопросов, я теперь могу приступить к реализации концепции или рабочего прототипа. На некоторые открытые вопросы, приведенные выше, можно ответить только таким образом, и как только мы создадим прототип (независимо от успеха или неудачи), мы сможем начать отвечать на некоторые из этих вопросов или вообще изменить подход. Оставайтесь с нами ~
wget
или что-то еще. Хакиш, но ты же говорил, что разрешено (: