Skip to content

Improve menu link adding#8032

Draft
yurabakhtin wants to merge 5 commits into
developfrom
enh/improve-menu-link-adding
Draft

Improve menu link adding#8032
yurabakhtin wants to merge 5 commits into
developfrom
enh/improve-menu-link-adding

Conversation

@yurabakhtin
Copy link
Copy Markdown
Contributor

What kind of change does this PR introduce? (check at least one)

  • Feature

The PR fulfills these requirements:

  • It's submitted to the develop branch, not the master branch if no hotfix
  • All tests are passing
  • Changelog was modified

Other information:
We have many code in the array format like this:

$this->addEntry(new MenuLink([
  'id' => 'spaces',
  'label' => Yii::t('AdminModule.base', 'Spaces'),
  'url' => ['/admin/space'],
  'icon' => 'dot-circle-o',
  'sortOrder' => 400,
  'isActive' => ControllerHelper::isActivePath('admin', 'space'),
  'isVisible' => Yii::$app->user->can([
    ManageSpaces::class,
    ManageSettings::class,
  ]),
]));

I prefer to apply options by methods as we have for bootstrap Button, so new code will be:

$this->addLink(Yii::t('AdminModule.base', 'Spaces'))
    ->link(['/admin/space'])
    ->id('spaces')
    ->icon('dot-circle-o')
    ->sortOrder(400)
    ->active('admin', 'space')
    ->visible(Yii::$app->user->can([ManageSpaces::class, ManageSettings::class]));

I have started this only for the widget AdminMenu, but it is used in almost all modules, if you will approve it then I will do this modification when I work on this https://github.com/humhub/humhub-internal/issues/1042.

@yurabakhtin yurabakhtin requested a review from luke- February 20, 2026 14:31
@luke-
Copy link
Copy Markdown
Contributor

luke- commented Mar 6, 2026

@yurabakhtin I'm a bit ambivalent about method chaining. On the one hand, it's very nice, but on the other hand, it's confusing when there are too many options and it's unclear which ones are required and which ones are optional.

In general, imo it would be best to enforce mandatory (or very typical) attributes via the constructor/create method and make "optional" attributes available via method chaining.

$this->addEntry(MenuLink::create(Yii::t('AdminModule.base', 'Spaces'), ['/admin/space'])
    ->id('spaces')
    ->icon('dot-circle-o')
    ->sortOrder(400)
    ->active('admin', 'space')
    ->visible(Yii::$app->user->can([ManageSpaces::class, ManageSettings::class]));

The second route parameter MenuLink::create(string $label, ?string|array $route) should also be allowed to be null here, but should have to be explicitly set to null.

What do you think about this change?

@yurabakhtin
Copy link
Copy Markdown
Contributor Author

@luke- Ok, for me it is enough too, main idea is to replace the array code to functions, because IDE suggests what methods are allowed for the object when I write -> but it is not fast to go to inside the class and find what properties the class has when it is used as array options.

Maybe we should use the method name as instance instead of create because I see this name is used more often.

The second route parameter MenuLink::create(string $label, ?string|array $route) should also be allowed to be null here, but should have to be explicitly set to null.

I see MenuLink is always used with URL, (except of this single case where property link is directly built as button, but we can keep it as is, without changing) so we can make the second param $route as mandatory string|array. Or when do you think it can be used with null?

@luke-
Copy link
Copy Markdown
Contributor

luke- commented Mar 9, 2026

@luke- Ok, for me it is enough too, main idea is to replace the array code to functions, because IDE suggests what methods are allowed for the object when I write -> but it is not fast to go to inside the class and find what properties the class has when it is used as array options.

👍

Maybe we should use the method name as instance instead of create because I see this name is used more often.

::instance is fine too!

The second route parameter MenuLink::create(string $label, ?string|array $route) should also be allowed to be null here, but should have to be explicitly set to null.

I see MenuLink is always used with URL, (except of this single case where property link is directly built as button, but we can keep it as is, without changing) so we can make the second param $route as mandatory string|array. Or when do you think it can be used with null?

Maybe there are some JS links, so I think we should allow null to avoid problems in future.

@yurabakhtin
Copy link
Copy Markdown
Contributor Author

yurabakhtin commented Mar 10, 2026

@luke- New changes a91a2fe.
Please note one case where I decided to define URL in the separate method url() instead of the second param because the link with title is long, and maybe. we could use this way for all others, i.e. one option is on single line:

        $this->addEntry(MenuLink::instance(Yii::t('AdminModule.base', 'Modules') . $this->getMarketplaceUpdatesBadge())
            ->url(['/admin/module'])

If the method name MenuLink::instance() is long we can name it as MenuLink::to(),
same method name we have to the class humhub\widgets\bootstrap\Link.

# Conflicts:
#	CHANGELOG.md
#	protected/humhub/modules/admin/widgets/AdminMenu.php
#	protected/humhub/modules/ui/menu/MenuLink.php
@luke-
Copy link
Copy Markdown
Contributor

luke- commented Mar 11, 2026

@yurabakhtin Thanks, looks good! If the PR isn't urgent, I'd like to put it on hold. We also wanted to take a closer look at the link/button classes, and it really makes sense to standardize them here as well.

@luke- luke- self-assigned this Mar 11, 2026
@yurabakhtin
Copy link
Copy Markdown
Contributor Author

@luke- Yes, it is not urgent, but it would be good to refactor the menu link adding in future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants