Vagif Verdi
Vagif Verdi

Reputation: 4896

Optional html attributes in Text.Blaze

Text.Blaze has an operator ! to add attributes to html:

option ! id "bla" ! value "1" ! selected "" $ "Hello!"

My question is how can i make attributes optional ? Right now my code is ugly:

option ! id "bla" ! value "1" ! (if x == val then selected "" else someStupidAttribute "")  $ "Hello!"

This leads to every html option element to have unnecessary irrelevant attribute just because i have to supply one.

EDIT: I accepted hammar's answer. I created a helper function:

(!?) :: Attributable h => h -> (Bool,Attribute) -> h
html !? (True, attr) = html ! attr
html !? _ = html

And here's how to use it:

option ! id "bla" ! value "1" !? ((k == val), selected "") $ "Hello!"

Upvotes: 3

Views: 559

Answers (4)

ondra
ondra

Reputation: 9331

This seems to work for me - mempty:

import Data.Monoid (mempty)
option ! id "bla" ! value "1" ! (if x == val then selected "" else mempty) $ "Hello!"

Upvotes: 0

Daniel Wagner
Daniel Wagner

Reputation: 152837

My favorite trick for pretty conditionals is using list comprehensions; [foo | x] will either evaluate to [foo] or []. Can we adapt this trick? Well, with a helper function that applies lists of attributes:

element !. options = foldr (!) element options -- (!.) = foldr (!)

Now you can write something relatively pretty like one of these two (depending on taste):

option ! id "bla" ! value "1" !. [selected "" | x == val] $ "Hello!"
option !. [id "bla", value "1"] ++ [selected "" | x == val] $ "Hello!"

You may have to add a fixity declaration for !.; you can use :i ! in ghci to see what you're trying to interoperate with.

Upvotes: 2

hammar
hammar

Reputation: 139850

How about defining a convenience operator to apply attributes conditionally?

(!?) :: Attributable h => h -> Maybe Attribute -> h
html !? (Just attr) = html ! attr
html !? Nothing = html

With this, you can write your example as follows.

option ! id "bla" ! value "1" !? toMaybe (x == val) (selected "") $ "Hello!"

Here, toMaybe is just a useful helper for building Maybe values, but you can use something else if you wish.

toMaybe :: Bool -> a -> Maybe a
toMaybe False _ = Nothing
toMaybe True  x = Just x

Upvotes: 5

dave4420
dave4420

Reputation: 47052

I don't know whether there is a better Blaze-specific way of doing this, and I know this isn't terribly readable, but you can do

(if x == val then (! selected "") else id) (option ! id "bla" ! value "1") $ "Hello!"

Upvotes: 0

Related Questions