I have a situation where I have to construct compiled splices and feed data into them which depends on the URL variable. I struggle to solve the problem.
So there is simple file name list that needs to be rendered in a table. Simple. Files belong to a group or category so you can list all files or related to a particular category. I pull data using this function:
getFilesList :: Maybe ByteString -> AppHandler [Document]
getFilesList cat = do
let selection = maybe [] (\c -> ["category" =: T.decodeUtf8 c]) cat
r <- eitherWithDB $ rest =<< find (select selection "files") {project = ["blob" =: 0]}
return $ either (const []) id r
If it gets Nothing it pulls the whole list if it gets Just category it pulls files that belongs to that category. Easy so far.
I call the above function from within a handler so that I can feed an argument into it.
listFiles :: AppHandler [Document]
listFiles = do
cat <- getParam "cat"
let r = maybe Nothing (\c -> if c == "all" then Nothing else Just c) cat
render "files/list-files"
getFilesList r
If I get "all" or Nothing on the URL - I get the full list. Anything other then that - I get a category filtered list.
The URL root looks like this
("/files/:cat", method GET listFiles)
But now I have a problem because the "method" function will only accept Handler App App () signature. My handler returns data to be fed into the splices.
I construct my splices like so:
listFilesS :: Splices (Splice (Handler App App))
listFilesS = "files" ## files
where
files = manyWithSplices runChildren file $ lift listFiles -- Feed data here
file = do
"file-name" ## (pureSplice . textSplice $ at "name")
"file-oid" ## (pureSplice . textSplice $ id)
"file-date" ## (pureSplice . textSplice $ dateFromDoc)
"file-size" ## (pureSplice . textSplice $ fsize)
"file-type" ## (pureSplice . textSplice $ at "type")
"file-auth" ## (pureSplice . textSplice $ const "admin")
"file-link" ## (pureSplice . textSplice $ flink)
"file-category" ## (pureSplice . textSplice $ at "category")
where id = T.pack . show . valueAt "_id"
fsize = T.pack . show . round . (flip (/) 1024) . (at "size")
flink = T.append "/files/" . id
I cannot find a way around it. Probably just missing something stupid. Any ideas what I am doing wrong?
In any case, my handler function looks incorrect since I render the template first and then pull the data. If I fix the handler then I cant feed the data based on the URL parameter.
Confused.