Link in SideMenu

Is it possible to add external links to the SideMenu (of MainScreen). I would like to link to external help pages like a wiki.

1 Like

I think you can use a bean to open external link.
Check menu.xsd:

<xs:complexType name="itemType">
    <xs:sequence>
        <xs:element name="properties" type="screenProperties" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute type="xs:string" name="id"/>
    <xs:attribute type="xs:string" name="screen"/>
    <xs:attribute type="xs:string" name="class"/>
    <xs:attribute type="xs:string" name="bean"/>
    <xs:attribute type="xs:string" name="beanMethod"/>
    <xs:attribute type="openModeType" name="openMode"/>
    <xs:attribute type="xs:boolean" name="resizable"/>
    <xs:attribute type="xs:string" name="shortcut"/>
    <xs:attribute type="resourceString" name="caption"/>
    <xs:attribute type="resourceString" name="description"/>
    <xs:attribute type="xs:string" name="stylename"/>
    <xs:attribute type="xs:string" name="icon"/>
    <xs:attributeGroup ref="insertGroup"/>
</xs:complexType>

you can configure menu like below:

<menu id="application" caption="msg://io.cooli.jmix_demo/menu.application" insertBefore="administration"> 
    <item screen="demo_User.browse" caption="msg://io.cooli.jmix_demo.screen.user/UserBrowse.caption"/>
    <item screen="themeSettingsScreen" caption="msg://io.jmix.ui.app.themesettings/themeSettings.caption"/>
    <item bean="menu_EnhanceMenuBean" beanMethod="openLink">
        <properties>
            <property name="url" value="https://jmix.io"/>
        </properties>
    </item>
</menu>

Actually it’s the bean I am struggling with :slight_smile: How can I link to an external URL?

You can use the WebBrowserTools bean as follows:

package com.company.demo.app;

import io.jmix.core.common.util.ParamsMap;
import io.jmix.ui.WebBrowserTools;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {

    @Autowired
    private ObjectProvider<WebBrowserTools> webBrowserToolsProvider;

    public void showWebPage() {
        webBrowserToolsProvider.getObject().showWebPage(
            "https://jmix.io", ParamsMap.of("target", "_blank"));
    }
}

In a screen controller, you can inject WebBrowserTools directly without ObjectProvider.

Thank you @krivopustov , that helped me a lot.

@Component
public class CustomMenu {

  @Autowired
  private ObjectProvider<WebBrowserTools> webBrowserToolsProvider;

  public void openLink(Map<String, Object> parameters) {
    String url = (String) parameters.get("url");
    if (url == null) {
      return;
    }

    webBrowserToolsProvider.getObject()
        .showWebPage(url, ParamsMap.of("target", "_blank"));
  }
}

But I am wondering, why the properties are empty and found the following line:

I guess it is currently not possible to actually make use of the properties.

You are right, now it’s impossible to pass parameters from menu item configuration to the bean method.
We’ll think how to do it: https://github.com/Haulmont/jmix-ui/issues/794

Meanwhile, you can create a class implementing MenuItemRunnable and open required pages depending of the menu item id, for example:

package com.company.untitled1.app;

import io.jmix.core.common.util.ParamsMap;
import io.jmix.ui.WebBrowserTools;
import io.jmix.ui.menu.MenuItem;
import io.jmix.ui.menu.MenuItemRunnable;
import io.jmix.ui.screen.FrameOwner;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class CustomMenu implements MenuItemRunnable, ApplicationContextAware {

    private ApplicationContext applicationContext;

    public void openLink(String url) {
        applicationContext.getBean(WebBrowserTools.class)
                .showWebPage(url, ParamsMap.of("target", "_blank"));
    }

    @Override
    public void run(FrameOwner origin, MenuItem menuItem) {
        if (menuItem.getId().equals("jmix")) {
            openLink("https://jmix.io");
        } else {
            openLink("https://google.com");
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}