mirror of
https://github.com/flarum/core.git
synced 2025-07-24 02:01:19 +02:00
Refactor frontend code to allow for extension of assets
- Simpler class naming: Frontend\CompilerFactory → Frontend\Assets Frontend\HtmlDocumentFactory → Frontend\Frontend Frontend\HtmlDocument → Frontend\Document - Remove AssetInterface and simply collect callbacks in Frontend\Assets instead - Remove ContentInterface because it serves no purpose (never type- hinted or type-checked) - Commit and add asset URLs to the Document via a content callback instead of in the Document factory class itself - Add translations and locale assets to Assets separate to the assets factory, as non-forum/admin asset bundles probably won't want them - Update Frontend Extender to allow the creation of new asset bundles - Make custom LESS validation listener a standalone class instead of extending RecompileFrontendAssets
This commit is contained in:
46
framework/core/src/Frontend/AddLocaleAssets.php
Normal file
46
framework/core/src/Frontend/AddLocaleAssets.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
use Flarum\Locale\LocaleManager;
|
||||
|
||||
class AddLocaleAssets
|
||||
{
|
||||
/**
|
||||
* @var LocaleManager
|
||||
*/
|
||||
protected $locales;
|
||||
|
||||
/**
|
||||
* @param LocaleManager $locales
|
||||
*/
|
||||
public function __construct(LocaleManager $locales)
|
||||
{
|
||||
$this->locales = $locales;
|
||||
}
|
||||
|
||||
public function to(Assets $assets)
|
||||
{
|
||||
$assets->localeJs(function (SourceCollector $sources, string $locale) {
|
||||
foreach ($this->locales->getJsFiles($locale) as $file) {
|
||||
$sources->addFile($file);
|
||||
}
|
||||
});
|
||||
|
||||
$assets->localeCss(function (SourceCollector $sources, string $locale) {
|
||||
foreach ($this->locales->getCssFiles($locale) as $file) {
|
||||
$sources->addFile($file);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
64
framework/core/src/Frontend/AddTranslations.php
Normal file
64
framework/core/src/Frontend/AddTranslations.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
use Flarum\Locale\LocaleManager;
|
||||
|
||||
class AddTranslations
|
||||
{
|
||||
/**
|
||||
* @var LocaleManager
|
||||
*/
|
||||
protected $locales;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $filter;
|
||||
|
||||
public function __construct(LocaleManager $locales, callable $filter = null)
|
||||
{
|
||||
$this->locales = $locales;
|
||||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
public function forFrontend(string $name)
|
||||
{
|
||||
$this->filter = function (string $id) use ($name) {
|
||||
return preg_match('/^.+(?:\.|::)(?:'.$name.'|lib)\./', $id);
|
||||
};
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function to(Assets $assets)
|
||||
{
|
||||
$assets->localeJs(function (SourceCollector $sources, string $locale) {
|
||||
$sources->addString(function () use ($locale) {
|
||||
$translations = $this->getTranslations($locale);
|
||||
|
||||
return 'flarum.core.app.translator.addTranslations('.json_encode($translations).')';
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private function getTranslations(string $locale)
|
||||
{
|
||||
$translations = $this->locales->getTranslator()->getCatalogue($locale)->all('messages');
|
||||
|
||||
return array_only(
|
||||
$translations,
|
||||
array_filter(array_keys($translations), $this->filter)
|
||||
);
|
||||
}
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Asset;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
|
||||
interface AssetInterface
|
||||
{
|
||||
/**
|
||||
* @param SourceCollector $sources
|
||||
*/
|
||||
public function js(SourceCollector $sources);
|
||||
|
||||
/**
|
||||
* @param SourceCollector $sources
|
||||
*/
|
||||
public function css(SourceCollector $sources);
|
||||
|
||||
/**
|
||||
* @param SourceCollector $sources
|
||||
* @param string $locale
|
||||
*/
|
||||
public function localeJs(SourceCollector $sources, string $locale);
|
||||
|
||||
/**
|
||||
* @param SourceCollector $sources
|
||||
* @param string $locale
|
||||
*/
|
||||
public function localeCss(SourceCollector $sources, string $locale);
|
||||
}
|
@@ -1,48 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Asset;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
|
||||
class CoreAssets implements AssetInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function js(SourceCollector $sources)
|
||||
{
|
||||
$sources->addFile(__DIR__."/../../../js/dist/$this->name.js");
|
||||
}
|
||||
|
||||
public function css(SourceCollector $sources)
|
||||
{
|
||||
$sources->addFile(__DIR__."/../../../less/$this->name.less");
|
||||
}
|
||||
|
||||
public function localeJs(SourceCollector $sources, string $locale)
|
||||
{
|
||||
}
|
||||
|
||||
public function localeCss(SourceCollector $sources, string $locale)
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,82 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Asset;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
|
||||
class ExtensionAssets implements AssetInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $moduleName;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $css;
|
||||
|
||||
/**
|
||||
* @var string|callable|null
|
||||
*/
|
||||
protected $js;
|
||||
|
||||
/**
|
||||
* @param string $moduleName
|
||||
* @param array $css
|
||||
* @param string|callable|null $js
|
||||
*/
|
||||
public function __construct(string $moduleName, array $css, $js = null)
|
||||
{
|
||||
$this->moduleName = $moduleName;
|
||||
$this->css = $css;
|
||||
$this->js = $js;
|
||||
}
|
||||
|
||||
public function js(SourceCollector $sources)
|
||||
{
|
||||
if ($this->js) {
|
||||
$sources->addString(function () {
|
||||
return 'var module={}';
|
||||
});
|
||||
|
||||
if (is_callable($this->js)) {
|
||||
$sources->addString($this->js);
|
||||
} else {
|
||||
$sources->addFile($this->js);
|
||||
}
|
||||
|
||||
$sources->addString(function () {
|
||||
return "flarum.extensions['$this->moduleName']=module.exports";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public function css(SourceCollector $sources)
|
||||
{
|
||||
foreach ($this->css as $asset) {
|
||||
if (is_callable($asset)) {
|
||||
$sources->addString($asset);
|
||||
} else {
|
||||
$sources->addFile($asset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function localeJs(SourceCollector $sources, string $locale)
|
||||
{
|
||||
}
|
||||
|
||||
public function localeCss(SourceCollector $sources, string $locale)
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Asset;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
|
||||
class LessVariables implements AssetInterface
|
||||
{
|
||||
/**
|
||||
* @var SettingsRepositoryInterface
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @param SettingsRepositoryInterface $settings
|
||||
*/
|
||||
public function __construct(SettingsRepositoryInterface $settings)
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function css(SourceCollector $sources)
|
||||
{
|
||||
$this->addLessVariables($sources);
|
||||
}
|
||||
|
||||
public function localeCss(SourceCollector $sources, string $locale)
|
||||
{
|
||||
$this->addLessVariables($sources);
|
||||
}
|
||||
|
||||
private function addLessVariables(SourceCollector $compiler)
|
||||
{
|
||||
$vars = [
|
||||
'config-primary-color' => $this->settings->get('theme_primary_color', '#000'),
|
||||
'config-secondary-color' => $this->settings->get('theme_secondary_color', '#000'),
|
||||
'config-dark-mode' => $this->settings->get('theme_dark_mode') ? 'true' : 'false',
|
||||
'config-colored-header' => $this->settings->get('theme_colored_header') ? 'true' : 'false'
|
||||
];
|
||||
|
||||
$compiler->addString(function () use ($vars) {
|
||||
return array_reduce(array_keys($vars), function ($string, $name) use ($vars) {
|
||||
return $string."@$name: {$vars[$name]};";
|
||||
}, '');
|
||||
});
|
||||
}
|
||||
|
||||
public function js(SourceCollector $sources)
|
||||
{
|
||||
}
|
||||
|
||||
public function localeJs(SourceCollector $sources, string $locale)
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Asset;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
use Flarum\Locale\LocaleManager;
|
||||
|
||||
class LocaleAssets implements AssetInterface
|
||||
{
|
||||
/**
|
||||
* @var LocaleManager
|
||||
*/
|
||||
protected $locales;
|
||||
|
||||
/**
|
||||
* @param LocaleManager $locales
|
||||
*/
|
||||
public function __construct(LocaleManager $locales)
|
||||
{
|
||||
$this->locales = $locales;
|
||||
}
|
||||
|
||||
public function localeJs(SourceCollector $sources, string $locale)
|
||||
{
|
||||
foreach ($this->locales->getJsFiles($locale) as $file) {
|
||||
$sources->addFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function localeCss(SourceCollector $sources, string $locale)
|
||||
{
|
||||
foreach ($this->locales->getCssFiles($locale) as $file) {
|
||||
$sources->addFile($file);
|
||||
}
|
||||
}
|
||||
|
||||
public function js(SourceCollector $sources)
|
||||
{
|
||||
}
|
||||
|
||||
public function css(SourceCollector $sources)
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,87 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Asset;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
use Flarum\Locale\LocaleManager;
|
||||
|
||||
class Translations implements AssetInterface
|
||||
{
|
||||
/**
|
||||
* @var LocaleManager
|
||||
*/
|
||||
protected $locales;
|
||||
|
||||
/**
|
||||
* @var callable
|
||||
*/
|
||||
protected $filter;
|
||||
|
||||
/**
|
||||
* @param LocaleManager $locales
|
||||
*/
|
||||
public function __construct(LocaleManager $locales)
|
||||
{
|
||||
$this->locales = $locales;
|
||||
|
||||
$this->filter = function () {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
public function localeJs(SourceCollector $sources, string $locale)
|
||||
{
|
||||
$sources->addString(function () use ($locale) {
|
||||
$translations = $this->getTranslations($locale);
|
||||
|
||||
return 'flarum.core.app.translator.addTranslations('.json_encode($translations).')';
|
||||
});
|
||||
}
|
||||
|
||||
private function getTranslations(string $locale)
|
||||
{
|
||||
$translations = $this->locales->getTranslator()->getCatalogue($locale)->all('messages');
|
||||
|
||||
return array_only(
|
||||
$translations,
|
||||
array_filter(array_keys($translations), $this->filter)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return callable
|
||||
*/
|
||||
public function getFilter(): callable
|
||||
{
|
||||
return $this->filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $filter
|
||||
*/
|
||||
public function setFilter(callable $filter)
|
||||
{
|
||||
$this->filter = $filter;
|
||||
}
|
||||
|
||||
public function js(SourceCollector $sources)
|
||||
{
|
||||
}
|
||||
|
||||
public function css(SourceCollector $sources)
|
||||
{
|
||||
}
|
||||
|
||||
public function localeCss(SourceCollector $sources, string $locale)
|
||||
{
|
||||
}
|
||||
}
|
@@ -11,25 +11,34 @@
|
||||
|
||||
namespace Flarum\Frontend;
|
||||
|
||||
use Flarum\Frontend\Asset\AssetInterface;
|
||||
use Flarum\Frontend\Compiler\CompilerInterface;
|
||||
use Flarum\Frontend\Compiler\JsCompiler;
|
||||
use Flarum\Frontend\Compiler\LessCompiler;
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
* A factory class for creating frontend asset compilers.
|
||||
*/
|
||||
class CompilerFactory
|
||||
class Assets
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $sources = [
|
||||
'js' => [],
|
||||
'css' => [],
|
||||
'localeJs' => [],
|
||||
'localeCss' => []
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var FilesystemAdapter
|
||||
* @var Filesystem
|
||||
*/
|
||||
protected $assetsDir;
|
||||
|
||||
@@ -43,23 +52,7 @@ class CompilerFactory
|
||||
*/
|
||||
protected $lessImportDirs;
|
||||
|
||||
/**
|
||||
* @var AssetInterface[]
|
||||
*/
|
||||
protected $assets = [];
|
||||
|
||||
/**
|
||||
* @var callable[]
|
||||
*/
|
||||
protected $addCallbacks = [];
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param FilesystemAdapter $assetsDir
|
||||
* @param string $cacheDir
|
||||
* @param array|null $lessImportDirs
|
||||
*/
|
||||
public function __construct(string $name, FilesystemAdapter $assetsDir, string $cacheDir = null, array $lessImportDirs = null)
|
||||
public function __construct(string $name, Filesystem $assetsDir, string $cacheDir = null, array $lessImportDirs = null)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->assetsDir = $assetsDir;
|
||||
@@ -67,76 +60,84 @@ class CompilerFactory
|
||||
$this->lessImportDirs = $lessImportDirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $callback
|
||||
*/
|
||||
public function add(callable $callback)
|
||||
public function js($sources)
|
||||
{
|
||||
$this->addCallbacks[] = $callback;
|
||||
$this->addSources('js', $sources);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function css($callback)
|
||||
{
|
||||
$this->addSources('css', $callback);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function localeJs($callback)
|
||||
{
|
||||
$this->addSources('localeJs', $callback);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function localeCss($callback)
|
||||
{
|
||||
$this->addSources('localeCss', $callback);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function addSources($type, $callback)
|
||||
{
|
||||
$this->sources[$type][] = $callback;
|
||||
}
|
||||
|
||||
private function populate(CompilerInterface $compiler, string $type, string $locale = null)
|
||||
{
|
||||
$compiler->addSources(function (SourceCollector $sources) use ($type, $locale) {
|
||||
foreach ($this->sources[$type] as $callback) {
|
||||
$callback($sources, $locale);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JsCompiler
|
||||
*/
|
||||
public function makeJs(): JsCompiler
|
||||
{
|
||||
$compiler = new JsCompiler($this->assetsDir, $this->name.'.js');
|
||||
|
||||
$this->addSources($compiler, function (AssetInterface $asset, SourceCollector $sources) {
|
||||
$asset->js($sources);
|
||||
});
|
||||
$this->populate($compiler, 'js');
|
||||
|
||||
return $compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LessCompiler
|
||||
*/
|
||||
public function makeCss(): LessCompiler
|
||||
{
|
||||
$compiler = $this->makeLessCompiler($this->name.'.css');
|
||||
|
||||
$this->addSources($compiler, function (AssetInterface $asset, SourceCollector $sources) {
|
||||
$asset->css($sources);
|
||||
});
|
||||
$this->populate($compiler, 'css');
|
||||
|
||||
return $compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $locale
|
||||
* @return JsCompiler
|
||||
*/
|
||||
public function makeLocaleJs(string $locale): JsCompiler
|
||||
{
|
||||
$compiler = new JsCompiler($this->assetsDir, $this->name.'-'.$locale.'.js');
|
||||
|
||||
$this->addSources($compiler, function (AssetInterface $asset, SourceCollector $sources) use ($locale) {
|
||||
$asset->localeJs($sources, $locale);
|
||||
});
|
||||
$this->populate($compiler, 'localeJs', $locale);
|
||||
|
||||
return $compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $locale
|
||||
* @return LessCompiler
|
||||
*/
|
||||
public function makeLocaleCss(string $locale): LessCompiler
|
||||
{
|
||||
$compiler = $this->makeLessCompiler($this->name.'-'.$locale.'.css');
|
||||
|
||||
$this->addSources($compiler, function (AssetInterface $asset, SourceCollector $sources) use ($locale) {
|
||||
$asset->localeCss($sources, $locale);
|
||||
});
|
||||
$this->populate($compiler, 'localeCss', $locale);
|
||||
|
||||
return $compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filename
|
||||
* @return LessCompiler
|
||||
*/
|
||||
protected function makeLessCompiler(string $filename): LessCompiler
|
||||
{
|
||||
$compiler = new LessCompiler($this->assetsDir, $filename);
|
||||
@@ -152,86 +153,41 @@ class CompilerFactory
|
||||
return $compiler;
|
||||
}
|
||||
|
||||
protected function fireAddCallbacks()
|
||||
{
|
||||
foreach ($this->addCallbacks as $callback) {
|
||||
$assets = $callback($this);
|
||||
$this->assets = array_merge($this->assets, is_array($assets) ? $assets : [$assets]);
|
||||
}
|
||||
|
||||
$this->addCallbacks = [];
|
||||
}
|
||||
|
||||
private function addSources(CompilerInterface $compiler, callable $callback)
|
||||
{
|
||||
$compiler->addSources(function ($sources) use ($callback) {
|
||||
$this->fireAddCallbacks();
|
||||
|
||||
foreach ($this->assets as $asset) {
|
||||
$callback($asset, $sources);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FilesystemAdapter
|
||||
*/
|
||||
public function getAssetsDir(): FilesystemAdapter
|
||||
public function getAssetsDir(): Filesystem
|
||||
{
|
||||
return $this->assetsDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FilesystemAdapter $assetsDir
|
||||
*/
|
||||
public function setAssetsDir(FilesystemAdapter $assetsDir)
|
||||
public function setAssetsDir(Filesystem $assetsDir)
|
||||
{
|
||||
$this->assetsDir = $assetsDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCacheDir(): ?string
|
||||
{
|
||||
return $this->cacheDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cacheDir
|
||||
*/
|
||||
public function setCacheDir(?string $cacheDir)
|
||||
{
|
||||
$this->cacheDir = $cacheDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getLessImportDirs(): array
|
||||
{
|
||||
return $this->lessImportDirs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $lessImportDirs
|
||||
*/
|
||||
public function setLessImportDirs(array $lessImportDirs)
|
||||
{
|
||||
$this->lessImportDirs = $lessImportDirs;
|
@@ -59,7 +59,7 @@ class LessCompiler extends RevisionCompiler
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @throws \Less_Exception_Parser
|
||||
*/
|
||||
protected function compile(array $sources): string
|
||||
{
|
||||
|
@@ -13,7 +13,7 @@ namespace Flarum\Frontend\Compiler;
|
||||
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
use Flarum\Frontend\Compiler\Source\SourceInterface;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
|
||||
class RevisionCompiler implements CompilerInterface
|
||||
{
|
||||
@@ -22,7 +22,7 @@ class RevisionCompiler implements CompilerInterface
|
||||
const EMPTY_REVISION = 'empty';
|
||||
|
||||
/**
|
||||
* @var FilesystemAdapter
|
||||
* @var Filesystem
|
||||
*/
|
||||
protected $assetsDir;
|
||||
|
||||
@@ -37,10 +37,10 @@ class RevisionCompiler implements CompilerInterface
|
||||
protected $sourcesCallbacks = [];
|
||||
|
||||
/**
|
||||
* @param FilesystemAdapter $assetsDir
|
||||
* @param Filesystem $assetsDir
|
||||
* @param string $filename
|
||||
*/
|
||||
public function __construct(FilesystemAdapter $assetsDir, string $filename)
|
||||
public function __construct(Filesystem $assetsDir, string $filename)
|
||||
{
|
||||
$this->assetsDir = $assetsDir;
|
||||
$this->filename = $filename;
|
||||
|
74
framework/core/src/Frontend/Content/Assets.php
Normal file
74
framework/core/src/Frontend/Content/Assets.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Content;
|
||||
|
||||
use Flarum\Foundation\Application;
|
||||
use Flarum\Frontend\Compiler\CompilerInterface;
|
||||
use Flarum\Frontend\Document;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class Assets
|
||||
{
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var \Flarum\Frontend\Assets
|
||||
*/
|
||||
protected $assets;
|
||||
|
||||
public function __construct(Application $app)
|
||||
{
|
||||
$this->app = $app;
|
||||
}
|
||||
|
||||
public function forFrontend(string $name)
|
||||
{
|
||||
$this->assets = $this->app->make('flarum.assets.'.$name);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __invoke(Document $document, Request $request)
|
||||
{
|
||||
$locale = $request->getAttribute('locale');
|
||||
|
||||
$compilers = [
|
||||
'js' => [$this->assets->makeJs(), $this->assets->makeLocaleJs($locale)],
|
||||
'css' => [$this->assets->makeCss(), $this->assets->makeLocaleCss($locale)]
|
||||
];
|
||||
|
||||
if ($this->app->inDebugMode()) {
|
||||
$this->commit(array_flatten($compilers));
|
||||
}
|
||||
|
||||
$document->js = array_merge($document->js, $this->getUrls($compilers['js']));
|
||||
$document->css = array_merge($document->css, $this->getUrls($compilers['css']));
|
||||
}
|
||||
|
||||
private function commit(array $compilers)
|
||||
{
|
||||
foreach ($compilers as $compiler) {
|
||||
$compiler->commit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CompilerInterface[] $compilers
|
||||
* @return string[]
|
||||
*/
|
||||
private function getUrls(array $compilers)
|
||||
{
|
||||
return array_filter(array_map(function (CompilerInterface $compiler) {
|
||||
return $compiler->getUrl();
|
||||
}, $compilers));
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Content;
|
||||
|
||||
use Flarum\Frontend\HtmlDocument;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
interface ContentInterface
|
||||
{
|
||||
/**
|
||||
* @param HtmlDocument $document
|
||||
* @param Request $request
|
||||
*/
|
||||
public function __invoke(HtmlDocument $document, Request $request);
|
||||
}
|
@@ -13,13 +13,13 @@ namespace Flarum\Frontend\Content;
|
||||
|
||||
use Flarum\Api\Client;
|
||||
use Flarum\Api\Controller\ShowUserController;
|
||||
use Flarum\Frontend\HtmlDocument;
|
||||
use Flarum\Frontend\Document;
|
||||
use Flarum\Locale\LocaleManager;
|
||||
use Flarum\User\User;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class CorePayload implements ContentInterface
|
||||
class CorePayload
|
||||
{
|
||||
/**
|
||||
* @var LocaleManager
|
||||
@@ -41,7 +41,7 @@ class CorePayload implements ContentInterface
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
public function __invoke(HtmlDocument $document, Request $request)
|
||||
public function __invoke(Document $document, Request $request)
|
||||
{
|
||||
$document->payload = array_merge(
|
||||
$document->payload,
|
||||
@@ -49,7 +49,7 @@ class CorePayload implements ContentInterface
|
||||
);
|
||||
}
|
||||
|
||||
private function buildPayload(HtmlDocument $document, Request $request)
|
||||
private function buildPayload(Document $document, Request $request)
|
||||
{
|
||||
$data = $this->getDataFromApiDocument($document->getForumApiDocument());
|
||||
|
||||
|
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend\Content;
|
||||
|
||||
use Flarum\Frontend\HtmlDocument;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class Layout implements ContentInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $layoutView;
|
||||
|
||||
/**
|
||||
* @param string $layoutView
|
||||
*/
|
||||
public function __construct(string $layoutView)
|
||||
{
|
||||
$this->layoutView = $layoutView;
|
||||
}
|
||||
|
||||
public function __invoke(HtmlDocument $document, Request $request)
|
||||
{
|
||||
$document->layoutView = $this->layoutView;
|
||||
}
|
||||
}
|
@@ -11,18 +11,18 @@
|
||||
|
||||
namespace Flarum\Frontend\Content;
|
||||
|
||||
use Flarum\Frontend\HtmlDocument;
|
||||
use Flarum\Frontend\Document;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class Meta implements ContentInterface
|
||||
class Meta
|
||||
{
|
||||
public function __invoke(HtmlDocument $document, Request $request)
|
||||
public function __invoke(Document $document, Request $request)
|
||||
{
|
||||
$document->meta = array_merge($document->meta, $this->buildMeta($document));
|
||||
$document->head = array_merge($document->head, $this->buildHead($document));
|
||||
}
|
||||
|
||||
private function buildMeta(HtmlDocument $document)
|
||||
private function buildMeta(Document $document)
|
||||
{
|
||||
$forumApiDocument = $document->getForumApiDocument();
|
||||
|
||||
@@ -35,7 +35,7 @@ class Meta implements ContentInterface
|
||||
return $meta;
|
||||
}
|
||||
|
||||
private function buildHead(HtmlDocument $document)
|
||||
private function buildHead(Document $document)
|
||||
{
|
||||
$head = [];
|
||||
|
||||
|
@@ -19,25 +19,19 @@ use Zend\Diactoros\Response\HtmlResponse;
|
||||
class Controller implements RequestHandlerInterface
|
||||
{
|
||||
/**
|
||||
* @var HtmlDocumentFactory
|
||||
* @var Frontend
|
||||
*/
|
||||
protected $document;
|
||||
protected $frontend;
|
||||
|
||||
/**
|
||||
* @param HtmlDocumentFactory $document
|
||||
*/
|
||||
public function __construct(HtmlDocumentFactory $document)
|
||||
public function __construct(Frontend $frontend)
|
||||
{
|
||||
$this->document = $document;
|
||||
$this->frontend = $frontend;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle(Request $request): Response
|
||||
{
|
||||
return new HtmlResponse(
|
||||
$this->document->make($request)->render()
|
||||
$this->frontend->document($request)->render()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ use Illuminate\Contracts\View\View;
|
||||
/**
|
||||
* A view which renders a HTML skeleton for Flarum's frontend app.
|
||||
*/
|
||||
class HtmlDocument implements Renderable
|
||||
class Document implements Renderable
|
||||
{
|
||||
/**
|
||||
* The title of the document, displayed in the <title> tag.
|
84
framework/core/src/Frontend/Frontend.php
Normal file
84
framework/core/src/Frontend/Frontend.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend;
|
||||
|
||||
use Flarum\Api\Client;
|
||||
use Flarum\Api\Controller\ShowForumController;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class Frontend
|
||||
{
|
||||
/**
|
||||
* @var Factory
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected $api;
|
||||
|
||||
/**
|
||||
* @var callable[]
|
||||
*/
|
||||
protected $content = [];
|
||||
|
||||
public function __construct(Factory $view, Client $api)
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->api = $api;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable $content
|
||||
*/
|
||||
public function content(callable $content)
|
||||
{
|
||||
$this->content[] = $content;
|
||||
}
|
||||
|
||||
public function document(Request $request): Document
|
||||
{
|
||||
$forumDocument = $this->getForumDocument($request);
|
||||
|
||||
$document = new Document($this->view, $forumDocument);
|
||||
|
||||
$this->populate($document, $request);
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
protected function populate(Document $document, Request $request)
|
||||
{
|
||||
foreach ($this->content as $content) {
|
||||
$content($document, $request);
|
||||
}
|
||||
}
|
||||
|
||||
private function getForumDocument(Request $request): array
|
||||
{
|
||||
$actor = $request->getAttribute('actor');
|
||||
|
||||
$this->api->setErrorHandler(null);
|
||||
|
||||
return $this->getResponseBody(
|
||||
$this->api->send(ShowForumController::class, $actor)
|
||||
);
|
||||
}
|
||||
|
||||
private function getResponseBody(Response $response): array
|
||||
{
|
||||
return json_decode($response->getBody(), true);
|
||||
}
|
||||
}
|
@@ -12,21 +12,18 @@
|
||||
namespace Flarum\Frontend;
|
||||
|
||||
use Flarum\Foundation\AbstractServiceProvider;
|
||||
use Flarum\Frontend\Compiler\Source\SourceCollector;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Illuminate\Contracts\View\Factory as ViewFactory;
|
||||
|
||||
class FrontendServiceProvider extends AbstractServiceProvider
|
||||
{
|
||||
public function register()
|
||||
{
|
||||
// Yo dawg, I heard you like factories, so I made you a factory to
|
||||
// create your factory. We expose a couple of factory functions that
|
||||
// will create frontend factories and configure them with some default
|
||||
// settings common to both the forum and admin frontends.
|
||||
|
||||
$this->app->singleton('flarum.frontend.assets.defaults', function () {
|
||||
$this->app->singleton('flarum.assets.factory', function () {
|
||||
return function (string $name) {
|
||||
$assets = new CompilerFactory(
|
||||
$assets = new Assets(
|
||||
$name,
|
||||
$this->app->make('filesystem')->disk('flarum-assets'),
|
||||
$this->app->storagePath()
|
||||
@@ -36,35 +33,26 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
||||
$this->app->basePath().'/vendor/components/font-awesome/less' => ''
|
||||
]);
|
||||
|
||||
$assets->add(function () use ($name) {
|
||||
$translations = $this->app->make(Asset\Translations::class);
|
||||
$translations->setFilter(function (string $id) use ($name) {
|
||||
return preg_match('/^.+(?:\.|::)(?:'.$name.'|lib)\./', $id);
|
||||
});
|
||||
|
||||
return [
|
||||
new Asset\CoreAssets($name),
|
||||
$this->app->make(Asset\LessVariables::class),
|
||||
$translations,
|
||||
$this->app->make(Asset\LocaleAssets::class)
|
||||
];
|
||||
});
|
||||
$assets->css([$this, 'addLessVariables']);
|
||||
$assets->localeCss([$this, 'addLessVariables']);
|
||||
|
||||
return $assets;
|
||||
};
|
||||
});
|
||||
|
||||
$this->app->singleton('flarum.frontend.view.defaults', function () {
|
||||
$this->app->singleton('flarum.frontend.factory', function () {
|
||||
return function (string $name) {
|
||||
$view = $this->app->make(HtmlDocumentFactory::class);
|
||||
$frontend = $this->app->make(Frontend::class);
|
||||
|
||||
$view->setCommitAssets($this->app->inDebugMode());
|
||||
$frontend->content(function (Document $document) use ($name) {
|
||||
$document->layoutView = 'flarum::frontend.'.$name;
|
||||
});
|
||||
|
||||
$view->add(new Content\Layout('flarum::frontend.'.$name));
|
||||
$view->add($this->app->make(Content\CorePayload::class));
|
||||
$view->add($this->app->make(Content\Meta::class));
|
||||
$frontend->content($this->app->make(Content\Assets::class)->forFrontend($name));
|
||||
$frontend->content($this->app->make(Content\CorePayload::class));
|
||||
$frontend->content($this->app->make(Content\Meta::class));
|
||||
|
||||
return $view;
|
||||
return $frontend;
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -81,4 +69,22 @@ class FrontendServiceProvider extends AbstractServiceProvider
|
||||
'url' => $this->app->make(UrlGenerator::class)
|
||||
]);
|
||||
}
|
||||
|
||||
public function addLessVariables(SourceCollector $sources)
|
||||
{
|
||||
$sources->addString(function () {
|
||||
$settings = $this->app->make(SettingsRepositoryInterface::class);
|
||||
|
||||
$vars = [
|
||||
'config-primary-color' => $settings->get('theme_primary_color', '#000'),
|
||||
'config-secondary-color' => $settings->get('theme_secondary_color', '#000'),
|
||||
'config-dark-mode' => $settings->get('theme_dark_mode') ? 'true' : 'false',
|
||||
'config-colored-header' => $settings->get('theme_colored_header') ? 'true' : 'false'
|
||||
];
|
||||
|
||||
return array_reduce(array_keys($vars), function ($string, $name) use ($vars) {
|
||||
return $string."@$name: {$vars[$name]};";
|
||||
}, '');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -1,182 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* (c) Toby Zerner <toby.zerner@gmail.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Frontend;
|
||||
|
||||
use Flarum\Api\Client;
|
||||
use Flarum\Api\Controller\ShowForumController;
|
||||
use Flarum\Frontend\Compiler\CompilerInterface;
|
||||
use Flarum\Frontend\Content\ContentInterface;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
|
||||
class HtmlDocumentFactory
|
||||
{
|
||||
/**
|
||||
* @var Factory
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected $api;
|
||||
|
||||
/**
|
||||
* @var CompilerFactory
|
||||
*/
|
||||
protected $assets;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $commitAssets;
|
||||
|
||||
/**
|
||||
* @var ContentInterface[]
|
||||
*/
|
||||
protected $content = [];
|
||||
|
||||
/**
|
||||
* @param Factory $view
|
||||
* @param Client $api
|
||||
* @param CompilerFactory|null $assets
|
||||
* @param bool $commitAssets
|
||||
*/
|
||||
public function __construct(Factory $view, Client $api, CompilerFactory $assets = null, bool $commitAssets = false)
|
||||
{
|
||||
$this->view = $view;
|
||||
$this->api = $api;
|
||||
$this->assets = $assets;
|
||||
$this->commitAssets = $commitAssets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ContentInterface|callable $content
|
||||
*/
|
||||
public function add($content)
|
||||
{
|
||||
$this->content[] = $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return HtmlDocument
|
||||
*/
|
||||
public function make(Request $request): HtmlDocument
|
||||
{
|
||||
$forumDocument = $this->getForumDocument($request);
|
||||
|
||||
$view = new HtmlDocument($this->view, $forumDocument);
|
||||
|
||||
$locale = $request->getAttribute('locale');
|
||||
|
||||
$js = [$this->assets->makeJs(), $this->assets->makeLocaleJs($locale)];
|
||||
$css = [$this->assets->makeCss(), $this->assets->makeLocaleCss($locale)];
|
||||
|
||||
$this->maybeCommitAssets(array_merge($js, $css));
|
||||
|
||||
$view->js = array_merge($view->js, $this->getUrls($js));
|
||||
$view->css = array_merge($view->css, $this->getUrls($css));
|
||||
|
||||
$this->populate($view, $request);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CompilerFactory
|
||||
*/
|
||||
public function getAssets(): CompilerFactory
|
||||
{
|
||||
return $this->assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CompilerFactory $assets
|
||||
*/
|
||||
public function setAssets(CompilerFactory $assets)
|
||||
{
|
||||
$this->assets = $assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param HtmlDocument $view
|
||||
* @param Request $request
|
||||
*/
|
||||
protected function populate(HtmlDocument $view, Request $request)
|
||||
{
|
||||
foreach ($this->content as $content) {
|
||||
$content($view, $request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
private function getForumDocument(Request $request): array
|
||||
{
|
||||
$actor = $request->getAttribute('actor');
|
||||
|
||||
$this->api->setErrorHandler(null);
|
||||
|
||||
return $this->getResponseBody(
|
||||
$this->api->send(ShowForumController::class, $actor)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Response $response
|
||||
* @return array
|
||||
*/
|
||||
private function getResponseBody(Response $response)
|
||||
{
|
||||
return json_decode($response->getBody(), true);
|
||||
}
|
||||
|
||||
private function maybeCommitAssets(array $compilers)
|
||||
{
|
||||
if ($this->commitAssets) {
|
||||
foreach ($compilers as $compiler) {
|
||||
$compiler->commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CompilerInterface[] $compilers
|
||||
* @return string[]
|
||||
*/
|
||||
private function getUrls(array $compilers)
|
||||
{
|
||||
return array_filter(array_map(function (CompilerInterface $compiler) {
|
||||
return $compiler->getUrl();
|
||||
}, $compilers));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getCommitAssets(): bool
|
||||
{
|
||||
return $this->commitAssets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $commitAssets
|
||||
*/
|
||||
public function setCommitAssets(bool $commitAssets)
|
||||
{
|
||||
$this->commitAssets = $commitAssets;
|
||||
}
|
||||
}
|
@@ -21,7 +21,7 @@ use Illuminate\Contracts\Events\Dispatcher;
|
||||
class RecompileFrontendAssets
|
||||
{
|
||||
/**
|
||||
* @var CompilerFactory
|
||||
* @var Assets
|
||||
*/
|
||||
protected $assets;
|
||||
|
||||
@@ -31,10 +31,10 @@ class RecompileFrontendAssets
|
||||
protected $locales;
|
||||
|
||||
/**
|
||||
* @param CompilerFactory $assets
|
||||
* @param Assets $assets
|
||||
* @param LocaleManager $locales
|
||||
*/
|
||||
public function __construct(CompilerFactory $assets, LocaleManager $locales)
|
||||
public function __construct(Assets $assets, LocaleManager $locales)
|
||||
{
|
||||
$this->assets = $assets;
|
||||
$this->locales = $locales;
|
||||
|
Reference in New Issue
Block a user