Все привет, особенно Ziaw.
Особенно потому, что это идея в первую очередь адресуется ему как создателю НРельсов.
Я тут посмотрел
Lift (
фиговенький передов книги по нему) и нашел его идеи по рендеренгу (точнее его подход к реализации паттерна MVC) вполне милым, логичным для ФЯ и (что самое важное) легко реализуемым на базе макросов немерла.
В качестве средства упрощения работы с БД можно использовать
Nemerle on rails созданный Ziaw. Рельсы по всей видимости нужно еще доводить до ума, но как основа они точно потянут.
Остается только движок рендеренга HTML/XML-я и JSON. JSON опять же уже смастерил Ziaw.
Так вот чтобы получить действительно законченные Nemerle on rails нужно смастерить движок рендеренга HTML/XML.
Предлагаю повторить Lift (естественно, с учетом особенностей немерла).
Идея рендерера Lift очень проста. В качестве шаблонов используется чистых XML. Места в которых на сервере нужно вставить динамический контент помечаются специальными тегами. Например, если мы хотим в середине страницы вывести некий динамический контент, то можно оформить страничку так:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:lift="http://liftweb.net/">
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<title>demo.helloworld:helloworld:1.0-SNAPSHOT</title>
<script id="jquery" src="/classpath/jquery.js" type="text/javascript"></script>
</head>
<body>
<lift:bind name="content" />
<lift:Menu.builder />
<lift:msgs/>
</body>
</html>
Собственно вся идея заключается в размещении тегов-заместителей (плэйсхолдеров) вроде <lift:Menu.builder /> для указанию движку рендеренга мест в которые нужно вставить динамический контент.
В теге <lift:Menu.builder /> значение Menu.builder — это имя метода представления который и генерирует динамический контент. Другими словами это что-то вроде активных тегов JSP или Руби. Не трудно развить эту идею и передавать параметры таким тегам (в виде атрибутов тегов).
Метод вызываемый таким образом должен всего лишь возвращать XML в определенном форммте. Для нас это будет формат XElement (т.е. LinqToXml).
Этот метод волен пользоваться любыми средствами формирования тегов, но основным средством будет Nemerle.Xml — DSL позволяющий придать человеческое лицо LinqToXml-ю.
Очень важной особенностью таких тегов является то, что они могут появляться не только в шаблонах, но и том ХМЛ-е который возвращается методами заполняющими плэйсхолдеры (вроде упомянутого Menu.builder). Принцип действия очень похож на раскрытие макросов немерла. Движок раскрывает одни плэйсхолдер подставляя вместо него содержимое сгенерированное указанным методом. Если в содержимом так же появляются плэйсхолдеры, то движок так же происходит их раскрытие. И так до тех пор пока в результате не получится ХМЛ не содержащий ни одного активного тега.
Собственно последняя особенность и определяет рекурсивный дизайн и устраняет необходимость дублирования кода.
Кто-то может спросить — "А где же здесь контролер?" — и я отвечу — здесь его нет и здесь он не нужен. Но это не значит, что его не будет совсем. Контроллер остается для: формирования сложных структур данных (тех что трудно получить одним запросом), для кэширования, для организации навигации и т.п. В случае когда контроллер формирует сложные наборы данных имеет смысл использовать модель Model <-> View Model, т.е. контроллер перепаковывает данные в View Model и далее во View используется уже эта копия. Это позволит формализовать трансформацию данных модели в данные которые удобно отображать пользователю.