Dynamic layout in @Route

I want to have one route url for my LegalNoticeView. But I want navigate to it from different points of my app - from the logged in area but also from the logged out area. Depending on that I want to either have the “layout = MainLayout.class” or not.

I am not happy with my current implementation:

Class LoggedOut

@Route(LegalNoticeLoggedOutView.ROUTE)
@PageTitle(LegalNoticeLoggedOutView.PAGE_TITLE)
@AnonymousAllowed
public class LegalNoticeLoggedOutView extends VerticalLayout {

    @Nonnull public static final String ROUTE = "legalnoticeloggedout";
    @Nonnull public static final String PAGE_TITLE = "Impressum";

    public LegalNoticeLoggedOutView(@Nonnull final LegalNoticeComponent legalNoticeComponent) {
        setAlignItems(Alignment.CENTER);
        H1 title = new H1(PAGE_TITLE);
add(title, legalNoticeComponent);
}```

Class LoggedIn
```java
@Route(value = LegalNoticeLoggedInView.ROUTE, layout = MainLayout.class)
@PageTitle(LegalNoticeLoggedInView.PAGE_TITLE)
@PermitAll
public class LegalNoticeLoggedInView extends VerticalLayout {

    @Nonnull public static final String ROUTE = "legalnoticeloggedin";
    @Nonnull public static final String PAGE_TITLE = "Impressum";

    public LegalNoticeLoggedInView(@Nonnull final LegalNoticeComponent legalNoticeComponent) {
        add(legalNoticeComponent);
}```

Why don’t you create two routes and share the same content.

For that create a class that contains the content

I currently have two routes (@Route(LegalNoticeLoggedOutView.ROUTE and @Route(value = LegalNoticeLoggedInView.ROUTE, layout = MainLayout.class)). And I share the content (LegalNoticeComponent). I would like to dynamically add or remove the layout (layout = MainLayout.class for example).
My goal is to have one route

If your goal is to have a single Route with different layouts you are out of luck. You have to make your main layout intelligent enough to work with authorized and non-authorized users.

To clarify, the goal is not to have two different layouts.

Case 1:

  • user is logged in
    → show layout

Case 2

  • no user is logged in
    → do not show layout

my idea would be to check that in the constructor of the View.

Layout == different Mainlayout / parent / outer layouts

I would like to have something like that (this does not work)

@Route(value = LegalNoticeView.ROUTE)
@PageTitle(LegalNoticeView.PAGE_TITLE)
@PermitAll
@Component
public class LegalNoticeView extends VerticalLayout implements BeforeEnterObserver {

    @Nonnull public static final String ROUTE = "legalnotice";
    @Nonnull public static final String PAGE_TITLE = "Impressum";

    private final LegalNoticeComponent legalNoticeComponent;

    public LegalNoticeView(@Nonnull final LegalNoticeComponent legalNoticeComponent) {
        this.legalNoticeComponent = legalNoticeComponent;
        setAlignItems(Alignment.CENTER);
        setJustifyContentMode(JustifyContentMode.CENTER);
        setSpacing(true);
    }

    @Override
    public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
        removeAll();
        if (isUserLoggedIn()) {
            beforeEnterEvent.getUI().get().setRouterLayout(MainLayout.class); // here I would like to add the MainLayout
            add(legalNoticeComponent); // 
        } else {
            // here I do not need the MainLayout, just the Button and the LegalNoticeComponent like in the other case
            add(new Button("Go to Login", e -> beforeEnterEvent.rerouteTo(LoginView.class)));
            add(legalNoticeComponent);
        }
    }

That’s not possible, I only know workarounds with multiple level of main layouts but that gets a total mess in maintenance. The easiest for you would be to make your main layout user aware and change it accordingly.

IMO having two views would be much easier to understand than having if/else everywhere

Or this :sweat_smile:

thank you a lot - I went for the user aware layout approach and it works well :+1:t4: