Targeting Flarum with extensions
What I'd like to explain is how you are able to interact with Flarum using extensions. To do so you'll need to understand some basic concepts.
Disclaimer, this article is written with the upcoming 0.1.0-beta.8 codebase in mind. As such code and namespace references might be off.
Frontends
First off let me introduce the concept of our frontends. They are called a frontend because they visibly interact with the visitor. The frontends are shown to the user as HTML, stylesheet and javascript. We see two types of frontends in Flarum:
- forum, the public side of your forum where users create discussions and posts.
- admin, the private side of your forum where, as an administrator of your forum, you configure your Flarum installation.
These two are pretty straightforward, right? Each of these is a separate frontend, although sharing some functionality they are mostly unique. They are a frontend because they visibly interact with the user.
These frontends are Single Page Applications or SPA for short. Let's not take a bath ? right now, but instead dive into what a SPA entails.
The fundamental principle of a SPA is that it does not rebuild the whole browser page while venturing into the depths of the website. Using javascript it instead loads only the resources (objects like users, discussions etc) it needs to serve the content you requested. One obvious benefit is that you will only request meta files, like javascript, stylesheets and html once for the whole session.
Backends
A SPA typically interacts with a backend, which allows us to retrieve resources (objects) used in the frontends. We're using a PHP based backend, it's based on several components of the Laravel framework.
Although Flarum is based on Laravel, it is not a Laravel app. Your extensions nevertheless can utilise a decent amount of functionality the Laravel framework has to offer!
Before I dive into the API backend too quick, let's first distinguish the backends first, these are;
- api, the json api providing resources to the Frontends continuously, even when browsing the forum or admin.
- web, the template based backend generating the HTML used when directly hitting a URL inside the forum or admin.
Api
The api backend which is providing the resources the Frontends need is in fact compliant to the json api specification. It's responding only with json. A good example of such a controller (which handles the request) is the Flarum\Api\Controller\ListDiscussionsController
which returns the list of discussions you see on your forum index page. Please note it does not generate the necessary HTML, only the information needed to generate that.
Web
The web backend is activated whenever you call on a page by directly entering it in your url bar. Eg, the discussions overview is calling the Flarum\Forum\Controller\IndexController
. It will respond with a (blade) view and has injected in this view the response json from the ListDiscussionController
mentioned in the previous section. So, instead of opening an HTML page and the api being queried, the web controller preloads this information and seeds it into our HTML.
Console
One last piece of the puzzle used in Flarum is the console. Although, currently, not extensively in use for other functionality than clearing cache and showing debug information (cache:clear
and info
) the console offers the ability to run scheduled, expensive or long tasks in the background.
I recommend looking at the Laravel console documentation and flagrow/console in case you're interested in learning more about this.
Extending
There are different ways to extend Flarum. We can make a distinction between Frontend and Backend.
They key to extending flarum is the bootstrap.php
file inside your extension directory. Whenever a (php) package is of type flarum-extension
Flarum will look at the vendor folder for the bootstrap file and load it. This allows Flarum to modify the Frontends and Backends with your changes.
Extending Frontends
In order to modify the frontend we need to add compiled javascript into the javascript compiler task and register an initializer to let Flarum know an extension needs to be booted on start up. Here's an example bootstrap.php
to register javascript for the admin Frontend:
<?php
return [
(new \Flarum\Extend\Assets('admin'))
->asset(__DIR__ . '/js/admin/dist/extension.js')
->bootstrapper('flagrow/bazaar/main')
];
Extending Backends
The backends are php driven and all core functionality fire events to which an extension can listen. Your bootstrap.php file is responsible for registering event listeners or directly listening on events. These events are identical to the events Laravel talks about.
Using the specific events we can target all our backends!
(should add some examples)
This document is work in progress, there might be some inconsistencies and future modifications.