apiClient = $apiClient; $this->locales = $locales; $this->settings = $settings; } /** * {@inheritdoc} * * @return ClientView */ public function render(Request $request, array $routeParams = []) { $actor = app('flarum.actor'); $assets = $this->getAssets(); $locale = $this->getLocaleCompiler($actor); $view = new ClientView( $this->apiClient, $request, $actor, $assets, $locale, $this->layout ); // Now that we've set up the ClientView instance, we can fire an event // to give extensions the opportunity to add their own assets and // translations. We will pass an array to the event which specifies // which translations should be included in the locale file. Afterwards, // we will filter all of the translations for the actor's locale and // compile only the ones we need. $translations = $this->locales->getTranslations($actor->locale); $keys = $this->translationKeys; event(new BuildClientView($this, $view, $keys)); $translations = $this->filterTranslations($translations, $keys); $locale->setTranslations($translations); return $view; } /** * Set up the asset manager, preloaded with a JavaScript compiler and a LESS * compiler. Automatically add the files necessary to boot a Flarum client, * as well as any configured LESS customizations. * * @return AssetManager */ protected function getAssets() { $public = $this->getAssetDirectory(); $assets = new AssetManager( new JsCompiler($public, "$this->clientName.js"), new LessCompiler($public, "$this->clientName.css") ); $this->addAssets($assets); $this->addCustomizations($assets); return $assets; } /** * Add the assets necessary to boot a Flarum client, found within the * directory specified by the $clientName property. * * @param AssetManager $assets */ protected function addAssets(AssetManager $assets) { $root = __DIR__.'/../..'; $assets->addFile("$root/js/$this->clientName/dist/app.js"); $assets->addFile("$root/less/$this->clientName/app.less"); } /** * Add any configured JS/LESS customizations to the asset manager. * * @param AssetManager $assets */ protected function addCustomizations(AssetManager $assets) { $assets->addLess(function () { $less = ''; foreach ($this->getLessVariables() as $name => $value) { $less .= "@$name: $value;"; } $less .= $this->settings->get('custom_less'); return $less; }); } /** * Get the values of any LESS variables to compile into the CSS, based on * the forum's configuration. * * @return array */ protected function getLessVariables() { return [ 'fl-primary-color' => $this->settings->get('theme_primary_color', '#000'), 'fl-secondary-color' => $this->settings->get('theme_secondary_color', '#000'), 'fl-dark-mode' => $this->settings->get('theme_dark_mode') ? 'true' : 'false', 'fl-colored-header' => $this->settings->get('theme_colored_header') ? 'true' : 'false' ]; } /** * Set up the locale compiler for the given user's locale. * * @param User $actor * @return LocaleJsCompiler */ protected function getLocaleCompiler(User $actor) { $locale = $actor->locale; $compiler = new LocaleJsCompiler($this->getAssetDirectory(), "$this->clientName-$locale.js"); foreach ($this->locales->getJsFiles($locale) as $file) { $compiler->addFile($file); } return $compiler; } /** * Get the path to the directory where assets should be written. * * @return string */ protected function getAssetDirectory() { return public_path().'/assets'; } /** * Take a selection of keys from a collection of translations. * * @param array $translations * @param array $keys * @return array */ protected function filterTranslations(array $translations, array $keys) { $filtered = []; foreach ($keys as $key) { $parts = explode('.', $key); $level = &$filtered; foreach ($parts as $part) { $level = &$level[$part]; } $level = array_get($translations, $key); } return $filtered; } }