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!"
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With