ihp
ihp copied to clipboard
HSX Template compiling lambda functions
On upgrade to v0.20 some old hsx code with a lambda expression stopped compiling: Old code:
<input type="hidden" name="googlePlaceId" value={(\(PlaceId x) -> x)(place_id x)}/>
Error message:
• Exception when trying to run compile-time code:
IHP.HSX.HsExpToTH.toPat: not implemented: (PlaceId x)
CallStack (from HasCallStack):
error, called at ./IHP/HSX/HsExpToTH.hs:195:18 in ihp-hsx-0.18.0-5G7n5wCYmB1CeYaNqV7khQ:IHP.HSX.HsExpToTH
Code: Language.Haskell.TH.Quote.quoteExp
hsx
"\n\
\ <div id=\"google-result\" data-lat-lon={encode $ (location (geometry x))}> {formatted_address x} </div>\n\
\ <input type=\"hidden\" name=\"eircode\" value={eircode} />\n\
\ <input type=\"hidden\" name=\"geoCoords\" value={latlngParam x}/>\n\
\ <input type=\"hidden\" name=\"googlePlaceId\" value={(\\(PlaceId x) -> x)(place_id x)}/>\n\
\ <input type=\"hidden\" name=\"googleMapsJSON\" value={encode x}/>\n\
\ {siteNameInputField sitename}\n\
\ {submitButton {label=\"Confirm Location\"}}\n\
Fix: Move lambda expression out of HSX block and into where clause.
Also some selectField code no longer compiling:
{(selectField #goal (Nothing:userGoals)){disableLabel=True}}
Also ran into this issue:
renderForm :: Product -> Html
renderForm product = formFor product [hsx|
{(textField #name) { placeholder = "Product Model Name", required = True }}
{(textareaField #description) { labelClass = "font-medium text-gray-700", placeholder = "Short Generic Description" }}
{(selectField #category (Nothing:(map Just productCategories)))}
{(selectField #productManufacturerId (Nothing:(map Just manufacturers)))}
{(checkboxField #public) { fieldLabel = "Visible On Website?" }}
{(submitButton) { label = "Update" }}
|]
Error message:
Rebuilding...
[76 of 80] Compiling Admin.View.Products.New ( Admin/View/Products/New.hs, interpreted )
Done in 26ms.
Admin/View/Products/New.hs:28:50: error:
* Exception when trying to run compile-time code:
exact
CallStack (from HasCallStack):
error, called at ./IHP/HSX/HsExpToTH.hs:67:16 in ihp-hsx-0.18.0-5G7n5wCYmB1CeYaNqV7khQ:IHP.HSX.HsExpToTH
Code: Language.Haskell.TH.Quote.quoteExp
hsx
"\n\
\ {(textField #name) { placeholder = \"Product Model Name\", required = True }}\n\
\\n\
\ {(textareaField #description) { labelClass = \"font-medium text-gray-700\", placeholder = \"Short Generic Description\" }}\n\
\\n\
\ {(selectField #category (Nothing:(map Just productCategories)))}\n\
\\n\
\ {(selectField #productManufacturerId (Nothing:(map Just manufacturers)))}\n\
\\n\
\ {(checkboxField #public) { fieldLabel = \"Visible On Website?\" }}\n\
\\n\
\ {(submitButton) { label = \"Create\" }}\n\
\ "
* In the quasi-quotation:
[hsx|
{(textField #name) { placeholder = "Product Model Name", required = True }}
{(textareaField #description) { labelClass = "font-medium text-gray-700", placeholder = "Short Generic Description" }}
{(selectField #category (Nothing:(map Just productCategories)))}
{(selectField #productManufacturerId (Nothing:(map Just manufacturers)))}
{(checkboxField #public) { fieldLabel = "Visible On Website?" }}
{(submitButton) { label = "Create" }}
|]
|
28 | renderForm product = formFor product [hsx|
| ^^^^^...
[77 of 80] Compiling Admin.View.Products.Edit ( Admin/View/Products/Edit.hs, interpreted )
Admin/View/Products/Edit.hs:30:38: error:
* Exception when trying to run compile-time code:
exact
CallStack (from HasCallStack):
error, called at ./IHP/HSX/HsExpToTH.hs:67:16 in ihp-hsx-0.18.0-5G7n5wCYmB1CeYaNqV7khQ:IHP.HSX.HsExpToTH
Code: Language.Haskell.TH.Quote.quoteExp
hsx
"\n\
\ {(textField #name) { placeholder = \"Product Model Name\", required = True }}\n\
\\n\
\ {(textareaField #description) { labelClass = \"font-medium text-gray-700\", placeholder = \"Short Generic Description\" }}\n\
\\n\
\ {(selectField #category (Nothing:(map Just productCategories)))}\n\
\\n\
\ {(selectField #productManufacturerId (Nothing:(map Just manufacturers)))}\n\
\\n\
\ {(checkboxField #public) { fieldLabel = \"Visible On Website?\" }}\n\
\\n\
\ {(submitButton) { label = \"Update\" }}\n"
* In the quasi-quotation:
[hsx|
{(textField #name) { placeholder = "Product Model Name", required = True }}
{(textareaField #description) { labelClass = "font-medium text-gray-700", placeholder = "Short Generic Description" }}
{(selectField #category (Nothing:(map Just productCategories)))}
{(selectField #productManufacturerId (Nothing:(map Just manufacturers)))}
{(checkboxField #public) { fieldLabel = "Visible On Website?" }}
{(submitButton) { label = "Update" }}
|]
|
30 | renderForm product = formFor product [hsx|
| ^^^^^...
Failed, 75 modules loaded.
Working code:
renderForm :: Product -> Html
renderForm product = formFor product [hsx|
{(textField #name) { placeholder = "Product Model Name", required = True }}
{(textareaField #description) { labelClass = "font-medium text-gray-700", placeholder = "Short Generic Description" }}
{(selectField #category ([Nothing] ++ map Just productCategories))}
{(selectField #productManufacturerId ([Nothing] ++ map Just manufacturers))}
{(checkboxField #public) { fieldLabel = "Visible On Website?" }}
{(submitButton) { label = "Update" }}
|]
Working on this in branch A lot of type familes make it tricky to find the right mapping (ConPat -> Th.ConP).
The target code to get working is an infix list concatenation and a parenthesies wrapped data constructor for pattern matching with lambdas.
html WelcomeView = [hsx|
<p> <a href={NewSessionAction}> Login </a> </p>
<p> <a href={DeleteSessionAction}> Logout </a> </p>
{ renderGreetAdmin currentAdminOrNothing }
<form>
<!-- These work -->
{infixList}
<input type="hidden" name="googlePlaceId" value={unpackedPlaceData}/>
<!-- These don't -->
<!-- {1 : [2,3,42]} -->
<input type="hidden" name="googlePlaceId" value={(\(PlaceId x) -> x)(placeData)}/>
</form>
|]
where
placeData = PlaceId "Punches Cross"
infixList = (1 ::Int) : [2,3,42]
unpackedPlaceData = (\(PlaceId x) -> x) placeData
Fixed via https://github.com/digitallyinduced/ihp/pull/1535