Yesod: Гамлет и прочие

Приветствую!

Как вы уже знаете, в корне Yesod-проекта имеется каталог templates, содержащий шаблоны, в которых уютно расположились наши HTML, CSS и JS. Пришло время узнать обо всём об этом подробнее.

Гамлет

Шаблоны с расширением .hamlet - самые главные, ведь именно в них живёт HTML. Впрочем, не совсем обыкновенный HTML. Те из вас, кто знаком с Ruby on Rails, наверняка знают о Slim. Так вот Hamlet - это что-то в том же духе. Вот простейший пример:

<div .centered>
    Привет, это Hamlet, мета-язык для создания HTML!

После сборки нашего проекта этот код превратится в следующий HTML:

<div class="centered">
    Привет, это Hamlet, мета-язык для создания HTML!
</div>

А теперь о деталях.

Теги

Как вы заметили, в Hamlet-коде не нужно закрывать теги, это будет сделано за нас автоматически. И на мой взгляд, это чрезвычайно удобно. Ведь если не нужно вручную закрывать тег, то мы не сможем ни забыть этого сделать, ни сделать это криво. Взгляните:

<div .register>
    <div .just-centered>
        <h4>Ещё нет профиля?

        <div .register-button>
            <button type=button
                    .btn
                    .btn-primary
                    .btn-lg
                    #registerButton
                    data-toggle=modal
                    data-target=#registerForm>Зарегистрируйтесь

Но вы спросите, а как же задаётся вложенность тегов, если нет закрывающих? Очень просто: через отступы. В этом плане синтаксис Hamlet похож на синтаксис Haskell: отступы имееют значение. Поэтому если мы напишем так:

<div .register>
    <div .just-centered>
        <h4>Ещё нет профиля?

то HTML получится такой:

<div class="register">
    <div class="just-centered">
        <h4>Ещё нет профиля?</h4>
    </div>
</div>

Однако стоит нам убрать отступ:

<div .register>
<div .just-centered>
    <h4>Ещё нет профиля?

и HTML получится таким:

<div class="register"></div>
<div class="just-centered">
    <h4>Ещё нет профиля?</h4>
</div>

Кто-то скажет, мол, не такая уж и большая выгода получается: в чистом HTML-коде нужно внимательно следить за симметрией открывающих/закрывающих тегов, а в Hamlet нужно столь же внимательно следить за отступами. Но тут уж, как говорится, на ваш выбор. Лично мне больше нравятся отступы, ведь, работая с Haskell, я уже и так привык к их важности.

Классы и идентификаторы

Имена CSS-классов и идентификаторов задаются точно так же, как в самом CSS: классы через точку, а идентификаторы - через хэш. Во-первых, это сокращает код, а во-вторых, имена классов и идентификаторов можно не заключать в кавычки. Согласитесь, вот так:

<div .register>

выглядит красивее, нежели так:

<div class="register">

Кавычки

Как было сказано выше, в Hamlet кавычки можно опускать, за исключением случаев, когда они необходимы (например, при наличии пробелов в идентификаторе). Поэтому в коде моей Bootstrap-овской кнопки я пишу так:

<button ... data-toggle=modal

а не так:

<button ... data-toggle="modal"

Haskell-примочки

Мы можем запихнуть в Hamlet-код ряд особых программных конструкций, таких как условия, Maybe, forall и case. Более того, мы можем даже чистый Haskell использовать внутри Hamlet-кода. Однако писать об этом подробно сейчас я не стану, ведь всё это мы рассмотрим в будущих заметках, когда приступим к написанию реальных кусочков нашего проекта.

Интернационализация

Как я и обещал, в одной из будущих заметок мы подробно обсудим вопрос интернационализации нашего веб-приложения. А сейчас скажу следующее: Hamlet позволяет очень легко использовать мультиязыковой текст, заданный в каталоге messages.

Луций

Lucius - это мета-язык, предназначенный для написания CSS. Без стилей, сами понимаете, никуда, однако с Луцием всё значительно проще, нежели с Гамлетом. Как правило, шаблоны с расширением .lucius включают в себя самый обыкновенный CSS. Правда, есть несколько вкусностей.

Вложенность

Стилевые секции в Lucius могут быть вложенными. Таким образом, вместо того, чтобы писать так:

article code { background-color: #eee; }
article p { text-indent: 1.5em; }
article a { text-decoration: none; }

мы можем написать так:

article {
    code { background-color: #eee; }
    p { text-indent: 1.5em; }
    a { text-decoration: none; }
}

Переменные

Во избежание дубляжа, можно использовать особые переменные внутри .lucius-файлов. Например:

@bigSpace: 100px;

.register-block {
    padding-top: #{bigSpace};
}

.login-block {
    padding-top: #{bigSpace};
}

По мере продвижения по нашему проекту мы увидим всё это в действии.

Юлий

С Julius всё совсем просто. Шаблоны с расширением .julius содержат в себе нативный JS. Правда, там можно использовать несколько Haskell-овских примочек, но их значительно меньше, нежели в Hamlet. Поэтому пока воспринимайте .julius-файлы как обычные .js-файлы.

Ну вот собственно и всё. В последующих заметках всё, о чём было сказано выше, оживёт и заиграет. И в частности, вскоре мы узнаем об одной из фундаментальных концепций Yesod - о виджете.