Hello 👋,

Since the last update I have completed the porting of extension manager we released last time onto the 2.x branch.

More importantly, I've been tackling what appears to be the most challenging task yet for our 2.0 roadmap: the refactoring of the JSON:API Layer. This is a developer-facing change, so there won't be any visible alterations from the end-user perspective.

Essentially, instead of necessitating extensive boilerplate for model CRUD operations, the refactored code aims to leverage a more abstract yet flexible API.

The new API is built upon the incredible package tobyzerner/json-api-server. (For those interested, you can delve into the current - albeit somewhat dry - details of the refactor process here: flarum/frameworkissues/3964*)

To illustrate, consider the Group model. Currently, we require the following boilerplate:

Api\Controller
 - CreateGroupController.php
 - ListGroupsController.php
 - ShowGroupController.php
 - UpdateGroupController.php
 - DeleteGroupController.php

Api\Serializer
 - GroupSerializer.php

Api\routes.php
 - ->get('/')
 - ->get('/{id}')
 - ->post('/')
 - ->patch('/{id}')
 - ->delete('/{id}')

Group\Command
 - CreateGroup.php
 - CreateGroupHandler.php
 - DeleteGroup.php
 - DeleteGroupHandler.php
 - EditGroup.php
 - EditGroupHandler.php

However, all of the above is replaced with a single GroupResource class:

class GroupResource extends AbstractDatabaseResource
{
    public function type(): string
    {
        return 'groups';
    }

    public function model(): string
    {
        return Group::class;
    }

    public function scope(Builder $query, Context $context): void
    {
        $query->whereVisibleTo($context->getActor());
    }

    public function endpoints(): array
    {
        return [
            Endpoint\Create::make()
                ->authenticated()
                ->can('createGroup'),
            Endpoint\Update::make()
                ->authenticated()
                ->can('edit'),
            Endpoint\Delete::make()
                ->authenticated()
                ->can('delete'),
            Endpoint\Show::make(),
            Endpoint\Index::make(),
        ];
    }

    public function fields(): array
    {
        return [
            Schema\Str::make('nameSingular')
                ->requiredOnCreate()
                ->get(function (Group $group) {
                    return $this->translateGroupName($group->name_singular);
                })
                ->set(function (Group $group, $value) {
                    $group->rename($value, null);
                })
                ->writable()
                ->required(),
            Schema\Str::make('namePlural')
                ->requiredOnCreate()
                ->get(function (Group $group) {
                    return $this->translateGroupName($group->name_plural);
                })
                ->set(function (Group $group, $value) {
                    $group->rename(null, $value);
                })
                ->writable()
                ->required(),
            Schema\Str::make('color')
                ->nullable()
                ->writable(),
            Schema\Str::make('icon')
                ->nullable()
                ->writable(),
            Schema\Boolean::make('isHidden')
                ->writable(),
        ];
    }

    public function sorts(): array
    {
        return [
            SortColumn::make('nameSingular'),
            SortColumn::make('namePlural'),
            SortColumn::make('isHidden'),
        ];
    }

    private function translateGroupName(string $name): string
    {
        $translation = resolve(TranslatorInterface::class)->trans($key = 'core.group.'.strtolower($name));

        if ($translation !== $key) {
            return $translation;
        }

        return $name;
    }

    public function deleting(object $model, Context $context): void
    {
        $this->events->dispatch(
            new Deleting($model, $context->getActor(), [])
        );

        parent::deleting($model, $context);
    }
    4 days later

    Softaculous

    With the extension manager now a thing, and a recent question related to softaculous making me aware about similar issues with softaculous installs, I decided to reach out to their team to inform them about the changes to our installation procedures and the introduction of the extension manager.

    As a consequence, future versions of Softaculous will now install Flarum with the extension manager by default. The ability to natively install extensions should empower these users without having to rely on composer.

    Federation

    Last Tuesday I kicked of my efforts for integrating federation with ActivityPub into Flarum by having a call with the NodeBB maintainer Julian Lam. Julian is also funded by NLNet to integrate Federation into their software. It was really enjoyable to speak to another community software maintainer. Although real collaboration isn't possible due to the use of different technologies, we have decided to stay in touch. Getting a common ground related to the FEPs and guaranteeing interoperability between the two platforms is something we absolutely are going to aim for.

    Since then I've started laying down a basic structure for an extension that will include Webfinger, NodeInfo and other vital functionality to pursue federation for Flarum.

      luceos Can confirm! Installed Flarum with Softaculous today on my webhotel, and it came with the extension manager!

      7 days later

      Hello everyone,

      Recently, we discovered that some tasks for the 2.0 version were overestimated in scope. This has led us to a positive pivot, allocating resources to introduce new features that promise to enrich the Flarum experience significantly.

      One of the exciting updates is to the Extension Manager, which is set to receive a fresh UI for easier discovery and installation of extensions. This enhancement is particularly exciting as it promises to make the Extension Manager an even more central component of the Flarum experience, especially for our dedicated Flarumites.

      For a sneak peek or to join the conversation around the design of this new feature, check out the proposal!

      Stay tuned, as I plan to unveil more about two additional proposals lined up for 2.0 in the upcoming weeks.

      I’ve used some forums software, flarum should be my favorite. I love everything of flarum except the post editor , I would prefer the editor of xenforo, it’s more user-friendly in my opinion

