Rework extension bootstrapping

System JS modules don't execute when they're registered, so we need to
import them explicitly. While we're at it, we may as well make the
locale bootstrapper a module too.
This commit is contained in:
Toby Zerner 2015-07-20 18:08:28 +09:30
parent 19fe138770
commit 6b7cf1b6bf
12 changed files with 130 additions and 59 deletions

View File

@ -30,7 +30,6 @@ gulp({
'src/**/*.js',
'../lib/**/*.js'
],
bootstrapFiles: [],
modulePrefix: 'flarum',
externalHelpers: true,
outputFile: 'dist/app.js'

View File

@ -2,23 +2,24 @@
use Flarum\Support\ClientAction;
use Flarum\Support\ClientView;
use Flarum\Forum\Actions\ClientAction as ForumClientAction;
class BuildClientView
{
/**
* @var ClientAction
*/
protected $action;
public $action;
/**
* @var ClientView
*/
protected $view;
public $view;
/**
* @var array
*/
protected $keys;
public $keys;
/**
* @param ClientAction $action
@ -31,4 +32,26 @@ class BuildClientView
$this->view = $view;
$this->keys = &$keys;
}
}
public function forumAssets($files)
{
if ($this->action instanceof ForumClientAction) {
$this->view->getAssets()->addFiles((array) $files);
}
}
public function forumBootstrapper($bootstrapper)
{
if ($this->action instanceof ForumClientAction) {
$this->view->addBootstrapper($bootstrapper);
}
}
public function forumTranslations(array $keys)
{
if ($this->action instanceof ForumClientAction) {
foreach ($keys as $key) {
$this->keys[] = $key;
}
}
}}

View File

@ -16,4 +16,9 @@ class RegisterLocales
{
$this->manager = $manager;
}
public function addTranslations($locale, $file)
{
$this->manager->addTranslations($locale, $file);
}
}

View File

@ -13,14 +13,18 @@ class JsCompiler extends RevisionCompiler
public function compile()
{
$output = "var initLocale = function(app) {
app.translator.translations = ".json_encode($this->translations).";";
$output = "System.register('locale', [], function() {
return {
execute: function() {
app.translator.translations = ".json_encode($this->translations).";\n";
foreach ($this->files as $filename) {
$output .= file_get_contents($filename);
}
$output .= "};";
$output .= "}
};
});";
return $output;
}

View File

@ -47,6 +47,13 @@ class ClientView implements Renderable
*/
protected $layout;
/**
* An array of JS modules to import before booting the app.
*
* @var array
*/
protected $bootstrappers = ['locale'];
/**
* An array of strings to append to the page's <head>.
*
@ -156,6 +163,16 @@ class ClientView implements Renderable
$this->footStrings[] = $string;
}
/**
* Add a JavaScript module to be imported before the app is booted.
*
* @param string $string
*/
public function addBootstrapper($string)
{
$this->bootstrappers[] = $string;
}
/**
* Get the view's asset manager.
*
@ -196,6 +213,7 @@ class ClientView implements Renderable
$view->head = implode("\n", $this->headStrings);
$view->foot = implode("\n", $this->footStrings);
$view->bootstrappers = $this->bootstrappers;
return $view->render();
}

View File

@ -4,6 +4,7 @@
// classes in the src directory to be autoloaded.
require __DIR__.'/vendor/autoload.php';
// Register our service provider with the Flarum application. In here we can
// register bindings and execute code when the application boots.
return $this->app->register('{{namespace}}\{{classPrefix}}ServiceProvider');
// Return the name of our Extension class. Flarum will register it as a service
// provider, allowing it to register bindings and execute code when the
// application boots.
return '{{namespace}}\Extension';

View File

@ -1,8 +0,0 @@
import { extend, override } from 'flarum/extension-utils';
import app from 'flarum/app';
app.initializers.add('{{name}}', function() {
// @todo
});

View File

@ -0,0 +1,4 @@
import { extend } from 'flarum/extend';
import app from 'flarum/app';
// TODO

View File

@ -0,0 +1,27 @@
<?php namespace {{namespace}};
use Flarum\Support\Extension;
use Illuminate\Events\Dispatcher;
class Extension extends BaseExtension
{
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot(Dispatcher $events)
{
$events->subscribe('{{namespace}}\Listeners\AddClientAssets');
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}

View File

@ -0,0 +1,33 @@
<?php namespace {{namespace}}\Listeners;
use Flarum\Events\RegisterLocales;
use Flarum\Events\BuildClientView;
use Illuminate\Contracts\Events\Dispatcher;
class AddClientAssets
{
public function subscribe(Dispatcher $events)
{
$events->listen(RegisterLocales::class, __CLASS__.'@addLocale');
$events->listen(BuildClientView::class, __CLASS__.'@addAssets');
}
public function addLocale(RegisterLocales $event)
{
$event->addTranslations('en', __DIR__.'/../../locale/en.yml');
}
public function addAssets(BuildClientView $event)
{
$event->forumAssets([
__DIR__.'/../../js/dist/extension.js',
__DIR__.'/../../less/extension.less'
]);
$event->forumBootstrapper('{{name}}/main');
$event->forumTranslations([
// '{{name}}.hello_world'
]);
}
}

View File

@ -1,39 +0,0 @@
<?php namespace {{namespace}};
use Flarum\Support\ServiceProvider;
use Flarum\Extend;
class {{classPrefix}}ServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$this->extend([
(new Extend\Locale('en'))->translations(__DIR__.'/../locale/en.yml'),
(new Extend\ForumClient())
->assets([
__DIR__.'/../js/dist/extension.js',
__DIR__.'/../less/extension.less'
])
->translations([
// Add the keys of translations you would like to be available
// for use by the JS client application.
])
]);
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}

View File

@ -35,7 +35,11 @@
document: {!! json_encode($document) !!},
session: {!! json_encode($session) !!}
};
initLocale(app);
@foreach ($bootstrappers as $bootstrapper)
System.import('{{ $bootstrapper }}');
@endforeach
app.boot();
} catch (e) {
document.write('<div class="container">Something went wrong.</div>');