Ограбление: Как вставить динамический список суб-шаблонов в шаблон? - PullRequest
6 голосов
/ 22 июля 2011

Я пишу сайт для онлайн-опросов. У меня есть список вопросов, которые все идут на одной странице HTML, и список имеет неизвестную длину. Каждый вопрос имеет форму, сохраненную в шаблоне qu1.tpl, а страница - qu.tpl. Теперь я хочу:

  1. заменить некоторые имена в qu1.tpl для каждого вопроса

  2. заменить некоторые вещи в qu.tpl один раз

  3. и вставьте все экземпляры qu1.tpl в qu.tpl

Используя то, что я узнал в этом уроке, я попытался рекурсивно заменить тег <qulist/> на <apply template="qu1.tpl"><qulist/> в qu.tpl, используя localHeist и bindString, но это не может работать, потому что qu.tpl уже отрендерено, поэтому вновь вставленный тег применения не разрешается.

что мне делать вместо этого?

(Полагаю, это более общий вопрос. Если вы можете подумать о других приложениях, к которым относится ответ, добавьте текст и теги для поисковых систем.)

Ответы [ 3 ]

4 голосов
/ 22 июля 2011

В Heist, когда вы делаете что-то, что включает вычисления для динамических данных, вы обычно будете использовать соединение Ваши первые две точки могут быть обработаны с помощью связующих соединений Что касается третьего пункта, я бы начал с создания функции сплайсинга, которая отображает конкретный шаблон вопроса. Это будет выглядеть примерно так:

questionSplice :: Monad m => Int -> Splice m
questionSplice n = do
  splices <- setupSplicesForThisQuestion
  mTemplate <- callTemplate (B.pack ("qu"++(show n))) splices
  return $ fromMaybe [] mTemplate

Теперь вы можете создать соединение для списка вопросов опроса:

surveyQuestions :: Monad m => Splice m
surveyQuestions = do
  questions <- getSurveyQuestions
  mapSplices questionSplice questions

Затем вы можете привязать это соединение к определенному тегу и использовать его где угодно в qu.tpl или любом другом шаблоне.

Важной частью здесь является функция callTemplate. Это функция Heist для рендеринга шаблонов из вычисления TemplateMonad. Я не думаю, что об этом много говорится в руководствах, потому что это не тот случай использования, которым обычно занимаются люди, и его легко пропустить в документации по API.

1 голос
/ 22 июля 2011

спасибо mightybyte за помощь в этом на irc. после 8 часов, в течение которых мне запретили отвечать на вопросы, вот мой вариант ответа:

  1. построить сплайс, который читает шаблон qu1.tpl, создает его экземпляр (то есть заполняет имя и номер вопроса в списке) и возвращает его. В этом вам поможет функция ограбления callTemplate. (этот сплайс называется сплайсексом в псевдокоде ниже.)

  2. напишите еще одно сращивание, которое сворачивает сплайсекс, чтобы вы получили список (созданных) вопросов вместо одного. (сращивание функции в псевдокоде.)

  3. использовать bindSplice вместо bindString.

псевдокод (протестирован, затем модифицирован и вырван из контекста) -

 ... -> let
          splice :: Monad m => Splice m
          splice = foldM (\ ts (s, i) ->
                             liftM ((++) ts) $ splicex (quName, quNumber))
                         []
                         (zip questionName [0..])

          splicex :: Monad m => (String, Int) -> Splice m
          splicex (quName, quNumber) =
              do
                mt <- callTemplate "qu1"
                        [ ("question-name", Data.Text.pack quName)
                        , ("question-number", Data.Text.pack $ show quNumber)
                        ]

                case mt of
                  Nothing -> error "splice rendering failed."
                  Just (t :: Template) -> return t
         in
           -- fill in the list of (instatiated) questions
           heistLocal (bindSplice "qulist" splice) $
           -- before that, instantiate the overall page
           instantiatePage $
           render "qu"

Кстати, мой аватар sourceforge слишком слаб, чтобы создавать новые теги. Кто-нибудь хочет пометить это с «ограблением»?

ссылки:

http://snapframework.com/

# канал моментальных снимков в сети IRC freenode.

http://snapframework.com/docs/tutorials/heist

0 голосов
/ 20 июля 2014

Когда я попытался выяснить циклы шаблонов, я несколько раз сталкивался с этим вопросом.К сожалению, все здесь, вероятно, устарело, версия 0.5 (или ниже), в то время как версия 0.6 (я полагаю) представила runChildrenWith.

Простой пример использования runChildrenWith:

list_test_entries.tpl:

<listTestEntries>
  <dt><testEntry/></dt>
  <dd>This is part of the repeated template</dd>
</listTestEntries>

Site.hs:

listTestEntriesHandler :: Handler App App  ()
listTestEntriesHandler = do
    results <- getData 
    renderWithSplices "list_test_entries"
        ("listTestEntries" ## listTestEntriesSplice results)

getData :: Handler App App [String]
getData = return ["1", "2", "3"]

listTestEntriesSplice  :: [String] -> I.Splice AppHandler
listTestEntriesSplice = I.mapSplices (I.runChildrenWith . listTestEntrySplice)

listTestEntrySplice :: Monad m => String -> Splices (HeistT n m Template)
listTestEntrySplice dataEntry = do
  "testEntry" ## I.textSplice (T.pack $ "data: " ++ dataEntry)

См. https://github.com/michaxm/heist-template-loop-demo для демонстрации работы.

...