Haskell Snap Framework - динамические гиперссылки с Heist

Я пытаюсь создать динамические ссылки, используя систему шаблонов Heist. Проблема в том, что ссылки отображаются в виде текста, а не интерпретируются как HTML. Есть ли какой-то особый метод для создания двойных списков с помощью Heist?

Функция, где создается ссылка:

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)]

Тег отображается как текст "http://localhost:8000/thread_home? Cateid=1'>1" на веб-странице. И источник показывает это следующим образом:

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

Я полагаю, что мне нужно, чтобы он напечатал фактические <и>, но я не уверен, как этого добиться. Поскольку в настоящее время я запускаю runChildrenWithText, чтобы заполнить этот шаблон Heist, изменив его только на runChildrenWith, требующий сращивания вместо текста, и поэтому вместо попытки этого я надеюсь, что есть какой-то способ runChildrenWithText без преобразования "<" и ">" в ​​"& lt" и '& gt'. Любая помощь приветствуется!

РЕДАКТИРОВАТЬ

Я пытаюсь вручную создать ссылку, используя:

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))]

Однако я сталкиваюсь с двумя ошибками:

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)

а также

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)'

Я не очень понимаю эти ошибки в настоящее время, и любая помощь приветствуется.

Рабочая функция для возврата ссылки и обычного текста:

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 ответ

Решение

Поведение, которое вы видите, это именно то, что задумано. Причина, по которой у вас возникают проблемы, заключается в том, что вы используете runChildrenWithText это функция более высокого уровня, предназначенная для ситуаций, когда вы возвращаете текстовые узлы. Он предназначен для того, когда вы хотите, чтобы этот фактический текст на вашей странице. То, что вы видите, является правильным способом достижения этого.

Сращивание - это вычисление, которое возвращает список узлов.

type Splice n = HeistT n n [Node]

Node является представлением DOM в виде типов Haskell, поэтому, если вы хотите вернуть ссылку, вы должны сделать что-то вроде этого:

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

Чтобы использовать этот вид соединения, вам нужно использовать runChildrenWith вместо runChildrenWithText,

Если это ручное создание Node Это кажется вам уродливым, есть и более удобный вариант. Если вы импортируете модуль Text.Blaze.Renderer.XmlHtml, вы найдете там функции, которые позволяют генерировать Node деревья, используя синтаксис Blaze-HTML.

Другие вопросы по тегам