        5 days later

        Hello 👋,

        Quick update on the 2.0 development. The current task I have been working on mentioned here SychO has finally been completed and is currently awaiting review: flarum/framework3971.

        This one is easily the longest and most intricate of the roadmap items by far. But I believe the new API for JSON resources will be a very beneficial upgrade from the old format in the long term.

        I will now begin documenting the breaking changes for the upgrade guide, and the new introduced API for extension developers.

        For some time now there has been a known performance problem related to the retrieval of all user IDs, which is especially aggravated with the active tag tracking extension. This seems to be a costly process in performance.

        flarum/issue-archive99 and with an interesting answer here: flarum/issue-archive99

        I would like to kindly ask if this problem will be addressed in version 2.0 or at least is on the table for the future. Communities with a lot of activity suffer too much.

          SychO Well, at least his message is reassuring. That it's on the table seems like great news to me. Looking forward to Flarum 2.0.

          Performance always seemed to me to be a key part of Flarum.

          20 days later

          For the past couple of weeks I have been working on updating the Flarum CLI and adapting it to the ongoing Flarum 2.0 changes. I have also supercharged it with some pretty neat additions that should further improve the extension dev's experience (flarum/cli41)

          New commands

          • flarum-cli make model [className] [PATH] [-n|--no-interaction]
          • flarum-cli make notification [className] [PATH] [-n|--no-interaction]
          • flarum-cli make post-type [className] [PATH] [-n|--no-interaction]
          • flarum-cli make locale [key] [value] [PATH] [-n|--no-interaction]
          • flarum-cli make backend api-resource [PATH] [-n|--no-interaction]
          • flarum-cli make backend filter [className] [PATH] [-n|--no-interaction]
          • flarum-cli make backend notification-blueprint [className] [PATH] [-n|--no-interaction]
          • flarum-cli make backend notification-driver [className] [PATH] [-n|--no-interaction]
          • flarum-cli make backend post-type [className] [PATH] [-n|--no-interaction]
          • flarum-cli make backend mail-driver [className] [PATH] [-n|--no-interaction]
          • flarum-cli make frontend forum-page [className] [routeName] [routePath] [PATH] [-n|--no-interaction]
          • flarum-cli make frontend gambit [PATH] [-n|--no-interaction]
          • flarum-cli make frontend notification [className] [PATH] [-n|--no-interaction]
          • flarum-cli make frontend post-type [className] [PATH] [-n|--no-interaction]

          Screenshot from 2024-03-29 14-19-59

            4 days later
            7 days later

            Last night we migrated to a new server for flarum.org, docs.flarum.org and discuss.flarum.org. This change was necessary as digital ocean had not been sponsoring our hosting and their costs kept going up. We have now moved to a server hosted with Hetzner.

            Due to this migration, discuss felt slow last night, this should have been settled now. Also emails for notifications might not have been processed, my apologies for any inconvenience. Should you have signed up please use the password forgotten functionality.


            In the past few weeks I have processed the yearly finances for the Foundation, so that the bookkeeper can create the legally required yearly statement. With that being passed on to a third party, I could focus on some of the other matters like the federation extension, the new website, migrating some of our own websites and the Italian verified community to other servers.


            Edit: update, the demos have now also migrated to the new server. This completes the migration from digital ocean to Hetzner.

            9 days later

            Hello 👋,

            Here's a quick update on what we've been working on recently.

            We've been focusing on maintenance-related features. In addition to the existing high maintenance mode, Flarum 2.0 will ship with two new maintenance modes:

            • Low maintenance mode: Allows admins to put the forum under maintenance while retaining admin access (you can see some screenshots here).
            • Safe mode: This mode combines low maintenance with not booting any extensions. This will help recovering from extension breaking issues (you can see some screenshots here).

            We're also working on adding a new feature called Extension Bisect, which will help diagnose which extension is causing a specific observable issue (you can see some screenshots here).

            tolgaaaltas Thanks for advice, i've been using that one, but format changed automatically:
            when switching new lines, you have to press enter 2 more times, so the format you see is what you entered, no offense, but annoying. And when you quoted something, you have to enter extra 2 times so the quotes will not combined as one automatically.
            After uploaded images, sometimes, it show a link and image, sometime just the image (using fof upload).
            Xenforo editor makes me feel stable and steady, you get what you entered lol

            5 days later

            luceos Apologies if it's been shared before, how percentage complete is Flarum 2.0? It is not possible to understand the process with Github Milestones. We're almost halfway through this year, and I'm curious not because I'm impatient, but because I want to see what great work the team has accomplished.

              tolgaaaltas Hi Tolga, in all honesty this is very hard to say. Great progress has already been made for 2.0, mostly because of the zealous effort that @SychO (Sami) has single-handedly put into it. Our original prognoses was to have nightly versions available somewhere at the end of this year. I still believe we are making sufficient progress to be able to reach that goal.

              Many of the open items have already been tackled or seen massive progress, like:

              • the json api backend rewrite
              • upgrade to laravel 10
              • improved ui/ux experience
              • javascript code splitting
              • theme design customizations
              • the extension manager
              • email unsubscribe
              • maintenance mode
              • support for backend search drivers

              Several of the massive rewrites that Sami has worked on are still pending review or edits. Once those are merged, I hope to update our nightly demo website to point to the 2.0 version as soon as possible.