Percorsi e contenuti
Una parte fondamentale dell'estensione di Flarum è l'aggiunta di percorsi, sia per esporre nuove risorse nell'API JSON, sia per aggiungere nuove pagine al frontend.
Il routing avviene sia sul backend PHP che sul frontend JavaScript.
Percorsi backend
Sul backend, Flarum ha tre raccolte di percorsi:
forum
Questi percorsi sono accessibili inyourforum.com/
. Includono percorsi che mostrano pagine nel frontend (comeyourforum.com/d/123-title
) e altri percorsi di utilità (come il percorso di reimpostazione della password).admin
Questi percorsi sono accessibili sottoyourforum.com/admin/
. Di default, c'è solo un percorsoadmin
nel backend; il resto del routing amministrativo avviene sul frontendapi
Questi percorsi sono accessibili sottoyourforum.com/api/
e compone le JSON:API di Flarum.
Definizione dei percorsi
Puoi aggiungere percorsi a una qualsiasi di queste raccolte utilizzando l'extender Routes
. Passa il nome della raccolta nel costruttore dell'extender, quindi chiama i suoi metodi per aggiungerle
Esistono metodi per registrare percorsi di qualsiasi metodo di richiesta HTTP: get
, post
, put
, patch
, e delete
. Tutti questi metodi accettano tre argomenti:
$path
Il percorso che utilizza sintassi FastRoute.$name
Un nome univoco per la rotta, utilizzato per generare URL. Per evitare conflitti con altre estensioni, è necessario utilizzare il nome di chi lo ha fornito.$handler
Il nome della classe controller che gestirà la richiesta. Quest'ultima verrà risolta tramite il contenitore.
<?php
use Flarum\Extend;
use Acme\HelloWorld\HelloWorldController;
return [
(new Extend\Routes('forum'))
->get('/hello-world', 'acme.hello-world', HelloWorldController::class)
];
I controller vengono risolti dal contenitore così puoi iniettarci all'interno le tue dipendenze.
$ flarum-cli make backend route
Controller
In Flarum, Controller è solo un altro nome per una classe che implementa RequestHandlerInterface. In parole povere, un controller deve implementare un metodo handle
che riceve una Richiesta e restituisce una Risposta. Flarum include laminas-diactoros che contiene implementazioni di Response
.
<?php
namespace Acme\HelloWorld;
use Laminas\Diactoros\Response\HtmlResponse;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface;
class HelloWorldController implements RequestHandlerInterface
{
public function handle(Request $request): Response
{
return new HtmlResponse('<h1>Hello, world!</h1>');
}
}
Controllers are resolved from the container so you can inject dependencies into their constructors.
Il metodo handle
di un Controller è il codice che viene eseguito quando qualcuno visita il tuo percorso (o invia dati ad esso tramite l'invio di un modulo). In generale, le implementazioni del controller seguono lo schema:
- Ricevere informazioni (GET params, POST data, l'utente corrente, ecc.) dall'oggetto Request.
- Fai qualcosa con quelle informazioni. Ad esempio, se il nostro controller gestisce un percorso per la creazione di post, vorremo salvare un nuovo post nel database.
- Restituisci una risposta. La maggior parte dei percorsi restituirà una pagina Web HTML o una risposta API JSON.
Parametri percorsi
A volte sarà necessario acquisire segmenti dell'URI all'interno di un percorso. Puoi farlo definendo i parametri del percorso usando sintassi FastRoute:
(new Extend\Routes('forum'))
->get('/user/{id}', 'acme.user', UserController::class)
Innanzitutto, dovrai indicare alla view factory dove può trovare i file di visualizzazione della tua estensione aggiungendo l'estender View
a extend.php
:
use Illuminate\Support\Arr;
$id = Arr::get($request->getQueryParams(), 'id');
Generare URL
È possibile generare URL per qualsiasi percorso definito utilizzando la classe Flarum\Http\UrlGenerator
. Iniettare una sua istanza nel controller o nella visualizzazione e richiamare il metodo to
per scegliere un percorso. Quindi, puoi generare un URL a un percorso utilizzando il nome che gli hai dato quando è stato definito. È possibile passare un array di parametri come secondo argomento. I parametri riempiranno i segmenti URI corrispondenti, altrimenti verranno aggiunti come parametri della query.
$url = $this->url->to('forum')->route('acme.user', ['id' => 123, 'foo' => 'bar']);
// http://iltuoforum.com/utente/123?foo=bar
Visualizzazioni
Puoi iniettare Visualizza di Laravel nel tuo controller. Ciò ti consentirà di eseguire il rendering di Blade template nella risposta del controller.
Innanzitutto, dovrai indicare al frontend dove può trovare i file di visualizzazione della tua estensione aggiungendo l'estender View
a extend.php
:
use Flarum\Extend;
use Illuminate\Contracts\View\Factory;
return [
(new Extend\View)
->namespace('acme.hello-world', __DIR__.'/views');
];
Quindi, inserisci la Factory nel tuo controller e rendenderizza tramite HtmlResponse
:
class HelloWorldController implements RequestHandlerInterface
{
protected $view;
public function __construct(Factory $view)
{
$this->view = $view;
}
public function handle(Request $request): Response
{
$view = $this->view->make('acme.hello-world::greeting');
return new HtmlResponse($view->render());
}
}
Controller API
Flarum\Api\Controller
contiene una serie di classi controller astratte che puoi estendere per implementare facilmente nuove risorse JSON-API. Vedere Utilizzo dei dati per info più dettagliate.
Percorsi Frontend
L'aggiunta di percorsi al frontend richiede in realtà di registrarl sia su frontend che backend. Questo perché quando il tuo percorso viene visitato, il backend deve avere informazioni per servire il frontend e il frontend analogamente deve sapere cosa visualizzare sulla pagina.
Sul backend, invece di aggiungere il tuo percorso frontend tramite Routes
, potresti utilizzare l'extender Frontend
con metodo route
. Questo presuppone sempre GET
come metodo, e accetta un percorso e un nome come primi due argomenti:
(new Extend\Frontend('forum'))
->route('/users', 'acme.users')
Ora quando tuoforum.com/utente
viene visitato, verrà visualizzato il frontend del forum. Tuttavia, poiché il frontend non conosce ancora la rotta users
, verrà visualizzato l'elenco di discussioni.
Flarum builds on Mithril's routing system, adding route names and an abstract class for pages (common/components/Page
).
To register the route on the frontend, there is a Routes
extender which works much like the backend one. Instead of a controller, however, you pass a component instance as the third argument:
import Extend from 'flarum/common/extenders';
export default [
new Extend.Routes()
.add('acme.users', '/users', <UsersPage />),
];
Remember to export the extend
module from your entry index.js
file:
export { default as extend } from './extend';
Now when yourforum.com/users
is visited, the forum frontend will be loaded and the UsersPage
component will be rendered in the content area. For more information on frontend pages, please see that documentation section.
Advanced use cases might also be interested in using route resolvers.
Parametri percorsi
Frontend routes also allow you to capture segments of the URI:
new Extend.Routes()
.add('acme.user', '/user/:id', <UsersPage />)
Route parameters will be passed into the attrs
of the route's component. They will also be available through m.route.param
Generare URL
To generate a URL to a route on the frontend, use the app.route
method. This accepts two arguments: the route name, and a hash of parameters. I parametri riempiranno i segmenti URI corrispondenti, altrimenti verranno aggiunti come parametri della query.
const url = app.route('acme.user', { id: 123, foo: 'bar' });
// http://yourforum.com/users/123?foo=bar
The extender also allows you to define a route helper method:
new Extend.Routes()
.add('acme.user', '/user/:id', <UsersPage />)
.helper('acmeUser', (user) => app.route('acme.user', { id: user.id() }))
This allows you to generate URLs to the route using the acmeUser
helper method:
const url = app.route.acmeUser(user);
// http://yourforum.com/users/123
Collegamenti ad altre pagine
A forum wouldn't be very useful if it only had one page. While you could, of course, implement links to other parts of your forum with HTML anchor tags and hardcoded links, this can be difficult to maintain, and defeats the purpose of Flarum being a Single Page Application in the first place.
Flarum uses Mithril's routing API to provide a Link
component that neatly wraps links to other internal pages. Its use is fairly simple:
import Link from 'flarum/common/components/Link';
// Link can be used just like any other component:
<Link href="/route/known/to/mithril">Hello World!</Link>
// You'll frequently use Link with generated routes:
<Link href={app.route('settings')}>Hello World!</Link>
// Link can even generate external links with the external attr:
<Link external={true} href="https://google.com">Hello World!</Link>
// The above example with external = true is equivalent to:
<a href="https://google.com">Hello World!</a>
// but is provided for flexibility: sometimes you might have links
// that are conditionally internal or external.
Contenuto
Whenever you visit a frontend route, the backend constructs a HTML document with the scaffolding necessary to boot up the frontend JavaScript application. You can easily modify this document to perform tasks like:
- Modificare il
<title>
della pagina - Aggiunta di risorse JavaScript e CSS esterne
- Aggiunta di contenuti SEO e tag
<meta>
- Aggiunta di dati al payload JavaScript (ad es. Per precaricare le risorse che verranno visualizzate immediatamente sulla pagina, evitando così una richiesta non necessaria all'API)
You can make blanket changes to the frontend using the Frontend
extender's content
method. This accepts a closure which receives two parameters: a Flarum\Frontend\Document
object which represents the HTML document that will be displayed, and the Request
object.
use Flarum\Frontend\Document;
use Psr\Http\Message\ServerRequestInterface as Request;
return [
(new Extend\Frontend('forum'))
->content(function (Document $document, Request $request) {
$document->head[] = '<script>alert("Hello, world!")</script>';
})
];
You can also add content onto your frontend route registrations:
return [
(new Extend\Frontend('forum'))
->route('/users', 'acme.users', function (Document $document, Request $request) {
$document->title = 'Users';
})
];