wintercms / web-installer

Web-based installer for Winter CMS
https://wintercms.com/
MIT License
30 stars 4 forks source link

Support for different languages #2

Open bennothommo opened 3 years ago

bennothommo commented 3 years ago

The installer should be welcoming to people of all languages, so we should at some point implement support for some internationalization of the content of the installer.

While applying i18n to the PHP side should be easy enough, the Vue side might be more tricky, although there's a great i18n plugin available for Vue - https://kazupon.github.io/vue-i18n/.

LukeTowers commented 3 years ago

I think I've used the following code before to make backend translations available to the vue plugin:

Route::get('/api/translation-messages', function () {
  // Store the generated data in the cache, cache will be manually emptied whenever a message updates
  // Cache::forget('author.plugin.translation-messages');
  $cacheData = Cache::rememberForever('author.plugin.translation-messages', function () {
    $translator = Translator::instance();
    $availableLocales = array_keys(LocaleModel::listEnabled());
    $activeLocale = $translator->getLocale();
    $fallbackLocale = $translator->getDefaultLocale();

    // NOTE: The actual message code is stored under "x" in the message data, the code column is
    // used in the database and turns any symbols into ".", which would turn the key account.create_header
    // into account.create.header. Thus we must request the "x" column and use it as the code
    $messageData = (new MessageExport())->exportData(MessageExport::getColumns() + ['x']);

    $messagesByLocale = [];
    foreach ($messageData as $message) {
      foreach ($availableLocales as $locale) {
        if (!empty($message[$locale])) {
          array_set($messagesByLocale, $locale . '.' . $message['x'], $message[$locale]);
        }
      }
    }

    $responseData = [
      'locale' => $activeLocale,
      'fallbackLocale' => $fallbackLocale,
      'messages' => $messagesByLocale,
    ];

    return [
      'data' => base64_encode(json_encode($responseData)),
      'etag' => md5($activeLocale . $fallbackLocale . implode('|', array_dot($messagesByLocale))),
      'last_modified' => now()->timestamp,
    ];
  });

  // Set the proper caching headers on the messages
  $response = Response::make();
  $response->header('Content-Type', 'application/json');
  $response->header('Cache-Control', 'private, max-age=604800');
  $response->setLastModified((new DateTime())->setTimestamp($cacheData['last_modified']));
  $response->setEtag($cacheData['etag']);
  $response->setPublic();
  $modified = !$response->isNotModified(App::make('request'));
  if ($modified) {
    $response->setContent(base64_decode($cacheData['data']));
  }

  return $response;
});
$.getJSON('/api/translation-messages').done(function (data) {
    vueParams.i18n = new VueI18n(data || {});
  }).always(function () {
    new Vue(vueParams);
  });
bennothommo commented 3 years ago

@LukeTowers ah yeah, I remember you showing me that once before. That'd work nicely!