Updating For 1.0
Flarum versione 1.0 è l'attesissima release stabile! Questa versione porta una serie di refactor, pulizia e piccoli miglioramenti che dovrebbero rendere la vostra esperienza su Flarum migliore!
Se hai bisogno di aiuto per alcune modifiche o utilizzare le nuove funzionalità, si prega di avviare una discussione sul forum della community o nella chat Discord.
Full Stack
Traduzioni e transChoice
Retroscena
Storicamente, Flarum ha usato Symfony per le traduzioni del backend, ed anche nel frontend per mantenere il formato coerente. Ci sono tuttavia alcuni limiti a questo approccio:
- Gli sviluppatori devono decidere se utilizzare
transotransChoiceper la pluralizzazione - Il formato di pluralizzazione è proprietario di Symfony
- E dobbiamo mantenerlo in autonomia
- Le chiavi per i valori forniti per le traduzioni del backend devono essere avvolte in parentesi graffe. (e.g.
$this->translator->trans('some.translation', ['{username}' => 'Some Username!'])). - Non c'è supporto per applicazioni complesse (pluralizzazione nidificata, selezione non basata su numero)
- Come risultato del punto precedente, la genderizzazione è impossibile. E questo è importante per molte lingue.
Nuovo sistema
In v5, Symfony ha abbandonato il suo sistema proprietario transChoice a favore dello standard ICU MessageFormat. Questo risolve praticamente ogni singolo problema sopra menzionato. In questa versione, Flarum passerà completamente a ICU MessageFormat. Cosa significa questo per le estensioni?
transChoicenon dovrebbe essere usato affatto; invece, la variabile passata per la pluralizzazione dovrebbe essere inclusa nei dati.- Le chiavi per le traduzioni del backend non hanno più bisogno di essere circondate da parentesi graffe.
- Le traduzioni possono ora utilizzare le sintassi
selecteplural. Perplural, sono supportati il parametrooffsete le variabili#. - Queste sintassi
selectepluralpossono essere annidate. Questa è spesso una cattiva idea anche se (oltre, ad esempio, 2 livelli), in quanto le cose possono diventare inutilmente complesse.
Non è necessario alcun cambiamento nella denominazione del file di traduzione (Symfony docs dice che è necessario un suffisso +intl-icu, ma Flarum interpreterà tutti i file di traduzione come internazionalizzati).
Cambiamenti Futuri
In futuro ciò servirà da base per ulteriori caratteristiche:
- I preprocessori consentiranno alle estensioni di modificare gli argomenti passati alle traduzioni. Questo abiliterà la genderizzazione (le estensioni potrebbero estrarre automaticamente un campo di genere da qualsiasi oggetto di tipo "utente" passato).
- We could support internationalized "magic variables" for numbers: currently,
oneis supported, but others (few,many, etc) currently aren't. - We could support ordinal formatting in additional to just plural formatting.
Changes Needed in Extensions
The transChoice methods in the frontend and backend have been removed. The trans method should always be used for translating, regardless of pluralization. If a translation requires pluralization, make sure you pass in the controlling variable as one of the arguments.
In the frontend, code that looked like this:
app.translator.transChoice('some-translation', guestCount, {host: hostName});
should be changed to:
// This uses ES6 key-property shorthand notation. {guestCount: guestCount} is equivalent to {guestCount}
app.translator.trans('some-translation', {host: hostName, guestCount });
Similarly, in the backend,
$translator->transChoice('some-translation', $guestCount, ['{host}' => $hostName]);
should be changed to:
$translator->trans('some-translation', ['host' => $hostName, 'guestCount' => $guestCount]);
Note that in the backend, translation keys were previously wrapped in curly braces. This is no longer needed.
Changes Needed in Translations
Translations that aren't using pluralization don't need any changes.
Pluralized translations should be changed as follows:
For {count} minute|For {count} minutes
to
{count, plural, one {For # minute} other {For # minutes}}
Note that in this example, count is the variable that controls pluralization. If a different variable were used (such as guestCount in the example above), this would look like:
{guestCount, plural, one {For # minute} other {For # minutes}}
See our i18n docs for more information.
Permissions Changes
For a long time, the viewDiscussions and viewUserList permissions have been confusing. Despite their names:
viewDiscussionscontrols viewing both discussions and users.viewUserListcontrols searching users, not viewing user profiles.
To clear this up, in v1.0, these permissions have been renamed to viewForum and searchUsers respectively. A migration in core will automatically adjust all permissions in the database to use the new naming. However, any extension code using the old name must switch to the new ones immediately to avoid security issues. To help the transfer, a warning will be thrown if the old permissions are referenced.
We have also slightly improved tag scoping for permissions. Currently, permissions can be applied to tags if:
- The permission is
viewForum - The permission is
startDiscussion - The permission starts with
discussion.
However, this doesn't work for namespaced permissions (flarum-acme.discussion.bookmark), or permissions that don't really have anything to do with discussions, but should still be scoped (e.g. viewTag). To counter this, a tagScoped attribute can be used on the object passed to registerPermission to explicitly indicate whether the permission should be tag scopable. If this attribute is not provided, the current rules will be used to determine whether the permission should be tag scopable.
Frontend
Tooltip Changes
The flarum/common/components/Tooltip component has been introduced as a simpler and less framework-dependent way to add tooltips. If your code is creating tooltips directly (e.g. via $.tooltip() in oncreate methods), you should wrap your components in the Tooltip component instead. Per esempio:
<Tooltip text="You wish!">
<button>
Click for free money!
</button>
</Tooltip>
See the source code for more examples and instructions.
See the PR for examples of how to change existing code to use tooltips.
PaginatedListState
The flarum/common/states/PaginatedListState state class has been introduced to abstract away most of the logic of DiscussionListState and NotificationListState. It provides support for loading and displaying paginated lists of JSON:API resources (usually models). In future releases, we will also provide an PaginatedList (or InfiniteScroll) component that can be used as a base class for these paginated lists.
Please see the source code for a list of methods.
Note that flarum/forum/states/DiscussionListState's empty and hasDiscussions methods have been removed, and replaced with isEmpty and hasItems respectively. Questo è un cambiamento decisivo.
New Loading Spinner
The old spin.js based loading indicator has been replaced with a CSS-based solution. For the most part, no changes should be needed in extensions, but in some cases, you might need to update your spinner. This change also makes it easier to customize the spinner.
See this discussion for more information.
classList util
Ever wrote messy code trying to put together a list of classes for some component? Well, no longer! The clsx library is now available as the flarum/common/utils/classList util.
User List
An extensible user list has been added to the admin dashboard. In future releases, we hope to extract a generic model table component that can be used to list any model in the admin dashboard.
See the source code for a list of methods to extend, and examples of how columns should look like (can be added by extending the columns method and adding items to the ItemList).
Varie
- Components should now call
superfor ALL Mithril lifecycle methods they define. Before, this was only needed foroninit,onbeforeupdate, andoncreate. Now, it is also needed inonupdate,onbeforeremove, andonremove. See this GitHub issue for information on why this change was made. - The
flarum/common/utils/insertTextandflarum/common/utils/styleSelectedTextutils have been moved to core fromflarum/markdown. Seeflarum/markdownfor an example of usage. - The
extendandoverrideutils can now modify several methods at once by passing in an array of method names instead of a single method name string as the second argument. This is useful for extending theoncreateandonupdatemethods at once. - The
EditUserModalcomponent is no longer available through theflarum/forumnamespace, it has been moved toflarum/common. Imports should be adjusted. - The
ModelandRouteJS extenders have been removed for now. There aren't currently used in any extensions that we know of. We will be reintroducing JS extenders during v1.x releases. - The
Searchcomponent can now be used with theSearchStatestate class. Previously,SearchStatewas missing thegetInitialSearchmethod expected by theSearchcomponent.
Backend
Filesystem Extenders
In this release, we refactored our use of the filesystem to more consistently use Laravel's filesystem API. Extensions can now declare new disks, more easily use core's flarum-assets and flarum-avatars disks, and create their own storage drivers, enabling CDN and cloud storage support.
Compat and Closure Extenders
In early Flarum versions, the extend.php file allowed arbitrary functions that allowed execution of arbitrary code one extension boot. Per esempio:
return [
// other extenders
function (Dispatcher $events) {
$events->subscribe(Listener\FilterDiscussionListByTags::class);
$events->subscribe(Listener\FilterPostsQueryByTag::class);
$events->subscribe(Listener\UpdateTagMetadata::class);
}
];
This approach was difficult to maintain and provide a well-tested public API for, frequently resolved classes early (breaking all sorts of things), and was not very descriptive. With the extender API completed in beta 16, this approach is no longer necessary. Support for these closures has been removed in this stable version.
One type of functionality for which the extender replacement isn't obvious is container bindings (e.g. flarum/pusher). This can be done with via the service provider extender (e.g. a newer version of flarum/pusher).
If you are unsure about which extenders should be used to replace your use of callbacks in extend.php, or are not sure that such an extender exists, please comment so below or reach out! We're in the final stages of finishing up the extender API, so now is the time to comment.
Scheduled Commands
The fof/console library has been a popular way to schedule commands (e.g. for publishing scheduled posts, running DB-heavy operations, etc) for several release. In Flarum 1.0, this functionality has been brought into core's Console extender. See our console extension documentation for more information on how to create schedule commands, and our console user documentation for more information on how to run scheduled commands.
Eager Loading Extender
As part of solving N+1 Query issues in some Flarum API endpoints, we have introduced a load method on the ApiController extender that allows you to indicate relations that should be eager loaded.
This should be done if you know a relation will always be included, or will always be referenced by controller / permission logic. For example, we will always need the tags of a discussion to check what permissions a user has on that discussion, so we should eager load the discussion's tags relationship. Per esempio:
return [
// other extenders
(new Extend\ApiController(FlarumController\ListDiscussionsController::class))
->addInclude(['tags', 'tags.state', 'tags.parent'])
->load('tags'),
];
RequestUtil
The Flarum\Http\RequestUtil's getActor and withActor should be used for getting/setting the actor (user) on requests. $request->getAttribute('actor') and $request->withAttribute('actor') are deprecated, and will be removed in v2.0.
Varie
- The
Formatterextender now has anunparsemethod that allows modifying XML before unparsing content. - All route names must now be unique. In beta 16, uniqueness was enforced per-method; now, it is mandatory for all routes.
- API requests sent through
Flarum\Api\Clientnow run through middleware, includingThrottleApi. This means that it is now possible to throttle login/registration calls. - In beta 16, registering custom searchers was broken. It has been fixed in stable.
- The
post_likestable in the flarum/likes extension now logs the timestamp when likes were created. This isn't used in the extension, but could be used in other extensions for analytics. - The
helpattribute of admin settings no longer disappears on click. - The
generate:migrationconsole command has been removed. The Flarum CLI should be used instead. - The
GambitManagerutil class is now considered internal API, and should not be used directly by extensions. - The
sessionattribute is no longer available on theUserclass. This caused issues with queue drivers, and was not conceptually correct (a user can have multiple sessions). The current session is still available via the$requestinstance. - The
app,base_path,public_path,storage_path, andeventglobal helpers have been restored, but deprecated perpetually. These exist in case Laravel packages need them; they should not be used directly by Flarum extension code. Theflarum/laravel-helperspackage has been abandoned. - The following deprecated features from beta 16 have been removed:
- The
TextEditor,TextEditorButton, andSuperTextareacomponents are no longer exported through theflarum/forumnamespace, but throughflarum/common(with the exception ofSuperTextarea, which has been replaced withflarum/common/utils/BasicEditorDriver). - Support for
Symfony\Component\Translation\TranslatorInterfacehas been removed,Symfony\Contracts\Translation\TranslatorInterfaceshould be used instead. - All backwards compatibility layers for the beta 16 access token refactors have been removed
- The
GetModelIsPrivateevent has been removed. TheModelPrivateextender should be used instead. - The
Searching(for bothUserandDiscussionmodels),ConfigureAbstractGambits,ConfigureDiscussionGambits, andConfigureUserGambitsevents have been removed. TheSimpleFlarumSearchextender should be used instead. - The
ConfigurePostsQueryevent has been removed. TheFilterextender should be used instead. - The
ApiSerializerextender'smutatemethod has been removed. The same class'sattributesmethod should be used instead. - The
SearchCriteriaandSearchResultsutil classes have been removed.Flarum\Query\QueryCriteriaandFlarum\Query\QueryResultsshould be used instead. - The
patternproperty ofAbstractRegexGambithas been removed; thegetGambitPatternmethod is now a required abstract method. - The
AbstractSearchutil class has been removed.Flarum\Search\SearchStateandFlarum\Filter\FilterStateshould be used instead. - The
CheckingPasswordevent has been removed, theAuthextender should be used instead.
- The
Tags Extension Changes
As mentioned above, tag scopable permissions can now be explicitly declared.
We've also made several big refactors to significantly improve tags performance.
Firstly, the Tag model's static getIdsWhereCan and getIdsWhereCannot methods have been removed. These methods scaled horribly on forums with many tags, sometimes adding several seconds to response time.
These methods have been replaced with a whereHasPermission Eloquent dynamic scope that returns a query. Per esempio:
Tag::whereHasPermission($actor, 'viewDiscussions).
That query can then be used in other DB queries, or further constricted to retrieve individual tags.
Secondly, we no longer load in all tags as part of the initial payload. The initial payload contains all top-level primary tags, and the top 3 secondary tags. Other tags are loaded in as needed. Future releases will paginate secondary tags. This should enable forums to have thousands of secondary tags without significant performance impacts. These changes mean that extensions should not assume that all tags are available in the model store.
Testing Library Changes
- Bundled extensions will not be automatically enabled; all enabled extensions must be specified in that test case.
settingandconfigmethods have been added that allow configuring settings and config.php values before the tested application boots. See the testing docs for more information.- The
php flarum test:setupcommand will now drop the existing test DB tables before creating the database. This means that you can runphp flarum test:setupto ensure a clean database without needing to go into the database and drop tables manually.