8

I'm trying to write a form that allows users to upload a file to my server. I saw Yesod uses fileAFormReq for such a functionality but was unable to get it to work, running into compilation errors, the latest of which was: "No instance for (RenderMessage MySite t)" Any stripped down example for how to use it will be highly appreciated. Thanks, Uri

Pieniadz
  • 653
  • 3
  • 9
  • 22
Uri Barenholz
  • 693
  • 3
  • 13
  • Hi Uri, just in case, I have written a little blog post on how to write a complete file upload (serving uploaded files, referencing them in Yesod and deleting them) https://ersocon.net/blog/2017/2/18/file-uploads-with-yesod – Alebon Feb 18 '17 at 13:33

1 Answers1

13

Update 13-Sep-2012:

There is an official maintained help page for file uploading here


Googling on the function fileAFormReq gave me this example.

I Made a minimal version of it with only the relevant parts.

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes, TypeFamilies, TemplateHaskell, MultiParamTypeClasses #-}
import Yesod.Core
import Yesod.Form
import Yesod.Form.MassInput
import Control.Applicative
import Data.Text (Text, pack)
import Network.Wai.Handler.Warp (run)
import Data.Time (utctDay, getCurrentTime)
import qualified Data.Text as T
import Control.Monad.IO.Class (liftIO)

mkYesod "HelloForms" [parseRoutes|
/file FileR GET POST
|]

data HelloForms = HelloForms

instance RenderMessage HelloForms FormMessage where
    renderMessage _ _ = defaultFormMessage

instance Yesod HelloForms where
    approot _ = ""


main = toWaiApp HelloForms >>= run 3000

fileForm = renderTable $ pure (,)
    <*> fileAFormReq "Required file"
    <*> fileAFormOpt "Optional file"

getFileR = do
    ((res, form), enctype) <- runFormPost fileForm
    defaultLayout [whamlet|
<p>Result: #{show res}
<form method=post enctype=#{enctype}>
    <table>
        ^{form}
    <tr>
        <td>
            <input type=submit>
|]

postFileR = getFileR

runhaskell this and then visit http://localhost:3000/file in your browser.

Hope this helps. :)


Edit:

Oh wait, it's obvious what you're missing. As the compilation error just said, you're missing a RenderMessage instance for your Foundation.

I know recent efforts for i18n have changed the forms-package slightly. If you're using the latest version of yesod, check this out.

The code I pasted uses the old non-i18n (default means english) version of yesod-forms package.

Tarrasch
  • 10,199
  • 6
  • 41
  • 57
  • 2
    Thanks.The missing instance error was actually a side-effect of me not using the fileAFormReq properly (Resulting in ghc expecting it to have another RenderMessage instance and not just the one you pointed out, which was very confusing). Anyway it works perfectly now, so thanks! – Uri Barenholz Sep 18 '11 at 10:54