1

I am trying to create dynamic links using the Heist templating system. The problem is that the links are appearing as text rather than being interpreted as html. Is there a specific method to create dyamic lists like this with Heist?

The function where the link is constructed:

renderCategories :: Monad m => Db.Category -> I.Splice m
renderCategories (Db.Category catid catname catdesc) =
  I.runChildrenWithText [ ("categoryId", T.concat $ ["<a    href='http://localhost:8000/thread_home?cateid=", T.pack . show $ catid, "'>", T.pack . show $ catid, "</a>"])
    , ("categoryName", catname)
    , ("categoryDesc", catdesc)]

The tag appears as "http://localhost:8000/thread_home?cateid=1'>1" text on the webpage. And the source shows it as follows:

&lt;a href='http://localhost:8000/thread_home?cateid=1'&gt;1&lt;/a&gt;

I figure that I need to have it print the actual < and > but I am not sure how to achieve this. As I am currently running runChildrenWithText to populate this Heist template changing to just runChildrenWith requires splices instead of text and so instead of attempting this I am hoping there is some way to runChildrenWithText without the '<' and '>' being converted to '&lt' and '&gt'. Any help is appreciated!

EDIT

I am trying to manually create the link using:

renderCategories :: Monad m => Db.Category -> I.Splice m
renderCategories (Db.Category catid catname catdesc) =
  I.runChildrenWith [ ("categoryId", return $ X.Element "a"[("href", "http://localhost")] $ X.TextNode (T.pack $ show catid))]

However I am encountering two errors:

Couldn't match type `X.Node' with `[X.Node]'
Expected type: I.Splice m
  Actual type: heist-0.11.1:Heist.Types.HeistT m m X.Node
In the expression:
  return
  $ X.Element "a" [("href", "http://localhost")]
    $ X.TextNode (T.pack $ show catid)

and

Couldn't match expected type `[X.Node]' with actual type `X.Node'
In the return type of a call of `X.TextNode'
In the second argument of `($)', namely
  `X.TextNode (T.pack $ show catid)'

I do not really understand these errors at the moment and any help is appreciated.

Working function for both returning the link and normal text:

renderCategories :: Monad m => Db.Category -> I.Splice m
renderCategories (Db.Category catid catname catdesc) =
I.runChildrenWith [( "categoryId", return $ [X.Element "a" [("href", T.concat $     ["http://localhost:8000/thread_home?cateid=", T.pack $ show catid] )] [X.TextNode (T.pack $  show catid)] ] )
, ("categoryName", I.textSplice catname)
, ("categoryDesc",  I.textSplice catdesc)]

1 Answers1

1

The behavior you are seeing is exactly what is intended. The reason you are having problems is because you're using runChildrenWithText which is a higher level function designed for situations where you are returning text nodes. It is meant for when you want that actual text on your page. What you are seeing is the correct way to achieve that.

A splice is a computation that returns a list of nodes.

type Splice n = HeistT n n [Node]

Node is a representation of the DOM as Haskell types, so if you want to return a link, you should do something like this:

return $ [Element "a" [("href", "http://localhost")] [TextNode (T.pack $ show catid)]]

To use this kind of a splice, you'll need to use runChildrenWith instead of runChildrenWithText.

If this manual creation of Nodes seems ugly to you, there's also a more convenient option. If you import the module Text.Blaze.Renderer.XmlHtml, you'll find functions there that let you generate Node trees using blaze-html syntax.

mightybyte
  • 7,282
  • 3
  • 23
  • 39
  • The error in your edit is because a splice has to return [Node], but I just returned Node. Also, I made the same mistake with the TextNode part. That should be a list as well. I've updated the answer. – mightybyte Aug 07 '13 at 19:21
  • Cheers still being a newbie when it comes to Haskell makes it difficult to clock on to such issues, hopefully it comes easier the more I do! –  Aug 07 '13 at 19:24
  • Yeah, it's tough at first. If you look at those error messages carefully, I think it's pretty easy to see what was going on. The compiler expected to see `[Node]`, but instead it saw `Node`. How do you fix that? Wrap it in a list. After awhile it gets easier. – mightybyte Aug 07 '13 at 19:30
  • It seems to work apart from not concatenating the number on to the end of the hyperlink. –  Aug 07 '13 at 19:31