Статьи

Ruby Templating With Slim: Часть 2

Во второй и последней части этой мини-серии мы завершим это введение разделами о выводе кода Ruby, интерполяции, обычном тексте и о том, как настроить Slim в соответствии с вашими потребностями. После этой статьи вы должны быть готовы к небольшому действию Slim.

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

1
2
3
4
5
6
html
 head
   title
   = stylesheet_link_tag ‘application’, media: ‘all’, ‘data-turbolinks-track’ => true
   = javascript_include_tag ‘application’, ‘data-turbolinks-track’ => true
   = csrf_meta_tags

Как вы можете видеть, внутри этого тега head мы уже использовали несколько методов из Rails для работы со стилями и JavaScript — ничего особенного. Все, что вам нужно сделать, чтобы выполнить код Ruby, это добавить его к знаку равенства = . Если ваш код должен распространяться на несколько строк, просто добавьте обратную косую черту \ в конце каждой строки и переходите к следующей. Если вы заканчиваете строку запятой, то вам не нужен обратный слеш. Приятное прикосновение, если вы спросите меня.

Давайте посмотрим на другой, более конкретный пример. Написание форм часто является проблемой — много шаблонного кода, много повторений и все эти страшные знаки <%= %> в ERB. Это может стать грязным в кратчайшие сроки. Может быть лучше, а?

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
<%= form_for @agent do |f|
 
  <%= f.label :name %>
  <%= f.text_field :name %>
 
  <%= f.label :number %>
  <%= f.text_field :number %>
 
  <%= f.label :licence_to_kill %>
  <%= f.check_box :licence_to_kill %>
 
  <%= f.label :gambler %>
  <%= f.check_box :gambler %>
 
  <%= f.label :womanizer %>
  <%= f.check_box :womanizer %>
 
  <%= f.submit %>
 
<% end %>

Много чего написать для создания нового объекта @agent , не так ли? Slim позволяет вам справиться с этим гораздо более кратко. Мы просто держим знак равенства и избавляемся от большинства других вещей. Tadaa!

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
= form_for @agent do |f|
 
 = f.label :name
 = f.text_field :name
 
 = f.label :number
 = f.text_field :number
 
 = f.label :licence_to_kill
 = f.check_box :licence_to_kill
 
 = f.label :gambler
 = f.check_box :gambler
 
 = f.label :womanizer
 = f.check_box :womanizer
 
 = f.submit

Вы можете ясно видеть, почему этот проект называется Slim. Так много лишнего жира ушло. Не говори мне, что тебе не нравится то, что ты видишь — я знаю, что ты копаешь это! Просто знак = и вы можете заполнить вашу разметку кодом Ruby — в данном случае, конечно, из Rails. И когда вы сравниваете его с HTML-кодом, представленным на последней странице, трудно игнорировать, насколько компактным на самом деле является Slim.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<form action=»/» accept-charset=»UTF-8″ method=»post»><input name=»utf8″ type=»hidden» value=»&#x2713;»
 
  <input type=»hidden» name=»authenticity_token» value=»+P2I801EkEVBlsMgDo9g9/XgwwQfCBd1eoOBkFmgAHE4bxYi9HGUjEjsNwNMnEadV2tbDtYvQhFb4s/SNMXYtw==» />
 
  <label for=»agent_name»>Name</label>
  <input type=»text» name=»agent[name]» id=»agent_name» />
 
  <label for=»agent_number»>Number</label>
  <input type=»text» name=»agent[number]» id=»agent_number» />
 
  <label for=»agent_licence_to_kill»>Licence to kill</label>
  <input name=»agent[licence_to_kill]» type=»hidden» value=»0″ />
  <input type=»checkbox» value=»1″ name=»agent[licence_to_kill]» id=»agent_licence_to_kill» />
 
  <label for=»agent_gambler»>Gambler</label>
  <input name=»agent[gambler]» type=»hidden» value=»0″ />
  <input type=»checkbox» value=»1″ name=»agent[gambler]» id=»agent_gambler» />
 
  <label for=»agent_womanizer»>Womanizer</label>
  <input name=»agent[womanizer]» type=»hidden» value=»0″ />
  <input type=»checkbox» value=»1″ name=»agent[womanizer]» id=»agent_womanizer» />
 
  <input type=»submit» name=»commit» value=»Save Agent» />
 
