Учитывая простой пример, подобный этому
glyphicon :: Text -> Widget
glyphicon name = toWidget [hamlet|<span class="glyphicon glyphicon-#{name}">|]
foo :: ToMarkup a => a -> Widget
foo content = toWidget [hamlet|<div class="foo">#{content}</div>|]
Есть ли в Yesod встроенный механизм, который позволил бы мне выполнять как foo "some text"
, так и foo (glyphicon "pencil")
? Мне удалось обойти это, используя собственный класс типов, который преобразует как текст, так и виджет в виджет.
class MakeWidget a where
makeWidget :: a -> Widget
instance MakeWidget Widget where
makeWidget = id
instance MakeWidget Text where
makeWidget x = toWidget [hamlet|#{x}|]
glyphicon :: Text -> Widget
glyphicon name = toWidget [hamlet|<span class="glyphicon glyphicon-#{name}">|]
foo :: MakeWidget a => a -> Widget
foo content = toWidget [whamlet|<div class="foo">^{makeWidget content}</div>|]
но это кажется неправильным, тем более что я даже не могу сделать ^{foo "hello"}
из-за неоднозначных типов и вместо этого должен сделать ^{foo (T.pack "hello")}
.
Есть ли лучший способ встроить Text
и Widget
в другой Widget
?