Flat structure or nested pages

In my application, some pages shares a template an part of the url, e.g. the settings page consist of settings/A, settings/B and settings/C, where the pages shares a part of the template including a submenu that displays the different pages and the active one.

My current implementation of this, is that Main know of the Settings page, and that I in that page-module handle what subpage is active. At the moment, this means that I can’t access a subpage directly with settings/A, which I would like to.

I am not familiar yet with all the best practices in Elm, and am hence wondering if I should rather let Main know of each of the subpages, and handle the shared template e.g. in the Page module (my structure is simalar to the elm-spa-example 1? Or if it is okey to have nested pages like i have now, and rather find a way to handle the path?

Each option has advantages and disadvantages. I think that avoiding nesting at all costs can lead to overly convoluted code. Nesting is fine if done in moderation.

So, be mindful of nesting and try to limit it as much as you can BUT, don’t try to avoid it when it is the obvious choice.

I would parse the route into Settings SettingsType where type SettingsType = A | B | C and handle it in the SettingsPage with nesting. :wink:

What exactly are you trying to do? When you say “I want to access a subpage directly”, do you mean, you want Main.elm to pull some kind of value out of Settings/A or something like that?

1 Like

No. What I want is that I can go directly to the path “settings/” and get the default (e.g. first) subpage, but that I can also go to “settings/B” and get subpage B directly, without having to go first to “settings” and then select subpage B.

Thank you! Will try to do that where I find nesting to be most appropriate :slight_smile:

Ah okay. I’m actually kind of in the same boat as you are right now. In my project, its not a settings page, but I also have a page that can be in a number of different states, and can be initialized from many different urls, which reflect different page states.

So, you if you have a settings page, with sub sections A, B, and C, its kind of like you have four routes total.

module Route exposing (..)

type Route
    = Settings SettingsSubRoute

type SettingsSubRoute
    = A 
    | B 
    | C

routeParser =
    [ Url.map (Settings A) (Url.s "settings")
    , Url.map (Settings A) (Url.s "settings" </> Url.s "a")
    , Url.map (Settings B) (Url.s "settings" </> Url.s "b")
    , Url.map (Settings C) (Url.s "settings" </> Url.s "c")

Now, if you do things this way, you have all the routes you want represented. Your routing logic just needs to handle the different cases. Your settings page is initialized somehow. Supposing you have a special Settings.init function, you can simply make the SettingsSubRoute type a parameter:

-- Page/Settings.elm
import Route

type alias Model  = { subSection : subSection }

type SubSection = A | B | C

init : Route.SettingsSubRoute -> Model
init subRoute =
    { subSection =
        case subRoute of
            Routes.A -> A
            Routes.B -> B
            Routes.C -> C

I am sure this code could be cleaned up, and tailored to your specific use-case. But I hope that presents a fresh option of how this could be done. Going back to your original post, in this way, nothing has to “know” what sub section the settings page is in, except the settings page itself. You only have to pass along the information about the Route and the settings page reacts accordingly.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.