The following:
instance View EditView where
html EditView { .. } = [hsx|
<nav>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href={PostsAction}>Posts</a></li>
<li class="breadcrumb-item active">Edit Post</li>
</ol>
</nav>
<h1>Edit Post</h1>
{renderForm post}
|]
is from the code for the Blog project in the Creating Your First Project section of the IHP guide.
I've mostly converted it from HSX to blaze-html here:
instance View EditView where
html EditView { .. } = do
H.nav $ do
H.ol ! A.class_ "breadcrumb" $ do
H.li ! A.class_ "breadcrumb-item" $ do
H.a ! A.href "PostsAction" $ do
"Posts"
H.li ! A.class_ "breadcrumb-item active" $ do
"Edit Post"
H.h1 "Edit Post"
renderForm post
The last bit I'm wondering about is this one:
<a href={PostsAction}>Posts</a>
If I do the following:
H.a ! A.href PostsAction $ do
"Posts"
I get this message:
• Couldn't match expected type ‘H.AttributeValue’
with actual type ‘PostsController’
• In the first argument of ‘A.href’, namely ‘PostsAction’
In the second argument of ‘(!)’, namely ‘A.href PostsAction’
In the expression: H.a ! A.href PostsActiontypecheck
PostsAction
Defined at /home/dharmatech/Dropbox/Documents/ihp-blog/blog/Web/Types.hs:13:7
What's a good way to pass PostsAction
to A.href
?
(If there are other ways to make the blaze-html expression more idiomatic, feel free to recommend as well. :-))
When I use the following, along the lines of what Willem suggested in his answer below:
instance View EditView where
html EditView { .. } = do
H.nav $ do
H.ol ! A.class_ "breadcrumb" $ do
H.li ! A.class_ "breadcrumb-item" $ do
H.a ! A.href (fromString (show PostsAction)) $ do
"Posts"
H.li ! A.class_ "breadcrumb-item active" $ do
"Edit Post"
H.h1 "Edit Post"
renderForm post
I get the following:
• Couldn't match type ‘Text’ with ‘[Char]’
Expected type: String
Actual type: Text
• In the first argument of ‘fromString’, namely
‘(show PostsAction)’
In the first argument of ‘A.href’, namely
‘(fromString (show PostsAction))’
In the second argument of ‘(!)’, namely
‘A.href (fromString (show PostsAction))’typecheck
Perhaps I need to import a Text
version of fromString
?
I've added the following import:
import Data.String(IsString(fromString))
However, the error message is the same:
• Couldn't match type ‘Text’ with ‘[Char]’
Expected type: String
Actual type: Text
• In the first argument of ‘fromString’, namely
‘(show PostsAction)’
In the first argument of ‘A.href’, namely
‘(fromString (show PostsAction))’
In the second argument of ‘(!)’, namely
‘A.href (fromString (show PostsAction))’typecheck
If I hover over show
the following signature is shown:
show :: forall a. Show a => a -> Text
And for fromString
:
fromString :: forall a. IsString a => String -> a
So I believe that's where the mismatch is.
This being a typical IHP view file, I have the following at the top for imports:
module Web.View.Posts.Edit where
import Web.View.Prelude
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as A
As the documentation on Inline Haskell says:
If the variable is another HSX expression, a blaze HTML element, a text or string: it is just included as you would expect.
If the variable is any other custom Haskell data structure: it will first be converted to a string representation by calling
show
on it. You can add a customToHtml
(import it fromIHP.HSX.ToHtml
) instance, to customize rendering a data structure.
So unless there was a ToHTML
in the [hsx|…]
quasiquoter for {PostAction}
, you thus should apply show
, next we call fromString :: IsString a => String -> a
to it to convert it to an AttributeValue
.
The code is thus equivalent to:
instance View EditView where
html EditView { .. } = do
H.nav $ do
H.ol ! A.class_ "breadcrumb" $ do
H.li ! A.class_ "breadcrumb-item" $ do
H.a ! A.href (fromString (show PostsAction)) $ do
"Posts"
H.li ! A.class_ "breadcrumb-item active" $ do
"Edit Post"
H.h1 "Edit Post"
renderForm post