</form>

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

Этот фрагмент ERB …

1
<%= render «shared/agents», collection: @agents %>

… Становится таким в Слиме:

1
= render «shared/agents», collection: @agents
01
02
03
04
05
06
07
08
09
10
11
<h2>Agents</h2>
 
<ul>
  <% @agents.each do |agent|
    <li class=’agent’>
      <div>Name: <%= agent.name %></div>
      <div>Number: <%= agent.number %></div>
      <div>Licence to kill: <%= agent.licence_to_kill %></div>
    </li>
  <% end %>
</ul>
01
02
03
04
05
06
07
08
09
10
11
12
13
h2 Agents
ul
  — @agents.each do |agent|
    li.agent
      div
        |
        = agent.name
      div
        |
        = agent.number
      div
        |
        = agent.licence_to_kill

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

1
2
3
4
5
6
7
h2 Agents
ul
  — @agents.each do |agent|
    li.agent
      div Name: #{agent.name}
      div Number: #{agent.number}
      div Licence to kill: #{agent.licence_to_kill}

Я упоминал об этом раньше кратко, но, поскольку это форма вывода кода Ruby, он также относится к этому разделу. Конечно, вы можете использовать стандартную интерполяцию текста из Ruby в своих шаблонах Slim.

1
2
3
h2 Welcome Mr. #{misix_agent.surname}!
 
h2 Welcome Mr. \#{misix_agent.surname}!
1
2
3
4
5
6
7
<h2>
  Welcome Mr. Bond!
</h2>
 
<h2>
  Welcome Mr. \#{misix_agent.surname}!
</h2>

Как видно выше, простой ведущий обратный слеш \ избегает интерполяции.

Еще один для дороги. Допустим, вы хотите использовать пару условных выражений в своем представлении. Подобно Haml, вы обозначаете код Ruby, который не должен выводиться на страницу простым тире - . Вы видели это в приведенном выше примере, где мы использовали это для перебора @agents без отображения конкретной части кода.

Хотя вы должны стараться избегать всевозможных условных выражений в своих представлениях, где это возможно, и пытаться найти лучшие ООП-решения для таких случаев — что является историей для другого времени — они будут выглядеть примерно так:

01
02
03
04
05
06
07
08
09
10
— if current_user.role == «admin»
  p#admintxt |
  = link_to «Edit Profile», edit_user_path(:current)
  = link_to «Logout», logout_path
— elsif current_user
  = link_to «Edit Profile», edit_user_path(:current)
  = link_to «Logout», logout_path
— else
  = link_to «Register», new_user_path
  = link_to «Login», login_path
01
02
03
04
05
06
07
08
09
10
11
<% if current_user.role == «admin» %>
  <p id=»admintxt»>Welcome back my master!</p>
  <%= link_to «Edit Profile», edit_user_path(:current) %>
  <%= link_to «Logout», logout_path %>
<% elsif current_user %>
  <%= link_to «Edit Profile», edit_user_path(:current) %>
  <%= link_to «Logout», logout_path %>
<% else %>
  <%= link_to «Register», new_user_path %>
  <%= link_to «Login», login_path %>
<% end %>

Если вы хотите вывести код без экранирования HTML, просто используйте два знака равенства == . Это оно!

Прежде чем мы продолжим, я определенно должен уделить время, чтобы упомянуть об этом: как вы, наверное, знаете, тонны кода представления — или тонны кода Ruby в нашем контексте — являются серьезным запахом и должны быть минимизированы в любое время. То, что Slim делает еще более заманчивым наложение ваших шаблонов тоннами логики, не означает, что вам следует это делать. Практика ограничения в этом отделе! Сделано правильно, с другой стороны, Slim делает действительно элегантным вводить Ruby, где это необходимо.

