Skip to content

Commit

Permalink
Update for stable (#325)
Browse files Browse the repository at this point in the history
* Document `help` field in admin settings

* Document additional attrs in admin page settings

* Document some helpers and utils.

* Document convention with the container in register/bind methods

* Document that all lifecycle stubs should call super

* Document scheduled commands

* Document permission tag scopability

* Document magic permission model namespaces

Closes flarum/framework#2202

* Document testing `config` method

* Document assets:publish command

* Document filesystem extensibility

Closes #172

* Update i18n docs for stable. Complete the lang pack docs.

* 1.0 update guide

* Document extension assets

* Remove beta references

* Revert "Remove beta references"

This reverts commit e15ed85.

* Update docs/extend/filesystem.md

Co-authored-by: Sami Mazouz <[email protected]>

* Update docs/extend/i18n.md

Co-authored-by: Clark Winkelmann <[email protected]>

* Update docs/extend/i18n.md

Co-authored-by: Sami Mazouz <[email protected]>

* Update docs/extend/i18n.md

Co-authored-by: Sami Mazouz <[email protected]>

* Update docs/extend/permissions.md

Co-authored-by: Sami Mazouz <[email protected]>

* Update docs/extend/update-1.0.md

Co-authored-by: Sami Mazouz <[email protected]>

* Update docs/extend/update-1.0.md

Co-authored-by: Sami Mazouz <[email protected]>

* Update docs/extend/update-1.0.md

Co-authored-by: Sami Mazouz <[email protected]>

* Update docs/extend/i18n.md

Co-authored-by: Sami Mazouz <[email protected]>

* Update docs/extend/i18n.md

Co-authored-by: Sami Mazouz <[email protected]>

* Spacing fix

* DOn't assume local storage driver

* Adjust tag scoped comment

* Finish sentences (and sandwiches)

* Mention translations

* Fix octane link docs

* Clarify pluralization variable convention

Co-authored-by: Sami Mazouz <[email protected]>
Co-authored-by: Clark Winkelmann <[email protected]>
  • Loading branch information
3 people authored May 13, 2021
1 parent 8b0d37b commit aeca351
Show file tree
Hide file tree
Showing 14 changed files with 599 additions and 73 deletions.
3 changes: 3 additions & 0 deletions docs/.vuepress/config/locales/en/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
'frontend-pages',
'interactive-components',
'i18n',
'language-packs',
'forms',
'permissions',
'settings',
Expand All @@ -35,9 +36,11 @@ module.exports = {
collapsable: false,
children: [
'api-throttling',
'assets',
'console',
'extending-extensions',
'extensibility',
'filesystem',
'formatting',
'mail',
'middleware',
Expand Down
26 changes: 26 additions & 0 deletions docs/console.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ Gather information about Flarum's core and installed extensions. This is very us

Clears the backend flarum cache, including generated js/css, text formatter cache, and cached translations. This should be run after installing or removing extensions, and running this should be the first step when issues occur.

### assets:publish

`php flarum assets:publish`

Publish assets from core and extensions (e.g. compiled JS/CSS, bootstrap icons, logos, etc). This is useful if your assets have become corrupted, or if you have switched [filesystem drivers](extend/filesystem.md) for the `flarum-assets` disk.

### migrate

`php flarum migrate`
Expand All @@ -49,3 +55,23 @@ Runs all outstanding migrations. This should be used when an extension that modi
`php flarum migrate:reset --extension [extension_id]`

Reset all migrations for an extension. This is mostly used by extension developers, but on occasion, you might need to run this if you are removing an extension, and want to clear all of its data from the database. Please note that the extension in question must currently be installed (but not necessarily enabled) for this to work.

### schedule:run

`php flarum schedule:run`

Many extensions use scheduled jobs to run tasks on a regular interval. This could include database cleanups, posting scheduled drafts, generating sitemaps, etc. If any of your extensions use scheduled jobs, you should add a [cron job](https://ostechnix.com/a-beginners-guide-to-cron-jobs/) to run this command on a regular interval:

```
* * * * * cd /path-to-your-flarum-install && php flarum schedule:run >> /dev/null 2>&1
```

This command should generally not be run manually.

Note that some hosts do not allow you to edit cron configuration directly. In this case, you should consult your host for more information on how to schedule cron jobs.

### schedule:list

`php flarum schedule:list`

This command returns a list of scheduled commands (see `schedule:run` for more information). This is useful for confirming that commands provided by your extensions are registered properly. This **can not** check that cron jobs have been scheduled successfully, or are being run.
17 changes: 17 additions & 0 deletions docs/extend/admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ app.initializers.add('interstellar', function(app) {
{
setting: 'acme-interstellar.coordinates', // This is the key the settings will be saved under in the settings table in the database.
label: app.translator.trans('acme-interstellar.admin.coordinates_label'), // The label to be shown letting the admin know what the setting does.
help: app.translator.trans('acme-interstellar.admin.coordinates_help'), // Optional help text where a longer explanation of the setting can go.
type: 'boolean', // What type of setting this is, valid options are: boolean, text (or any other <input> tag type), and select.
},
30 // Optional: Priority
Expand All @@ -75,6 +76,17 @@ If you use `type: 'select'` the setting object looks a little bit different:
}
```

Also, note that additional items in the setting object will be used as component attrs. This can be used for placeholders, min/max restrictions, etc:

```js
{
setting: 'acme-interstellar.crew_count',
label: app.translator.trans('acme-interstellar.admin.crew_count_label'),
type: 'number',
min: 1,
max: 10
}
```

If you want to add something to the settings like some extra text or a more complicated input, you can also pass a callback as the first argument that returns JSX. This callback will be executed in the context of [`ExtensionPage`](https://api.docs.flarum.org/js/master/class/src/admin/components/extensionpage.js~extensionpage) and setting values will not be automatically serialized.

Expand Down Expand Up @@ -124,13 +136,18 @@ app.initializers.add('interstellar', function(app) {
icon: 'fas fa-rocket', // Font-Awesome Icon
label: app.translator.trans('acme-interstellar.admin.permissions.fly_rockets_label'), // Permission Label
permission: 'discussion.rocket_fly', // Actual permission name stored in database (and used when checking permission).
tagScoped: true, // Whether it be possible to apply this permission on tags, not just globally. Explained in the next paragraph.
},
'start', // Category permission will be added to on the grid
95 // Optional: Priority
);
});
```

If your extension interacts with the [tags extension](https://github.com/flarum/tags) (which is fairly common), you might want a permission to be tag scopable (i.e. applied on the tag level, not just globally). You can do this by including a `tagScoped` attribute, as seen above. Permissions starting with `discussion.` will automatically be tag scoped unless `tagScoped: false` is indicated.

To learn more about Flarum permissions, see [the relevant docs](permissions.md).

### Chaining Reminder

Remember these functions can all be chained like:
Expand Down
8 changes: 8 additions & 0 deletions docs/extend/assets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Extension Assets

Some extensions might want to include assets like images or JSON files in their source code (note that this is not the same as uploads, which would probably require a [filesystem disk](filesystem.md)).

This is actually very easy to do. Just create an `assets` folder at the root of your extension, and place any asset files there.
Flarum will then automatically copy those files to its own `assets` directory (or other storage location if [one is offered by extensions](filesystem.md)) every time the extension is enabled or [`php flarum assets:publish`](../console.md) is executed.

If using the default storage driver, assets will be available at `https://FORUM_URL/assets/extensions/EXTENSION_ID/file.path`. However, since other extensions might use remote filesystems, we recommend serializing the url to assets you need in the backend. See [Flarum's serialization of the logo and favicon URLs](https://github.com/flarum/core/blob/bba6485effc088e38e9ae0bc8f25528ecbee3a7b/src/Api/Serializer/ForumSerializer.php#L85-L86) for an example.
21 changes: 18 additions & 3 deletions docs/extend/console.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,23 @@ return [
];
```

::: tip Scheduled Commands
## Scheduled Commands

The [fof/console library](https://github.com/FriendsOfFlarum/console) allows you to schedule commands to run on a regular interval! However, please note that this is a community solution.
The `Flarum\Extend\Console`'s `schedule` method allows extension developers to create scheduled commands that run on an interval:

:::

```php
use Flarum\Extend;
use YourNamespace\Console\CustomCommand;
use Illuminate\Console\Scheduling\Event;

return [
// Other extenders
(new Extend\Console())->schedule('cache:clear', function (Event $event) {
$event->everyMinute();
}, ['Arg1', '--option1', '--option2']),
// Other extenders
];
```

In the callback provided as the second argument, you can call methods on the [$event object](https://laravel.com/api/8.x/Illuminate/Console/Scheduling/Event.html) to schedule on a variety of frequencies (or apply other options, such as only running on one server). See the [Laravel documentation](https://laravel.com/docs/8.x/scheduling#scheduling-artisan-commands) for more information.
132 changes: 132 additions & 0 deletions docs/extend/filesystem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Filesystem

Flarum core integrates with the filesystem to store and serve assets (like compiled JS/CSS or upload logos/favicons) and avatars.

Extensions can use Flarum's provided utils for their own filesystem interaction and file storage needs. This system is based around [Laravel's filesystem tools](https://laravel.com/docs/8.x/filesystem), which are in turn based on the [Flysystem library](https://github.com/thephpleague/flysystem).

## Disks

Filesystem **disks** represent storage locations, and are backed by storage drivers, which we'll cover later.
Flarum core has 2 disks: `flarum-assets` and `flarum-avatars`.

### Using existing disks

To access a disk, you'll need to retrieve it from the [Filesystem Factory](https://laravel.com/api/8.x/Illuminate/Contracts/Filesystem/Factory.html).
To do so, you should inject the factory contract in your class, and access the disks you need.

Let's take a look at core's [`DeleteLogoController`](https://github.com/flarum/core/blob/bba6485effc088e38e9ae0bc8f25528ecbee3a7b/src/Api/Controller/DeleteLogoController.php#L19-L59) for an example:

```php
<?php

/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/

namespace Flarum\Api\Controller;

use Flarum\Http\RequestUtil;
use Flarum\Settings\SettingsRepositoryInterface;
use Illuminate\Contracts\Filesystem\Factory;
use Illuminate\Contracts\Filesystem\Filesystem;
use Laminas\Diactoros\Response\EmptyResponse;
use Psr\Http\Message\ServerRequestInterface;

class DeleteLogoController extends AbstractDeleteController
{
/**
* @var SettingsRepositoryInterface
*/
protected $settings;

/**
* @var Filesystem
*/
protected $uploadDir;

/**
* @param SettingsRepositoryInterface $settings
* @param Factory $filesystemFactory
*/
public function __construct(SettingsRepositoryInterface $settings, Factory $filesystemFactory)
{
$this->settings = $settings;
$this->uploadDir = $filesystemFactory->disk('flarum-assets');
}

/**
* {@inheritdoc}
*/
protected function delete(ServerRequestInterface $request)
{
RequestUtil::getActor($request)->assertAdmin();

$path = $this->settings->get('logo_path');

$this->settings->set('logo_path', null);

if ($this->uploadDir->exists($path)) {
$this->uploadDir->delete($path);
}

return new EmptyResponse(204);
}
}
```

The object returned by `$filesystemFactory->disk(DISK_NAME)` implements the [Illuminate\Contracts\Filesystem\Cloud](https://laravel.com/api/8.x/Illuminate/Contracts/Filesystem/Cloud.html) interface, and can be used to create/get/move/delete files, and to get the URL to a resource.

### Declaring new disks

Some extensions will want to group their resources / uploads onto a custom disk as opposed to using `flarum-assets` or `flarum-avatars`.

This can be done via the `Filesystem` extender:

```php
use Flarum\Extend;

return [
(new Extend\Filesystem)
->disk('flarum-uploads', function (Paths $paths, UrlGenerator $url) {
return [
'root' => "$paths->public/assets/uploads",
'url' => $url->to('forum')->path('assets/uploads')
];
});
```

Since all disks use the local filesystem by default, you'll need to provide a base path and base URL for the local filesystem.

The config array can contain other entries supported by [Laravel disk config arrays](https://laravel.com/docs/8.x/filesystem#configuration). The `driver` key should not be provided, and will be ignored.

## Storage drivers

Flarum selects the active driver for each disk by checking the `disk_driver.DISK_NAME` key in the [settings repository](settings.md) and [config.php file](../config.md). If no driver is configured, or the configured driver is unavailable, Flarum will default to the `local` driver.

You can define new storage drivers by implementing the [`Flarum\Filesystem\DriverInterface` interface](https://github.com/flarum/core/blob/bba6485effc088e38e9ae0bc8f25528ecbee3a7b/src/Filesystem/DriverInterface.php#L16-L16), and registering it via the `Filesystem` extender:

```php
use Flarum\Extend;

return [
(new Extend\Filesystem)
->driver('aws-with-cdn', AwsWithCdnDriver::class);
```

Filesystem storage drivers are a very powerful tool that allows you to completely customize file storage locations, attach arbitrary CDNs, and otherwise extend the filesystem / cloud storage integration layer.

::: danger

Some drivers might try to index their filesystem every time the driver is instantiated, even if only the `url` method is needed. This can have serious performance implications. In most cases, you'll want to ensure that your driver's `url` method does not ping the remote filesystem. Similarly, the remote filesystem should usually not be accessed until operations are actually executed.

:::

## GUI and Admin Configuration

Flarum does not currently provide a GUI for selecting drivers for disks, or for entering settings for drivers. This might be added in the future.
For now, extensions are responsible for providing a GUI for their disks and drivers.

As noted [above](#storage-drivers), if your extension provides a GUI for selecting drivers for a disk, it should modify the `disk_driver.DISK_NAME` key in settings.
15 changes: 13 additions & 2 deletions docs/extend/frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ You should familiarize yourself with [Mithril's component API](https://mithril.j
* `CustomComponentClass.component(attrs, children)`
* `<CustomComponentClass {...attrs}>{children}</CustomComponentClass>`

However, component classes extending `Component` must call `super` when using the `oninit`, `oncreate`, and `onbeforeupdate` methods.
However, component classes extending `Component` must call `super` when using the lifecycle methods (`oninit`, `oncreate`, `onbeforeupdate`, `onupdate`, `onbeforeremove`, and `onremove`).

To use Flarum components, simply extend `flarum/common/Component` in your custom component class.

Expand Down Expand Up @@ -385,4 +385,15 @@ Some potential "advanced" uses include:

### Flarum Utils

Flarum defines (and provides) quite a few util and helper functions, which you may want to use in your extensions. The best way to learn about them is through [the source code](https://github.com/flarum/core/tree/master/js) or [our javascript API documentation](https://api.docs.flarum.org/js/).
Flarum defines (and provides) quite a few util and helper functions, which you may want to use in your extensions. A few particularly useful ones:

- `flarum/common/utils/Stream` provides [Mithril Streams](https://mithril.js.org/stream.html), and is useful in [forms](forms.md).
- `flarum/common/utils/classList` provides the [clsx library](https://www.npmjs.com/package/clsx), which is great for dynamically assembling a list of CSS classes for your components
- `flarum/common/utils/extractText` extracts text as a string from Mithril component vnode instances (or translation vnodes).
- `flarum/common/utils/throttleDebounce` provides the [throttle-debounce](https://www.npmjs.com/package/throttle-debounce) library
- `flarum/common/helpers/avatar` displays a user's avatar
- `flarum/common/helpers/highlight` highlights text in strings: great for search results!
- `flarum/common/helpers/icon` displays an icon, usually used for FontAwesome.
- `flarum/common/helpers/username` shows a user's display name, or "deleted" text if the user has been deleted.

And there's a bunch more! Some are covered elsewhere in the docs, but the best way to learn about them is through [the source code](https://github.com/flarum/core/tree/master/js) or [our javascript API documentation](https://api.docs.flarum.org/js/).
Loading

0 comments on commit aeca351

Please sign in to comment.