Доброго времени суток, Хабр! Если Вы давно хотели сделать себе, соседке или её собаке сайт, но пока не сделали, то эта статья для Вас! В этой серии статей я покажу основы работы с vibe для создания сайтов на примере простого блога.
В первой части мы разберём базовые моменты и добавим к получившемуся приложению шифрование. Итак у нас уже есть заготовка от Людвига и нам нужно расширить её. Первое что мы сделаем, это создадим класс нашего приложения и добавим пару страниц. Как можно заметить, метод getHome имеет UDA @path("/"), который указывает на то, что это корневая страница. UDA — user defined attributes — атрибуты объявляемые пользователем. По сути это любые объекты языка: enum'ы, структуры, простые типы данных. Используя сущьность, имеющую UDA мы можем проверить как наличие атрибута, его значение, а так же получить все поля и методы в классе/структуре, помеченные каким-то UDA. vibe, в данном случае, использует это для построения кода роутинга. Метод getPage2 использует соглашение именования и будет отрабатывать по get запросу по пути http://127.0.0.1:8080/page2. Таким же образом себя будут вести @property методы. Сейчас методы своей сигнатурой не отличаются от функции hello в шаблоне и пишем мы тела страниц руками. Не комильфо, добавим представлений в папку views и сразу по уму. Создадим несколько файлов: Шаблон для всех страниц сайта Отступы комментариев должны соответствовать отступам блоков. Комментарии попадают в результирующий html, если Вы этого не хотите используйте // - (со знаком минус). Тут будет шапка сайта Тут будет подвал сайта Главная страница, первой строкой мы указываем какой шаблон хотим расширять (без пути, ибо в той же папке и без расширения .dt) Вторая страница аналогична главной И поправим код нашего блога Стало лаконичней, нам не нужно теперь напрямую писать тело ответа. Добавим стиля! Нужно включить раздачу статических файлов в нашем приложении И, наконец, добавить стиль в head нашего layout.dt После сборки и запуска должно выглядеть примерно так: 
Не особо, но, надеюсь, что глаза не выпадают и с этим будет уже приятней работать) У нас появился какой-то базис, теперь пора задуматься о дальнейшем развитии. И прежде чем добавлять какую-либо функциональность позаботимся о безопасности: добавим шифрование. О создании сертификатов можно найти много информации, например. Тут приведу основные шаги без описания: openssl genrsa -out rootCA.key 2048 openssl req -x509 -new -key rootCA.key -days 9999 -out rootCA.crt
Ответы на вопросы не важны, мы заставим наш браузер ему доверять) openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 9998
Добавляем в браузер rootCA.crt, rootCA.key содержим в тайне. Теперь включим шифрование в нашем приложении. Теперь, если Вы всё сделали правильно, сайт перестанет быть доступным по http и станет доступным без вопросов по https. Для начала создадим сессию в нашем приложении. Добавим немного кода. Вне нашего класса будет тип переменной сессии. Для неразрывного восприятия, наверное, будет лучше показать новый класс целиком. Все публичные методы класса попадают в роутинг, поэтому ensureAuth создан как private. При этом vibe'у нужно знать об этом методе для его вызова перед помеченными @auth методами, поэтому нужно использовать mixin PrivateAccessProxy. Атрибут @auth создаётся с помощью шаблона before, выполняя роль хука, вызывает указанную функцию до помеченной и передаёт ей в качестве аргумента результат функции хука. Так же существует @after, который заставит выполняться функцию после и требует чтобы хук-функция принимала в качестве аргумента рузультат помечаемой. К сожалению документации я не нашёл на сайте vibe, но в код документация по этим моментам есть. Так же мы переименовали (удалили) метод page2. На его место встал getWritepost, который будет возвращать страницу создания новой записи. Также следует немного доработать остальные файлы. В views/layout.dt вставить блок, который будет содержать отображение ошибки block error (в layout он будет вставляться из других файлов) В views/index.dt добавить блок отображения ошибок, он может выглядеть так Как Вы, скорее всего, поняли после знака '-' должен идти код на D, а #{value} экранирует и вставляет в html значение переменной value.  Создать файл views/logindesk.dt, куда добавить форму для логина Необходимо внимательно относится к отступам, они работают как в python (а тут форматирование иногда ест пробелы). В файле views/index.dt изменить блок main Переменные settings и error передаются в шаблон функцией render!("index.dt", settings, error); в методе getHome. Каждый темплейт представления принимает свой набор переменных. Теперь у нас есть сайт, на котором можно залогиниться и есть страница на сайте (writepost), на которую нельзя перейти, если не залогинен. Статья и так получилась достаточно объёмной, но хочется довести её до какой-то логической запятой)
Добавим запись новых статей в обычное поле класса, а тип поля будет массив структур Добавляем в наш класс этот массив, передаём его в параметрах в функцию render метода getHome и добавляем метод, записывающий эти посты в массив. Будьте внимательны — имена параметров методов должны совпадать с именами полей формы! Осталось главное изменение, которое позволит нам видеть посты. В файле views/index.dt заменим запись "Контент" на код К этому моменты у Вас уже должно быть создано приложение в котором есть: У меня получилось так: 
Исходники этой части лежат тут. В следующих частях я расскажу как использовать mongo, сделать страницы для постов (url будет содержать индекс или имя поста) и коментирование, покажу более адекватную авторизацию и ещё некоторые мелочи. Пишите в коментариях что было не до конца ясно, буду рад доработать эту часть. Программист