Scala / Lift - попытка понять одновременное утверждение Lift об использовании действительного HTML и склонности к лифту: теги и перезапись тегов в рендере - PullRequest
12 голосов
/ 22 июня 2011

Все семь вещей (http://seventhings.liftweb.net/), безусловно, хороши, но я был особенно рад заявлению в шаблонах (http://seventhings.liftweb.net/templates)), что «Lift поддерживает шаблоны, дружественные для дизайнера».

В качестве одного из моих шагов в изучении способа работы Lift я пытаюсь создать простую форму создания объекта: взять несколько параметров, использовать их в качестве аргументов конструктора, а затем убрать объект. После некоторых исследований и экспериментов,У меня есть две проблемы:

  1. Кажется, существует значительная склонность к значительному переписыванию / украшению разметки шаблона во фрагментах.
  2. В формах, похоже, не используются действительные или распознаваемые элементы HTML.

На чем я основываю это:

Примеры форм / документация, похоже, посвящены специальным функциям: теги. Исследование подъема предполагает, что форма должна выглядеть следующим образом: (http://exploring.liftweb.net/master/index-6.html)

<lift:Ledger.add form="POST">
  <entry:description />
  <entry:amount /><br />
  <entry:submit />
</lift:Ledger.add>

Я не уверен, что это даже допустимый html5, и хотя он может быть действительным xhtml, он dНе кажется, что это соответствует духу того, что ваши шаблоны выглядят как настоящий html для наших дизайнерских друзей.Я читал где-то еще (не могу найти это снова), что у нас была возможность использовать фактические входные теги, но тогда мы не получили бы некоторые части причудливой формы Lift или что-то подобное, отрывок не был очень яснымо том, что именно я упустил бы, и примеры, кажется, не интересуют мое написание простой HTML-формы для создания простого HTML-сообщения.

Код для примера demo.liftweb.net (1) предлагаетчтобы ваш шаблон выглядел следующим образом (2)

<lift:surround with="default" at="content">
  <div class="lift:PersonScreen"></div>
</lift:surround>

Код фрагмента PersonScreen также не совсем светится (3).Есть несколько других примеров шаблона, который имеет, например, только тег ul в определенном месте только для генерации целой серии сложных li с вложенными элементами во фрагменте.Конечно, вы можете использовать xml в Scala, и он читается сносно, но он по-прежнему разбрасывает вашу разметку повсюду.Кажется, это нарушает дух «дружественных дизайнеров шаблонов».

Что я хочу понять.

Долгое время я строго придерживался двух правил в своемразработка веб-приложений:

  1. Нет разметки в 'коде' (контроллеры, бизнес-модели).
  2. Нет бизнес-логики в шаблонах.

Idiomatic Liftкажется, полностью отказаться от первого правила и полностью упустить значение второго правила.Эти правила хорошо послужили мне, и я не готов просто следовать за примерами, которые, кажется, нарушают их, не понимая, почему это не приведет к беспорядку.Я хочу понять, почему в Lift нормально генерировать столько кода для отображения во фрагментах.Я также хочу понять, почему хорошо, что разметка в шаблонах так редко отражает вывод.

То, что я (думаю) хочу:

Я хочу всемоя разметка с очень немногими исключениями, если они есть, в моих шаблонах.Я хочу, чтобы мои фрагменты выполняли минимальное искажение шаблона, обычно заменяя только текст элемента на «листовых» тегах и, возможно, настраивая значения атрибутов.Я думаю, что я сделал это для довольно сложного примера отображения, и я подозреваю, что мог бы использовать ту же технику для генерации ванильной HTML-формы, а затем обрабатывать параметры самостоятельно.Это то, что мне нужно сделать, если я хочу, чтобы мой шаблон выглядел как форма конечного результата?

Отклики и любые другие мысли, особенно по поводу понимания мышления Lift относительно этого материала, были бы чрезвычайно признательны.

Спасибо!

  1. http://demo.liftweb.net/simple_screen?F674431078927QJVVYD=_
  2. https://github.com/lift/examples/blob/master/combo/example/src/main/webapp/simple_screen.html
  3. https://github.com/lift/examples/blob/master/combo/example/src/main/scala/net/liftweb/example/snippet/Wizard.scala#L94

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

В ответ на @ OXMO456.(Спасибо за ответ.)

У меня есть, и они, кажется, только подтверждают мои опасения: Например, мы начинаем с:

Шаблоны лифта не содержат исполняемого кода.Это чистый, сырой, действительный HTML.

, что потрясающе.Потом позже:

Два последних механизма вызова фрагментов не приведут к действительным шаблонам Html5.

и все же, кажется, все используют первый из этих двух механизмов. Также написано:

В-третьих, разработчикам не нужно беспокоиться об обучении программированию чего-либо для проектирования HTML-страниц, потому что выполнение программы абстрагировано от HTML, а не встроено в HTML.

Но довольно последовательно примеры фрагментов, подобные тому, на который я ссылался в OP, генерируют разметку полностью программно. Это, кажется, противоречит целям (а) создания удобных для дизайнера шаблонов, поэтому разработчикам не нужно беспокоиться о разметке Freemarker и (б) отделении логики отображения от бизнес-логики.

Вторая ссылка полезна и поучительна, но она ясно дает понять, что это не The Lift Way. Тем не менее, похоже, что The Lift Way тянет весь фрагмент генерации разметки в фрагменты, что (я думаю) является огромным сочетанием разметки и бизнес-логики. Это Подъемный Путь?

Ответы [ 2 ]

18 голосов
/ 23 июня 2011

Это теги старого стиля, а не дизайнерские теги.

<lift:MySnippet>
  <b:field />
</lift:MySnippet>

становится

<div class="lift:MySnippet">
  <div class="field"></div>
</div>

Шаблоны Lift старого стиля являются действительным XML, а не XHTML - так что вы можетене имеет закрытых тегов или чего-либо еще - это отличает Lift от большинства фреймворков, которые обрабатывают шаблоны как необработанные строки с битами кода, переплетенными повсюду, независимо от тегов или структуры.

Кстати, в тегах старого стиля этивсе поля сфабрикованы - они не являются частью какого-то стандартного набора тегов Lift.Я мог бы так же легко сделать:

<lift:MySnippet>
  <frobnicate:blorb />
</lift:MySnippet>

, пока мой фрагмент кода ищет этот конкретный тег.

Лифт не позволяет любой логике в вашемшаблоны.Вся логика происходит в вашем классе Snippet.Так что для приведенного выше примера с дружественным дизайном у меня может быть такой фрагмент кода:

 class MySnippet { 
   def render(in: NodeSeq): NodeSeq = ".field" #> Text("some text here")
 }

, который даст такой результат:

 <div>
   <div class="field">some text here</div>
 </div>

Невозможно поместить какую-либо логику в Liftшаблоны - все, что они могут делать, это вызывать фрагменты Lift, которые являются обычными классами Scala, в которых выполняется вся работа.

Lift отменяет правило, согласно которому у вас не должно быть никакой логики отображения в вашем реальном коде.Зачем?Потому что это делает более многократно используемый код, потому что Scala имеет мощную поддержку XML, встроенную в язык, и потому что вся ваша логика теперь обрабатывается как обычный старый код Scala.

Если я определю фрагмент кода Lift с именем CurrentTime,Я могу просто перенести это в любой шаблон, и он будет отображать текущее время - в старых средах MVC каждый метод действия должен установить время как переменную страницы, а затем мои шаблоны нужно будет изменить, чтобы распечатать.Для более сложной логики, старые школьные рамки, вероятно, потребовали бы условия в шаблонах.Lift не позволяет этого - вся ваша логика представляет собой обычный код Scala, пригодный для рефакторинга, легко тестируемый и совместимый с современными IDE.

4 голосов
/ 24 июня 2011

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

Кроме того, поскольку Lift следует своей парадигме представления, единственное, что фактически требуется представлению, - это обозначение для контуракакие разделы разметки вы хотите обработать, в каких фрагментах рендеринга.Есть несколько способов, как показано на примере ОП и «Билла», но лично я предпочитаю:

<div lift="YourSnippet.method">
  <p>Some other code</p>
</div>

Это предпочтительнее, потому что тогда вы не культивируете атрибут класса, который (IMO) может бытьсбивает с толку дизайнеров.Lift может быть очень удобным для дизайнера, но я думаю, что главная проблема здесь в том, что вы должны быть дисциплинированными при написании своих фрагментов, игнорируя при этом многие из доступных сегодня образцов, которые смешивают Scala и разметку.

Вас может заинтересовать этот пост (http://blog.getintheloop.eu/2011/04/11/using-type-classes-for-lift-snippet-binding/);Используя этот тип шаблона, вы можете определить разделенные, повторно используемые части логики рендеринга, одновременно сохраняя свою бизнес-логику в безопасности от фрагментов.

Наконец, и не желая бесстыдно продвигать свой собственный продукт, я специально старался не использовать никакие смешанные xml-литералы Scala в моем примере кода для Lift in Action (кроме как для иллюстрации того, что это возможно).), так что, возможно, это будет полезно, если вы посмотрите на Лифт (http://manning.com/perrett/)

...