elm-pages 3.0.0-beta.40 → 3.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/codegen/elm-pages-codegen.cjs +204 -262
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
- package/generator/src/RouteBuilder.elm +9 -8
- package/generator/src/SharedTemplate.elm +5 -5
- package/generator/src/compatibility-key.js +2 -2
- package/package.json +1 -1
- package/src/BackendTask.elm +18 -24
- package/src/Head/Seo.elm +4 -4
- package/src/Pages/ConcurrentSubmission.elm +127 -0
- package/src/Pages/Form.elm +151 -40
- package/src/Pages/FormData.elm +18 -0
- package/src/Pages/Internal/NotFoundReason.elm +4 -4
- package/src/Pages/Internal/Platform/Cli.elm +15 -15
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
- package/src/Pages/Internal/Platform.elm +39 -38
- package/src/Pages/Internal/ResponseSketch.elm +2 -2
- package/src/Pages/Manifest.elm +23 -7
- package/src/Pages/Navigation.elm +87 -0
- package/src/Pages/PageUrl.elm +3 -3
- package/src/Pages/ProgramConfig.elm +10 -9
- package/src/Pages/Script.elm +64 -7
- package/src/Pages/Url.elm +3 -3
- package/src/PagesMsg.elm +9 -3
- package/src/RenderRequest.elm +7 -7
- package/src/Scaffold/Form.elm +28 -5
- package/src/Scaffold/Route.elm +12 -3
- package/src/Server/Request.elm +2 -1
- package/src/Server/Session.elm +1 -1
- package/src/Server/SetCookie.elm +71 -31
- package/src/{Path.elm → UrlPath.elm} +21 -21
- package/src/Pages/Transition.elm +0 -79
package/src/Pages/Form.elm
CHANGED
|
@@ -1,11 +1,47 @@
|
|
|
1
1
|
module Pages.Form exposing
|
|
2
|
-
(
|
|
2
|
+
( renderHtml, renderStyledHtml
|
|
3
|
+
, Options
|
|
4
|
+
, withConcurrent
|
|
3
5
|
, FormWithServerValidations, Handler
|
|
4
6
|
)
|
|
5
7
|
|
|
6
|
-
{-|
|
|
8
|
+
{-| `elm-pages` has a built-in integration with [`dillonkearns/elm-form`](https://package.elm-lang.org/packages/dillonkearns/elm-form/latest/). See the `dillonkearns/elm-form`
|
|
9
|
+
docs and examples for more information on how to define your [`Form`](https://package.elm-lang.org/packages/dillonkearns/elm-form/latest/Form). This module is the interface for rendering your `Form` in your `elm-pages` app.
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
By rendering your `Form` with this module,
|
|
12
|
+
you get all of the boilerplate managed for you automatically by the `elm-pages` framework. That means you do not need to use `Form.init`, `Form.update`, `Form.Model` since these are all
|
|
13
|
+
abstracted away. In addition to that, in-flight form state is automatically managed for you and exposed through the `app` argument in your Route modules.
|
|
14
|
+
|
|
15
|
+
This means that you can declaratively derive Pending UI or Optimistic UI state from `app.navigation` or `app.concurrentSubmissions` in your Route modules, and even build a
|
|
16
|
+
rich dynamic page that shows pending submissions in the UI without using your Route module's `Model`! This is the power of this abstraction - it's less error-prone to
|
|
17
|
+
declaratively derive state rather than imperatively managing your `Model`.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Rendering Forms
|
|
21
|
+
|
|
22
|
+
@docs renderHtml, renderStyledHtml
|
|
23
|
+
|
|
24
|
+
@docs Options
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
## Form Submission Strategies
|
|
28
|
+
|
|
29
|
+
When you render with [`Pages.Form.renderHtml`](#renderHtml) or [`Pages.Form.renderStyledHtml`](#renderStyledHtml),
|
|
30
|
+
`elm-pages` progressively enhances form submissions to manage the requests through Elm (instead of as a vanilla HTML form submission, which performs a full page reload).
|
|
31
|
+
|
|
32
|
+
By default, `elm-pages` Forms will use the same mental model as the browser's default form submission behavior. That is, the form submission state will be tied to the page's navigation state.
|
|
33
|
+
If you click a link while a form is submitting, the form submission will be cancelled and the page will navigate to the new page. Conceptually, you can think of this as being tied to the navigation state.
|
|
34
|
+
A form submission is part of the page's navigation state, and so is a page navigation. So if you have a page with an edit form, a delete form (no inputs but only a delete button), and a link to a new page,
|
|
35
|
+
you can interact with any of these and it will cancel the previous interactions.
|
|
36
|
+
|
|
37
|
+
You can access this state through `app.navigation` in your `Route` module, which is a value of type [`Pages.Navigation`](Pages-Navigation).
|
|
38
|
+
|
|
39
|
+
This default form submission strategy is a good fit for more linear actions. This is more traditional server submission behavior that you might be familiar with from Rails or other server frameworks without JavaScript enhancement.
|
|
40
|
+
|
|
41
|
+
@docs withConcurrent
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## Server-Side Validation
|
|
9
45
|
|
|
10
46
|
@docs FormWithServerValidations, Handler
|
|
11
47
|
|
|
@@ -19,8 +55,9 @@ import Form.Handler
|
|
|
19
55
|
import Form.Validation exposing (Validation)
|
|
20
56
|
import Html
|
|
21
57
|
import Html.Styled
|
|
58
|
+
import Pages.ConcurrentSubmission
|
|
22
59
|
import Pages.Internal.Msg
|
|
23
|
-
import Pages.
|
|
60
|
+
import Pages.Navigation
|
|
24
61
|
import PagesMsg exposing (PagesMsg)
|
|
25
62
|
|
|
26
63
|
|
|
@@ -45,56 +82,122 @@ type alias Handler error combined =
|
|
|
45
82
|
Form.Handler.Handler error (BackendTask FatalError (Validation error combined Never Never))
|
|
46
83
|
|
|
47
84
|
|
|
48
|
-
{-| -
|
|
49
|
-
type
|
|
50
|
-
|
|
51
|
-
|
|
85
|
+
{-| A replacement for [`Form.Options`](https://package.elm-lang.org/packages/dillonkearns/elm-form/latest/Form#Options)
|
|
86
|
+
with some extra configuration for the `elm-pages` integration. You can use this type to annotate your form's options.
|
|
87
|
+
-}
|
|
88
|
+
type alias Options error parsed input msg =
|
|
89
|
+
Form.Options error parsed input msg { concurrent : Bool }
|
|
52
90
|
|
|
53
91
|
|
|
54
|
-
{-|
|
|
92
|
+
{-| Instead of using the default submission strategy (tied to the page's navigation state), you can use `withConcurrent`.
|
|
93
|
+
`withConcurrent` allows multiple form submissions to be in flight at the same time. It is useful for more dynamic applications. A good rule of thumb
|
|
94
|
+
is if you could have multiple pending spinners on the page at the same time, you should use `withConcurrent`. For example, if you have a page with a list of items,
|
|
95
|
+
say a Twitter clone. If you click the like button on a Tweet, it won't result in a page navigation. You can click the like button on multiple Tweets at the same time
|
|
96
|
+
and they will all submit independently.
|
|
97
|
+
|
|
98
|
+
In the case of Twitter, there isn't an indication of a loading spinner on the like button because it is expected that it will succeed. This is an example of a User Experience (UX) pattern
|
|
99
|
+
called Optimistic UI. Since it is very likely that liking a Tweet will be successful, the UI will update the UI as if it has immediately succeeded even though the request is still in flight.
|
|
100
|
+
If the request fails, the UI will be updated to reflect the failure with an animation to show that something went wrong.
|
|
101
|
+
|
|
102
|
+
The `withConcurrent` is a good fit for either of these UX patterns (Optimistic UI or Pending UI, i.e. showing a loading spinner). You can derive either of these
|
|
103
|
+
visual states from the `app.concurrentSubmissions` field in your `Route` module.
|
|
104
|
+
|
|
105
|
+
You can call `withConcurrent` on your `Form.Options`. Note that while `withConcurrent` will allow multiple form submissions to be in flight at the same time independently,
|
|
106
|
+
the ID of the Form will still have a unique submission. For example, if you click submit on a form with the ID `"edit-123"` and then submit it again before the first submission has completed,
|
|
107
|
+
the second submission will cancel the first submission. So it is important to use unique IDs for forms that represent unique operations.
|
|
108
|
+
|
|
109
|
+
import Form
|
|
110
|
+
import Pages.Form
|
|
111
|
+
|
|
112
|
+
todoItemView app todo =
|
|
113
|
+
deleteItemForm
|
|
114
|
+
|> Pages.Form.renderHtml []
|
|
115
|
+
(Form.options ("delete-" ++ todo.id)
|
|
116
|
+
|> Form.withInput todo
|
|
117
|
+
|> Pages.Form.withConcurrent
|
|
118
|
+
)
|
|
119
|
+
app
|
|
120
|
+
|
|
121
|
+
-}
|
|
122
|
+
withConcurrent : Options error parsed input msg -> Options error parsed input msg
|
|
123
|
+
withConcurrent options_ =
|
|
124
|
+
{ options_ | extras = Just { concurrent = True } }
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
--init :
|
|
129
|
+
-- (parsed -> combined)
|
|
130
|
+
-- -> FormWithServerValidations error parsed input view
|
|
131
|
+
-- -> Handler error combined
|
|
132
|
+
--init mapFn form =
|
|
133
|
+
-- Form.Handler.init
|
|
134
|
+
-- (\something ->
|
|
135
|
+
-- let
|
|
136
|
+
-- foo : parsed
|
|
137
|
+
-- foo =
|
|
138
|
+
-- something
|
|
139
|
+
--
|
|
140
|
+
-- goal : BackendTask FatalError (Validation error combined Never Never)
|
|
141
|
+
-- goal =
|
|
142
|
+
-- Debug.todo ""
|
|
143
|
+
-- in
|
|
144
|
+
-- --Form.Validation.map (BackendTask.map (mapFn something))
|
|
145
|
+
-- --Debug.todo ""
|
|
146
|
+
-- goal
|
|
147
|
+
-- )
|
|
148
|
+
-- form
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
{-| A replacement for `Form.renderHtml` from `dillonkearns/elm-form` that integrates with `elm-pages`. Use this to render your [`Form`](https://package.elm-lang.org/packages/dillonkearns/elm-form/latest/Form)
|
|
152
|
+
as `elm/html` `Html`.
|
|
153
|
+
-}
|
|
55
154
|
renderHtml :
|
|
56
155
|
List (Html.Attribute (PagesMsg userMsg))
|
|
57
|
-
->
|
|
58
|
-
-> Form.Options error parsed input userMsg
|
|
156
|
+
-> Options error parsed input userMsg
|
|
59
157
|
->
|
|
60
158
|
{ --path : Path
|
|
61
159
|
--, url : Maybe PageUrl
|
|
62
160
|
--, action : Maybe action
|
|
63
161
|
app
|
|
64
162
|
| pageFormState : Form.Model
|
|
65
|
-
,
|
|
66
|
-
,
|
|
163
|
+
, navigation : Maybe Pages.Navigation.Navigation
|
|
164
|
+
, concurrentSubmissions : Dict String (Pages.ConcurrentSubmission.ConcurrentSubmission (Maybe action))
|
|
67
165
|
}
|
|
68
166
|
-> Form.Form error { combine : Validation error parsed named constraints, view : Form.Context error input -> List (Html.Html (PagesMsg userMsg)) } parsed input
|
|
69
167
|
-> Html.Html (PagesMsg userMsg)
|
|
70
|
-
renderHtml attrs
|
|
168
|
+
renderHtml attrs options_ app form_ =
|
|
169
|
+
let
|
|
170
|
+
concurrent : Bool
|
|
171
|
+
concurrent =
|
|
172
|
+
options_.extras |> Maybe.map .concurrent |> Maybe.withDefault False
|
|
173
|
+
in
|
|
71
174
|
form_
|
|
72
175
|
|> Form.renderHtml
|
|
73
176
|
{ state = app.pageFormState
|
|
74
177
|
, submitting =
|
|
75
|
-
(case app.
|
|
178
|
+
(case app.concurrentSubmissions |> Dict.get options_.id of
|
|
76
179
|
Just { status } ->
|
|
77
180
|
case status of
|
|
78
|
-
Pages.
|
|
181
|
+
Pages.ConcurrentSubmission.Complete _ ->
|
|
79
182
|
False
|
|
80
183
|
|
|
81
|
-
Pages.
|
|
184
|
+
Pages.ConcurrentSubmission.Submitting ->
|
|
82
185
|
True
|
|
83
186
|
|
|
84
|
-
Pages.
|
|
187
|
+
Pages.ConcurrentSubmission.Reloading _ ->
|
|
85
188
|
True
|
|
86
189
|
|
|
87
190
|
Nothing ->
|
|
88
191
|
False
|
|
89
192
|
)
|
|
90
|
-
|| (case app.
|
|
91
|
-
Just (Pages.
|
|
193
|
+
|| (case app.navigation of
|
|
194
|
+
Just (Pages.Navigation.Submitting formData) ->
|
|
92
195
|
formData.id == Just options_.id
|
|
93
196
|
|
|
94
|
-
Just (Pages.
|
|
197
|
+
Just (Pages.Navigation.LoadAfterSubmit submitData _ _) ->
|
|
95
198
|
submitData.id == Just options_.id
|
|
96
199
|
|
|
97
|
-
Just (Pages.
|
|
200
|
+
Just (Pages.Navigation.Loading _ _) ->
|
|
98
201
|
False
|
|
99
202
|
|
|
100
203
|
Nothing ->
|
|
@@ -113,7 +216,7 @@ renderHtml attrs strategy options_ app form_ =
|
|
|
113
216
|
case submission.parsed of
|
|
114
217
|
Form.Valid _ ->
|
|
115
218
|
Pages.Internal.Msg.Submit
|
|
116
|
-
{ useFetcher =
|
|
219
|
+
{ useFetcher = concurrent
|
|
117
220
|
, action = submission.action
|
|
118
221
|
, fields = submission.fields
|
|
119
222
|
, method = submission.method
|
|
@@ -127,7 +230,7 @@ renderHtml attrs strategy options_ app form_ =
|
|
|
127
230
|
|
|
128
231
|
Form.Invalid _ _ ->
|
|
129
232
|
Pages.Internal.Msg.Submit
|
|
130
|
-
{ useFetcher =
|
|
233
|
+
{ useFetcher = concurrent
|
|
131
234
|
, action = submission.action
|
|
132
235
|
, method = submission.method
|
|
133
236
|
, fields = submission.fields
|
|
@@ -136,55 +239,62 @@ renderHtml attrs strategy options_ app form_ =
|
|
|
136
239
|
, valid = False
|
|
137
240
|
}
|
|
138
241
|
)
|
|
242
|
+
, extras = Nothing
|
|
139
243
|
}
|
|
140
244
|
attrs
|
|
141
245
|
|
|
142
246
|
|
|
143
|
-
{-| -
|
|
247
|
+
{-| A replacement for `Form.renderStyledHtml` from `dillonkearns/elm-form` that integrates with `elm-pages`. Use this to render your [`Form`](https://package.elm-lang.org/packages/dillonkearns/elm-form/latest/Form)
|
|
248
|
+
as `rtfeldman/elm-css` `Html.Styled.Html`.
|
|
249
|
+
-}
|
|
144
250
|
renderStyledHtml :
|
|
145
251
|
List (Html.Styled.Attribute (PagesMsg userMsg))
|
|
146
|
-
->
|
|
147
|
-
-> Form.Options error parsed input userMsg
|
|
252
|
+
-> Options error parsed input userMsg
|
|
148
253
|
->
|
|
149
254
|
{ --path : Path
|
|
150
255
|
--, url : Maybe PageUrl
|
|
151
256
|
--, action : Maybe action
|
|
152
257
|
app
|
|
153
258
|
| pageFormState : Form.Model
|
|
154
|
-
,
|
|
155
|
-
,
|
|
259
|
+
, navigation : Maybe Pages.Navigation.Navigation
|
|
260
|
+
, concurrentSubmissions : Dict String (Pages.ConcurrentSubmission.ConcurrentSubmission (Maybe action))
|
|
156
261
|
}
|
|
157
262
|
-> Form.Form error { combine : Validation error parsed named constraints, view : Form.Context error input -> List (Html.Styled.Html (PagesMsg userMsg)) } parsed input
|
|
158
263
|
-> Html.Styled.Html (PagesMsg userMsg)
|
|
159
|
-
renderStyledHtml attrs
|
|
264
|
+
renderStyledHtml attrs options_ app form_ =
|
|
265
|
+
let
|
|
266
|
+
concurrent : Bool
|
|
267
|
+
concurrent =
|
|
268
|
+
options_.extras |> Maybe.map .concurrent |> Maybe.withDefault False
|
|
269
|
+
in
|
|
160
270
|
form_
|
|
161
271
|
|> Form.renderStyledHtml
|
|
162
272
|
{ state = app.pageFormState
|
|
163
273
|
, toMsg = Pages.Internal.Msg.FormMsg
|
|
164
274
|
, submitting =
|
|
165
|
-
(case app.
|
|
275
|
+
(case app.concurrentSubmissions |> Dict.get options_.id of
|
|
166
276
|
Just { status } ->
|
|
167
277
|
case status of
|
|
168
|
-
Pages.
|
|
278
|
+
Pages.ConcurrentSubmission.Complete _ ->
|
|
169
279
|
False
|
|
170
280
|
|
|
171
|
-
Pages.
|
|
281
|
+
Pages.ConcurrentSubmission.Submitting ->
|
|
172
282
|
True
|
|
173
283
|
|
|
174
|
-
Pages.
|
|
284
|
+
Pages.ConcurrentSubmission.Reloading _ ->
|
|
175
285
|
True
|
|
176
286
|
|
|
177
287
|
Nothing ->
|
|
178
288
|
False
|
|
179
289
|
)
|
|
180
|
-
|| (case app.
|
|
181
|
-
Just (Pages.
|
|
290
|
+
|| (case app.navigation of
|
|
291
|
+
Just (Pages.Navigation.Submitting formData) ->
|
|
182
292
|
formData.id == Just options_.id
|
|
183
293
|
|
|
184
|
-
Just (Pages.
|
|
294
|
+
Just (Pages.Navigation.LoadAfterSubmit submitData _ _) ->
|
|
185
295
|
submitData.id == Just options_.id
|
|
186
296
|
|
|
187
|
-
Just (Pages.
|
|
297
|
+
Just (Pages.Navigation.Loading _ _) ->
|
|
188
298
|
False
|
|
189
299
|
|
|
190
300
|
Nothing ->
|
|
@@ -202,7 +312,7 @@ renderStyledHtml attrs strategy options_ app form_ =
|
|
|
202
312
|
case submission.parsed of
|
|
203
313
|
Form.Valid _ ->
|
|
204
314
|
Pages.Internal.Msg.Submit
|
|
205
|
-
{ useFetcher =
|
|
315
|
+
{ useFetcher = concurrent
|
|
206
316
|
, action = submission.action
|
|
207
317
|
, fields = submission.fields
|
|
208
318
|
, method = submission.method
|
|
@@ -216,7 +326,7 @@ renderStyledHtml attrs strategy options_ app form_ =
|
|
|
216
326
|
|
|
217
327
|
Form.Invalid _ _ ->
|
|
218
328
|
Pages.Internal.Msg.Submit
|
|
219
|
-
{ useFetcher =
|
|
329
|
+
{ useFetcher = concurrent
|
|
220
330
|
, action = submission.action
|
|
221
331
|
, fields = submission.fields
|
|
222
332
|
, method = submission.method
|
|
@@ -225,5 +335,6 @@ renderStyledHtml attrs strategy options_ app form_ =
|
|
|
225
335
|
, valid = False
|
|
226
336
|
}
|
|
227
337
|
)
|
|
338
|
+
, extras = Nothing
|
|
228
339
|
}
|
|
229
340
|
attrs
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Pages.FormData exposing (FormData)
|
|
2
|
+
|
|
3
|
+
{-|
|
|
4
|
+
|
|
5
|
+
@docs FormData
|
|
6
|
+
|
|
7
|
+
-}
|
|
8
|
+
|
|
9
|
+
import Form
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
{-| -}
|
|
13
|
+
type alias FormData =
|
|
14
|
+
{ fields : List ( String, String )
|
|
15
|
+
, method : Form.Method
|
|
16
|
+
, action : String
|
|
17
|
+
, id : Maybe String
|
|
18
|
+
}
|
|
@@ -9,7 +9,7 @@ module Pages.Internal.NotFoundReason exposing (ModuleContext, NotFoundReason(..)
|
|
|
9
9
|
import Html exposing (Html)
|
|
10
10
|
import Html.Attributes as Attr
|
|
11
11
|
import Pages.Internal.RoutePattern exposing (RoutePattern)
|
|
12
|
-
import
|
|
12
|
+
import UrlPath exposing (UrlPath)
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
{-| -}
|
|
@@ -22,7 +22,7 @@ type alias ModuleContext =
|
|
|
22
22
|
|
|
23
23
|
{-| -}
|
|
24
24
|
type alias Payload =
|
|
25
|
-
{ path :
|
|
25
|
+
{ path : UrlPath
|
|
26
26
|
, reason : NotFoundReason
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -58,7 +58,7 @@ document pathPatterns payload =
|
|
|
58
58
|
, Html.code []
|
|
59
59
|
[ Html.text
|
|
60
60
|
(payload.path
|
|
61
|
-
|>
|
|
61
|
+
|> UrlPath.toAbsolute
|
|
62
62
|
)
|
|
63
63
|
]
|
|
64
64
|
, Html.text " Did you mean to go to one of these routes:"
|
|
@@ -85,7 +85,7 @@ document pathPatterns payload =
|
|
|
85
85
|
, Html.code []
|
|
86
86
|
[ Html.text
|
|
87
87
|
(payload.path
|
|
88
|
-
|>
|
|
88
|
+
|> UrlPath.toAbsolute
|
|
89
89
|
)
|
|
90
90
|
]
|
|
91
91
|
, Html.text " successfully matched the route "
|
|
@@ -32,11 +32,11 @@ import Pages.ProgramConfig exposing (ProgramConfig)
|
|
|
32
32
|
import Pages.SiteConfig exposing (SiteConfig)
|
|
33
33
|
import Pages.StaticHttp.Request
|
|
34
34
|
import PagesMsg exposing (PagesMsg)
|
|
35
|
-
import Path exposing (Path)
|
|
36
35
|
import RenderRequest exposing (RenderRequest)
|
|
37
36
|
import RequestsAndPending exposing (RequestsAndPending)
|
|
38
37
|
import TerminalText as Terminal
|
|
39
38
|
import Url exposing (Url)
|
|
39
|
+
import UrlPath exposing (UrlPath)
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
{-| -}
|
|
@@ -402,7 +402,7 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
|
|
|
402
402
|
{ protocol = Url.Https
|
|
403
403
|
, host = site.canonicalUrl
|
|
404
404
|
, port_ = Nothing
|
|
405
|
-
, path = serverRequestPayload.path |>
|
|
405
|
+
, path = serverRequestPayload.path |> UrlPath.toRelative
|
|
406
406
|
, query = Nothing
|
|
407
407
|
, fragment = Nothing
|
|
408
408
|
}
|
|
@@ -471,7 +471,7 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
|
|
|
471
471
|
case pageData of
|
|
472
472
|
PageServerResponse.RenderPage responseInfo pageData_ ->
|
|
473
473
|
let
|
|
474
|
-
currentPage : { path :
|
|
474
|
+
currentPage : { path : UrlPath, route : route }
|
|
475
475
|
currentPage =
|
|
476
476
|
{ path = serverRequestPayload.path, route = urlToRoute config currentUrl }
|
|
477
477
|
|
|
@@ -565,7 +565,7 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
|
|
|
565
565
|
-- TODO handle other cases besides redirects?
|
|
566
566
|
|> Maybe.withDefault byteEncodedPageData
|
|
567
567
|
|> (\encodedData ->
|
|
568
|
-
{ route = currentPage.path |>
|
|
568
|
+
{ route = currentPage.path |> UrlPath.toRelative
|
|
569
569
|
, contentJson = Dict.empty
|
|
570
570
|
, html = viewValue.body |> bodyToString
|
|
571
571
|
, errors = []
|
|
@@ -615,7 +615,7 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
|
|
|
615
615
|
|
|
616
616
|
PageServerResponse.ErrorPage error record ->
|
|
617
617
|
let
|
|
618
|
-
currentPage : { path :
|
|
618
|
+
currentPage : { path : UrlPath, route : route }
|
|
619
619
|
currentPage =
|
|
620
620
|
{ path = serverRequestPayload.path, route = urlToRoute config currentUrl }
|
|
621
621
|
|
|
@@ -651,7 +651,7 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
|
|
|
651
651
|
|> Bytes.Encode.encode
|
|
652
652
|
)
|
|
653
653
|
|> (\encodedData ->
|
|
654
|
-
{ route = currentPage.path |>
|
|
654
|
+
{ route = currentPage.path |> UrlPath.toRelative
|
|
655
655
|
, contentJson = Dict.empty
|
|
656
656
|
, html = viewValue.body |> bodyToString
|
|
657
657
|
, errors = []
|
|
@@ -743,7 +743,7 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
|
|
|
743
743
|
)
|
|
744
744
|
|> Tuple.first
|
|
745
745
|
|
|
746
|
-
currentPage : { path :
|
|
746
|
+
currentPage : { path : UrlPath, route : route }
|
|
747
747
|
currentPage =
|
|
748
748
|
{ path = serverRequestPayload.path, route = urlToRoute config currentUrl }
|
|
749
749
|
|
|
@@ -752,7 +752,7 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
|
|
|
752
752
|
(config.view Dict.empty Dict.empty Nothing currentPage Nothing justSharedData dataThing Nothing |> .view)
|
|
753
753
|
pageModel
|
|
754
754
|
in
|
|
755
|
-
{ route =
|
|
755
|
+
{ route = UrlPath.toAbsolute currentPage.path
|
|
756
756
|
, contentJson = Dict.empty
|
|
757
757
|
, html = viewValue.body |> bodyToString
|
|
758
758
|
, errors = []
|
|
@@ -797,7 +797,7 @@ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as rende
|
|
|
797
797
|
-- TODO do I need sharedDataResult here?
|
|
798
798
|
Nothing
|
|
799
799
|
isDevServer
|
|
800
|
-
(
|
|
800
|
+
(UrlPath.fromString path)
|
|
801
801
|
NotFoundReason.NoMatchingRoute
|
|
802
802
|
--Err error ->
|
|
803
803
|
-- [ error ]
|
|
@@ -909,7 +909,7 @@ render404Page :
|
|
|
909
909
|
ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
910
910
|
-> Maybe sharedData
|
|
911
911
|
-> Bool
|
|
912
|
-
->
|
|
912
|
+
-> UrlPath
|
|
913
913
|
-> NotFoundReason
|
|
914
914
|
-> Effect
|
|
915
915
|
render404Page config sharedData isDevServer path notFoundReason =
|
|
@@ -940,7 +940,7 @@ render404Page config sharedData isDevServer path notFoundReason =
|
|
|
940
940
|
pageData =
|
|
941
941
|
config.errorPageToData config.notFoundPage
|
|
942
942
|
|
|
943
|
-
pathAndRoute : { path :
|
|
943
|
+
pathAndRoute : { path : UrlPath, route : route }
|
|
944
944
|
pathAndRoute =
|
|
945
945
|
{ path = path, route = config.notFoundRoute }
|
|
946
946
|
|
|
@@ -958,7 +958,7 @@ render404Page config sharedData isDevServer path notFoundReason =
|
|
|
958
958
|
)
|
|
959
959
|
pageModel
|
|
960
960
|
in
|
|
961
|
-
{ route =
|
|
961
|
+
{ route = UrlPath.toAbsolute path
|
|
962
962
|
, contentJson = Dict.empty
|
|
963
963
|
, html = viewValue.body |> bodyToString
|
|
964
964
|
, errors = []
|
|
@@ -987,7 +987,7 @@ render404Page config sharedData isDevServer path notFoundReason =
|
|
|
987
987
|
}
|
|
988
988
|
|> NotFoundReason.document config.pathPatterns
|
|
989
989
|
in
|
|
990
|
-
{ route =
|
|
990
|
+
{ route = UrlPath.toAbsolute path
|
|
991
991
|
, contentJson = Dict.empty
|
|
992
992
|
, html = bodyToString notFoundDocument.body
|
|
993
993
|
, errors = []
|
|
@@ -1021,7 +1021,7 @@ urlToRoute config url =
|
|
|
1021
1021
|
|
|
1022
1022
|
toRedirectResponse :
|
|
1023
1023
|
ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
1024
|
-
-> { b | path :
|
|
1024
|
+
-> { b | path : UrlPath }
|
|
1025
1025
|
-> RenderRequest.IncludeHtml
|
|
1026
1026
|
-> { c | headers : List ( String, String ), statusCode : Int }
|
|
1027
1027
|
-> { response | statusCode : Int, headers : List ( String, String ) }
|
|
@@ -1044,7 +1044,7 @@ toRedirectResponse config serverRequestPayload includeHtml serverResponse respon
|
|
|
1044
1044
|
|> Bytes.Encode.encode
|
|
1045
1045
|
)
|
|
1046
1046
|
in
|
|
1047
|
-
{ route = serverRequestPayload.path |>
|
|
1047
|
+
{ route = serverRequestPayload.path |> UrlPath.toRelative
|
|
1048
1048
|
, contentJson = Dict.empty
|
|
1049
1049
|
, html = "This is intentionally blank HTML"
|
|
1050
1050
|
, errors = []
|