Could not deduce ‘IHP.RouterSupport.AutoRoute

Hi,
I’m trying to add some image handling based on this blog: A resolution switching responsive images template with Haskell and IHP. I’m pretty comfortable with Haskell, but new to IHP. I put the deets below. Thanks.

I needed to modify it a bit but I put this in Helper/View.hs:

import Web.Types

renderImgFullWidth :: Text -> Html
renderImgFullWidth imgName = [hsx|
    <div style="--aspect-ratio:3/1;">
        <picture>
            <source media={imgHD} srcset={imgPathStaticHD imgName}/>
            <source media={imgBig} srcset={imgPathStaticBig imgName}/>
            <source media={imgMedium} srcset={imgPathStaticMedium imgName}/>
            <img src={imgPathStaticSmall imgName} class="image-full-width" alt={imgName}/>
        </picture>
    </div>
|]

And in Web/Types:

data ImgParams = ImgParams
    { minWidth :: Integer
    , filesize :: Integer
    } deriving (Show)

imgHD     :: ImgParams
imgHD      = ImgParams {minWidth = 1201, filesize = 1920}
imgBig    :: ImgParams
imgBig     = ImgParams {minWidth = 961, filesize = 1110}
imgMedium :: ImgParams
imgMedium  = ImgParams {minWidth = 768, filesize = 690}
imgSmall  :: ImgParams
imgSmall   = ImgParams {minWidth = 1, filesize = 545}

imgPathStaticHD     :: Text -> Text
imgPathStaticHD     imgName = "../img/" <> imgName <> "_" <> show (filesize imgHD)     <> ".png"
imgPathStaticBig    :: Text -> Text
imgPathStaticBig    imgName = "../img/" <> imgName <> "_" <> show (filesize imgBig)    <> ".png"
imgPathStaticMedium :: Text -> Text
imgPathStaticMedium imgName = "../img/" <> imgName <> "_" <> show (filesize imgMedium) <> ".png"
imgPathStaticSmall  :: Text -> Text
imgPathStaticSmall  imgName = "../img/" <> imgName <> "_" <> show (filesize imgSmall)  <> ".png"

Full error:

Application/Helper/View.hs:7:35
    • Could not deduce ‘IHP.RouterSupport.AutoRoute ImgParams’
        arising from a use of ‘IHP.HSX.Attribute.applyAttribute’
      from the context: ?context::ControllerContext
        bound by the type signature for:
                   renderImgFullWidth :: Text -> Html
        at Application/Helper/View.hs:6:1-34
    • In the expression:
        IHP.HSX.Attribute.applyAttribute
          (Data.Text.unpackCStringLen# "media"# (GHC.Types.I# 5#))
          (Data.Text.unpackCStringLen# " media=\""# (GHC.Types.I# 8#)) imgHD
      In the second argument of ‘IHP.HSX.QQ.applyAttributes’, namely
        ‘[IHP.HSX.Attribute.applyAttribute
            (Data.Text.unpackCStringLen# "media"# (GHC.Types.I# 5#))
            (Data.Text.unpackCStringLen# " media=\""# (GHC.Types.I# 8#)) imgHD,
          IHP.HSX.Attribute.applyAttribute
            (Data.Text.unpackCStringLen# "srcset"# (GHC.Types.I# 6#))
            (Data.Text.unpackCStringLen# " srcset=\""# (GHC.Types.I# 9#))
            (imgPathStaticHD imgName)]’
      In the expression:
        IHP.HSX.QQ.applyAttributes
          (IHP.HSX.QQ.makeParent
             (IHP.HSX.QQ.textToStaticString
                (Data.Text.unpackCStringLen# "source"# (GHC.Types.I# 6#)))
             (IHP.HSX.QQ.textToStaticString
                (Data.Text.unpackCStringLen# "<source"# (GHC.Types.I# 7#)))
             (IHP.HSX.QQ.textToStaticString
                (Data.Text.unpackCStringLen# "</source>"# (GHC.Types.I# 9#)))
             [])
          [IHP.HSX.Attribute.applyAttribute
             (Data.Text.unpackCStringLen# "media"# (GHC.Types.I# 5#))
             (Data.Text.unpackCStringLen# " media=\""# (GHC.Types.I# 8#)) imgHD,
           IHP.HSX.Attribute.applyAttribute
             (Data.Text.unpackCStringLen# "srcset"# (GHC.Types.I# 6#))
             (Data.Text.unpackCStringLen# " srcset=\""# (GHC.Types.I# 9#))
             (imgPathStaticHD imgName)]
  |
7 | renderImgFullWidth imgName = [hsx|

Maybe you can try this way of implementation - IHP Guide

The issue is in media={imgHD}. The imgHD variable is not of type Text but of type ImgParams. So it cannot be assigned to the HSX attribute.

I guess you need to add a helper function toMedia :: ImgParams -> Text like this:

toMedia ImgParams { minWidth } = "(min-width: " <> tshow minWidth <> "px)"

-- Then use it like this:
<source media={toMedia imgHD} srcset={imgPathStaticHD imgName}/>

cc @fritzfeger

Thanks. That makes sense.