Comments (12)
The initial version has been released! Let me know what you two think! 😄
from elm-pages.
Thanks for sharing your use case @tennety! That's good to know, especially because it gives a solid reason for triggering the msg even in cases where you navigate to a route that isn't found (even if the view
function isn't triggered in that case for now).
from elm-pages.
Hello @rovdyl,
Thank you so much for leaving this feedback! I completely agree, this seems like a common sense feature to add that would be really useful in a lot of situations.
Having an onPageChange
, similar to onUrlChange
, seems like the right design there. And passing it in to init
also makes sense. I think you've described exactly the right approach, I can't think of any refinements.
Great to get another perspective, thanks for chiming in!
from elm-pages.
Excellent! elm-pages seems like a fantastic project and this was one of the only features preventing me from using it on a site of my own. Excited to see how this turns out
from elm-pages.
Hello!
So I did an initial change for this. Here's the PR: #8
I currently have init : Maybe (PagePath pathKey) -> (userModel, Cmd userMsg)
. So if you start out at an invalid page, you get a Nothing
.
I'm wondering which of these two approaches makes more sense for page changes though.
If the user navigates to an invalid page:
- Fire an
onPageChange
Msg
withNothing
- Don't fire an
onPageChange
Msg
at all
The interesting thing is that your view
function currently doesn't get called at all if you are on an invalid page. That design might change (to let you customize your 404 pages).
But it seems strange to have the user's init
and update
functions be called in cases where their view
function is not. It also seems strange to not call the init
function right away in the case where you start out on an invalid route.
The simplest thing to do might be to just always give the user that data (give them the most information possible) and pass Nothing
when they're on invalid routes. Then at a later stage I can revisit the possibility of calling the view
function for "not found" pages.
What do you think of that idea?
from elm-pages.
I think support for custom 404 pages would be a good idea, so adjusting view
to support that makes sense to me.
In fact, if you really wanted to provide as much information as possible, instead of using a Maybe
you could use some custom type and provide the url/path of the invalid page as well. Perhaps this would open up a sort of way to "escape" elm-pages' routing and use a custom router for paths not covered by it (albeit while losing some of the benefits of elm-pages in doing so). No idea if there is an actual use case for something like that, though, especially once elm-pages has better support for pages created from metadata and such, so it may end up just adding unnecessary complexity/confusion.
Whichever way you end up going, though, I think it would be best to call onPageChange
with the same type that is passed to init
, whether that be Maybe (PagePath pathKey)
, my idea for a custom PageOrInvalidPath pathKey
type, or even just PagePath pathKey
if you want to delay calling init
until we're on a valid page (you could still support custom 404 pages in this case by not providing a model to the view if we're on an invalid page, but, to echo your sentiment, that does feel fairly odd). Consistency here is likely good, and whatever information is relevant to init
will likely be relevant to onPageChange
as well, I think.
I'm not entirely sure which option of the three would be best, but with lack of a specific use case it may actually be best to go with the option that provides the simplest possible API. I suppose technically that would be the plain PagePath pathKey
, but if you do want to support custom 404 pages with interactivity, then at least Maybe (PagePath pathKey)
will likely be necessary.
Hope these thoughts help in some way.
from elm-pages.
I like the idea of passing the full URL instead of Nothing
and using that as a way to do custom routing. That was sort of the design I had in mind for that as well.
I wonder if it makes sense to treat 404 pages differently than a dynamic route? I guess the only reason it would be important would be if you want to actually have an HTTP status of 404, which may not actually be necessary for user-facing web applications (as opposed to machine-read API responses). I like the simplicity of having 404 pages just be another type of dynamic route, and then leaving it to the user to display a 404 message, OR display a dynamic route, based on their own routing logic. Or always display a 404 message for fallback (non-static) routes.
I'll open a separate issue to discuss dynamic routing and 404s. This is definitely on the roadmap, but I'd like to tackle that issue separately and ship a simpler version of this for now.
Changes for this iteration
Whichever way you end up going, though, I think it would be best to call onPageChange with the same type that is passed to init, whether that be Maybe (PagePath pathKey), my idea for a custom PageOrInvalidPath pathKey type, or even just PagePath pathKey if you want to delay calling init until we're on a valid page (you could still support custom 404 pages in this case by not providing a model to the view if we're on an invalid page, but, to echo your sentiment, that does feel fairly odd). Consistency here is likely good, and whatever information is relevant to init will likely be relevant to onPageChange as well, I think.
That sounds like a good idea to have onPageChange
take the exact same type as init
.
For this iteration, I'll start with this API:
init : Maybe (PagePath pathKey) -> ( model, Cmd msg)
onPageChange : Maybe (PagePath pathKey) -> msg
Future iteration
I'll revisit these ideas in the next round:
- Call
view
when the page is not found - Instead of
Nothing
, pass in the URL when navigating to a page that is not one of the static routes (to let the user either render a custom 404, or do their own dynamic routing) - I need to consider the implications of this design, but it seems reasonable.
Here's a rough sketch of what that could look like. I think that there may need to be a different view
function static pages and dynamic pages. The key differences:
- Static pages get pre-rendered at build time (dynamic pages don't)
- Static pages can have a list of
Head.Tag
s that are added to the pre-rendered HTML (dynamic pages can't) - Static pages have a
StaticHttp.Request
(dynamic pages don't)
type Route pathKey frontmatter = StaticRoute (PagePath pathKey frontmatter) | DynamicRoute Url
init : Route pathKey -> ( model, Cmd msg)
onPageChange : Route pathKey -> msg
staticView :
List ( PagePath pathKey, metadata )
->
{ path : PagePath pathKey
, frontmatter : metadata
}
->
StaticHttp.Request
{ view : Model -> View -> { title : String, body : Html Msg }
, head : List (Head.Tag Pages.PathKey)
}
dynamicView : List ( PagePath pathKey, metadata ) -> Url -> Model -> { title : String, body : Html msg }
from elm-pages.
Thanks again for the really helpful input and brainstorming @rovdyl! I really appreciate the discussion!
I'll be merging the changes I described in "Changes for this iteration" (unless you have any concerns about that design). This will go out with the major release that will include the StaticHttp
API.
from elm-pages.
Also, for reference, with Netlify you could set up redirects for custom 404s and dynamic routes using a rule like this:
/* /index.html 200
Because of Netlify's route shadowing behavior, it will only do that redirect if it doesn't conflict with a static file that would satisfy a given route. So it would work perfectly for that use case!
Full docs are here:
https://docs.netlify.com/routing/redirects/rewrites-proxies/#history-pushstate-and-single-page-apps
from elm-pages.
Thank you so much for hearing me out! This looks absolutely perfect to me, I really like the idea of having separate views like that. I think it's a lot cleaner than the idea I had in mind, and I'm excited to think about what StaticHttp.Request
will allow for. Looking forward to seeing how this goes 👍
from elm-pages.
Just adding my use-case here in case other folks are attempting something similar: a pop-up nav that should close when a link is clicked and the page is navigated to. I think the proposed onPageChange
hook would be perfect for setting my nav state.
from elm-pages.
The onPageChange
hook works great for what I was trying to do!
from elm-pages.
Related Issues (20)
- elm-pages run script/src/AddRoute.elm fails when run before first build HOT 4
- [SSCCE] ANSI escape codes in `onError` and `ErrorPage` error messages
- Provide a way to render static 404 pages using elm-pages HOT 2
- Replace StaticHttp examples in BackendTask HOT 1
- Cannot watch for fragment changes in URL
- Scroll is reset on back navigation HOT 1
- DeadCodeEliminateData errors cached in elm-stuff
- Feature request: `Pages.Script.writeFileBinary`/`BackendTask.File.rawBinary` HOT 2
- `elm-pages build` inserts `import FatalError` into unit test modules HOT 2
- Update .gitignore generator template for elm-pages-cli-mjs HOT 1
- Compilation error when using `elm-pages docs` HOT 9
- npx elm-pages run <script name> does not work on Windows HOT 1
- Vite Pre-transform error after upgrade HOT 9
- Initialization failed while loading node modules HOT 4
- Compatibility Keys match, but elm-pages says they don't when running script HOT 7
- Feature request: `BackendTask.race` HOT 1
- Feature request: `Script.stateful` HOT 1
- `Debug.todo` causes a `Script` to stop with no error message HOT 5
- INTERNAL ERROR when calling custom task. HOT 1
- BadBody: INTERNAL ERROR when input to Backend.Custom.run is mutated HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from elm-pages.