Если вы чувствуете необходимость писать HTML в ваших шаблонах Slim, у вас есть возможность. Я не использовал эту функцию и не хотел бы использовать ее, но, возможно, на переходном этапе это может быть полезно для новичков. Давайте посмотрим супер быстро.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
doctype html
<html>
  head
    title = full_title(yield(:title))
    = stylesheet_link_tag ‘application’, media: ‘all’, ‘data-turbolinks-track’ => true
    = javascript_include_tag ‘application’, ‘data-turbolinks-track’ => true
    = csrf_meta_tags
  <body>
    header.navbar
      .logo
        = link_to «sample app», ‘root_path’, id: «logo»
        <nav>
          ul.navbar-right
            li
              = link_to «Home», ‘root_path’
            li
              = link_to «Help», ‘help_path’
            li
              = link_to «Log in», ‘login_path’
        </nav>
    .main
      = yield
  </body>
</html>

Когда Слим встречает левую угловую скобку < , он знает, что вы хотите смешать какой-то HTML.

Символ трубы | сообщает Slim, что вы хотите получить простой текст — слово в слово — и просто копирует строку. По сути, это позволяет избежать любой обработки. В документации сказано, что если вы хотите записать дословный текст в несколько строк, вы должны делать отступ текста с каждым разрывом строки.

1
2
3
4
body
 p
   |
     Slim is my new best friend.
1
2
3
4
5
<body>
  <p>
    Slim is my new best friend.
  </p>
</body>
Screenshot of the templates output

Если вы поместите текст в ту же строку, что и символ канала, вы можете установить левое поле после канала плюс один пробел. Из любопытства я немного обманулся и нашел следующие результаты. Только последний вариант варианта имеет небольшой очевидный сбой, о котором вы должны знать: он проглатывает первое слово предложения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
body
 p
   |
     This line is on the left margin.
      This line will have one space in front of it.
        This line will have two spaces in front of it.
           And so on…
 
 p
   |
      This line will have one space in front of it.
        This line will have two spaces in front of it.
           And so on…
 
 p This line is on the left margin.
      This line will have one space in front of it.
        This line will have two spaces in front of it.
           And so on…
 
 p This line is on the left margin.
   This line will have one space in front of it.
   This line will have two spaces in front of it.
   And so on…
 
 p
   This line is on the left margin.
   This line will have one space in front of it.
   This line will have two spaces in front of it.
   And so on…
Screenshot of the output by the above source code

То, как вывод выводится в вашу HTML-разметку, немного отличается.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<body>
   <p>
     This line is on the left margin.
      This line will have one space in front of it.
        This line will have two spaces in front of it.
           And so on…
   </p>
 
   <p>
     This line is on the left margin.
      This line will have one space in front of it.
        This line will have two spaces in front of it.
          And so on…
   </p>
 
   <p>
     This line is on the left margin.
        This line will have one space in front of it.
          This line will have two spaces in front of it.
            And so on…
   </p>
 
   <p>
     This line is on the left margin.
     This line will have one space in front of it.
     This line will have two spaces in front of it.
     And so on…
   </p>
 
   <p>
     <This>line is on the left margin.</This><This>line will have one space in front of it.</This><This>line will have two spaces in front of it.</This><And>so on…</And>
   </p>
 </body>

Конечно, необходимо периодически комментировать ваш код. Не забывайте, однако, что слишком много комментариев также являются запахом. Просто постарайтесь свести это к абсолютному минимуму!

Косая черта / — это все, что вам нужно, чтобы закомментировать любой код.

1
2
3
4
5
6
body
 /p
   |
      This line will have one space in front of it.
        This line will have two spaces in front of it.
          And so on…

Boom! И теперь этот абзац исчез со страницы. Этот комментарий не оставляет следов в окончательной разметке HTML. Вам просто нужно применить его к родительскому селектору, и все его дочерние элементы также будут закомментированы. Таким образом, даже комментарии невелики и минимальны.

С другой стороны, если вам нужен HTML-комментарий <!-- --> который отображается в окончательном отображаемом выводе, вам просто нужно добавить восклицательный знак ! после косой черты

1
2
3
4
5
6
body
 /!p
   |
      This line will have one space in front of it.
        This line will have two spaces in front of it.
          And so on…
1
2
3
4
5
6
<body>
 <!—p
     |
       This line will have one space in front of it.
         This line will have two spaces in front of it.
           And so on…—>

Ухоженная!

Мы все время использовали ярлыки. Когда вы набираете точку . или символ хеша # вы говорите Slim, что хотите использовать предопределенные ярлыки для классов и идентификаторов. Это, безусловно, очень хороший вариант по умолчанию, но что вы можете сделать, чтобы расширить его и создать свои собственные небольшие фрагменты фрагментов? Мы можем сделать это для тегов и атрибутов. Добро пожаловать в удивительный Slim!

В Rails нам просто нужно настроить инициализатор со следующим шаблоном:

1
Slim::Engine.set_options shortcut: {‘c’ => {tag: ‘container’}, ‘#’ => {attr: ‘id’}, ‘.’

В приложениях Sinatra вы просто добавляете ту же конфигурацию в любом месте ниже линии, где вам require 'slim' .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
require ‘sinatra’
require ‘slim’
 
Slim::Engine.set_options shortcut: {‘c’ => {tag: ‘container’}, ‘#’ => {attr: ‘id’}, ‘.’
 
get(‘/’) { slim :index }
 
__END__
 
@@ index
doctype html
html
  head
    title Slim Templates
    body
      h1 Boss Level Templates With Slim

Вы можете установить параметры в Slim :: Engine, предоставив хэш с нужным вам ярлыком. В приведенном выше примере мы указали Slim использовать c в качестве ярлыка для тега container . Вы бы использовали это в своих файлах Slim:

1
c.content Now you have a container tag with a .content class.

И обработанный HTML будет выглядеть, конечно, так:

1
2
3
<container class=»content»>
  Now you have a container tag with a .content class.
</container>

Довольно мило, а? Но ты не думал, что на этом музыка останавливается? Мы можем пойти дальше этого. Позвольте мне привести пример, который немного более сложный:

1
2
3
4
5
6
7
8
Slim::Engine.set_options shortcut: {
           ‘#’ => {attr: ‘id’},
           ‘.’
           ‘c’ => {tag: ‘container’},
           ‘&’ => {tag: ‘input’, attr: ‘type’},
           ‘@’ => {attr: ‘role’},
           ‘^’ => {attr: %w(data-role role)}
          }

В этом примере я не только создал пользовательские теги, но и предоставил удобные пользовательские атрибуты. Давайте рассмотрим это шаг за шагом. Кстати, я разбил хэш опций на несколько строк, чтобы сделать его читаемым и избежать длинной строки кода, на которую никто не любит наткнуться. Читает намного приятнее, тебе не кажется?

Посредством символа амперсанда & теперь мы можем создать входной тег, и нам просто нужно передать ему тип, который следует сразу за амперсандом. Мы можем использовать любой символ, который имеет смысл использовать; нет необходимости использовать тот же, который я сделал. Будьте осторожны и постарайтесь принимать бескомпромиссные решения в этом отделе.

1
2
3
&text name=»user»
&password name=»pw»
&submit
1
2
3
<input name=»user» type=»text»>
<input name=»pw» type=»password»>
<input type=»submit»>

Когда вы вносите изменения в этот инициализатор с помощью пользовательских ярлыков, не забудьте перезагрузить локальный сервер. Без этого ваши изменения не будут отражены во время предварительной обработки.

Далее, если мне нужен атрибут role , теперь я могу просто поставить его перед символом @ .

1
.person@admin Daniel Mendler
1
2
3
<div class=»person» role=»admin»>
  Daniel Mendler
</div>

Обновление: атрибут role — это семантический подход для описания роли рассматриваемого элемента — если вам необходимо определить назначение элемента.

Видите ли, через точку мы получаем class="person" а @admin дал нам role="admin" . Довольно удобный денди, но мы можем сделать еще один маленький шаг и использовать массив, чтобы указать несколько атрибутов, которые должны быть созданы с помощью одного ярлыка.

1
.nifty^hacker CrackDoctor
1
2
3
<div class=»nifty» data-role=»hacker» role=»hacker»>
  CrackDoctor
</div>

Поскольку мы связали массив атрибутов для нашего ярлыка ^ , Slim создает атрибуты data-role и role одновременно с помощью одного символа. Это может пригодиться. Представьте, что вы хотите вывести элемент, подобный следующему, и можете сделать это кратко с помощью ярлыка и некоторого кода Ruby.

1
<source src=»track1.mp3″ type=»audio/mpeg» data-duration=»1min5secs» data-tempo=»125bpm» data-artist=»The Beatles» />

Написание всего этого вручную, кажется, не лучшее использование вашего времени — у нас есть код, чтобы выполнить эту работу за нас. Ну, вот и все, это все, что вам нужно знать, чтобы создать свой собственный набор потрясающих ярлыков или создать большой беспорядок, когда вы не практикуете немного ограничений. Я бы рекомендовал не зацикливаться на этом — особенно старайтесь избегать определения ярлыков, которые используют символы, к которым уже прикреплен Slim.

Обновление: атрибуты данных используются, чтобы иметь некоторые личные данные на вашей странице или в приложении. Материал, который помогает вам фильтровать контент, например. Это пользовательские атрибуты, которые можно использовать для всех элементов HTML. Использование их в целях JavaScript — еще одна распространенная практика. Это также очень удобно для тестирования элементов на странице, если вы хотите убедиться, что определенные элементы отображаются, и вы не хотите, чтобы дизайнеры связывались с вашими стилями.

Перед тем как уйти, я хотел показать вам немного заглянуть в обширные параметры конфигурации и то, как вы их применяете. Для Rails вы должны создать файл среды, такой как config/environments/development.rb и указать нужные параметры. Вы просто размещаете свою конфигурацию в каком-то месте внутри блока Rails.application.configure .

01
02
03
04
05
06
07
08
09
10
Rails.application.configure do
  Slim::Engine.set_options default_tag: ‘p’,
                           tabsize: 2,
                           attr_list_delims: {‘(‘ => ‘)’,
                                              ‘[‘ => ‘]’,
                                              ‘{‘ => ‘}’,
                                              ‘«’ => ‘»’,
                                              ‘‹’ => ‘›’
                                              }
end

В этой конфигурации я удостоверился, что тег по умолчанию, который создается, если имя тега опущено, является <p> не тегом div , который является стандартным параметром. Кроме того, я настроил размер вкладки, чтобы использовать два пробела, и, наконец, добавил еще два разделителя для обтекания атрибутов тегов. Теперь я могу использовать ‹ › и « » для этого. Не очень полезно, но хорошо для демонстрационных целей.

В приведенном ниже примере вы можете видеть, что все разделители для оболочек атрибутов создают одинаковые выходные данные, а также .some-class или #some-id создают теги <p> по умолчанию.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
body
 #zeroth
 a{href=»http://slim-lang.com» title=’Home page’} Goto the home page
 
 .first
 a[href=»http://slim-lang.com» title=’Home page’] Goto the home page
 
 .second
 a(href=»http://slim-lang.com» title=’Home page’) Goto the home page
 
 .third
 a‹href=»http://slim-lang.com» title=’Home page’› Goto the home page
 
 .fourth
 a«href=»http://slim-lang.com» title=’Home page’» Goto the home page
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<body>
    <p id=»zeroth»></p>
    <a href=»http://slim-lang.com» title=»Home page»>Goto the home page</a>
 
    <p class=»first»></p>
    <a href=»http://slim-lang.com» title=»Home page»>Goto the home page</a>
 
    <p class=»second»></p>
    <a href=»http://slim-lang.com» title=»Home page»>Goto the home page</a>
 
    <p class=»third»></p>
    <a href=»http://slim-lang.com» title=»Home page»>Goto the home page</a>
 
    <p class=»fourth»></p>
    <a href=»http://slim-lang.com» title=»Home page»>Goto the home page</a>
</body>

В качестве альтернативы вы также можете установить этот материал в config/initializers/slim.rb как я показал вам в разделе о пользовательских ярлыках.

Для Sinatra это то же самое упражнение, которое также обсуждалось в разделе ярлыков. Просто установите свои варианты где-нибудь под вашим require 'slim' и все готово.

Посмотрите документацию в разделе «Доступные опции», чтобы узнать больше о том, что доступно для конфигурации. Slim дает вам много возможностей для игры.

Это в основном это. Есть одна или две более сложные темы, которые вы должны изучить в случае необходимости, но я подумал, что они в основном не подходят для начинающих и не используются в повседневной жизни. Я хотел упростить ситуацию и показать вам все, что вам нужно для быстрого перехода на этот потрясающий движок шаблонов. Веселитесь, и я надеюсь, что Slim теперь одна из ваших любимых новых игрушек!