() translation by (you can also view the original English article)
En la segunda y última parte de esta mini serie, terminaremos esta introducción con secciones sobre cómo generar código Ruby, interpolación, texto plano y cómo personalizar Slim según tus necesidades. Después de ese artículo deberías estar listo para la acción de Slim.
Código de salida
Ya has visto un poco acerca de cómo usar Ruby en tus plantillas. Esta sección te brinda todo lo que necesitas para hacer uso de esto. En el primer artículo, ya hemos estado usando Ruby en nuestras plantillas. Déjame recordarte lo que quiero decir:
Slim
1 |
html
|
2 |
head
|
3 |
title
|
4 |
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true |
5 |
= javascript_include_tag 'application', 'data-turbolinks-track' => true |
6 |
= csrf_meta_tags |
Como puedes ver, dentro de esta etiqueta head ya usamos un par de métodos de Rails para lidiar con los estilos y las cosas de JavaScript, nada importante. Todo lo que necesitas hacer para ejecutar el código de Ruby es anteponerlo con un signo igual =
. Si tu código necesita extenderse en varias líneas, simplemente agrega una barra invertida \
al final de cada línea y continúa con la siguiente. Si terminas la línea con una coma ,
, entonces no necesitas la barra invertida. Un buen toque si me preguntas.
Echemos un vistazo a otro ejemplo más concreto. Escribir formularios es a menudo un problema: un montón de código repetitivo, mucha redundancia y todos estos temibles signos <% =%>
en ERB. Esto puede ensuciarse al instante. Podría ser mejor, ¿eh?
ERB
1 |
<%= form_for @agent do |f| %> |
2 |
|
3 |
<%= f.label :name %> |
4 |
<%= f.text_field :name %> |
5 |
|
6 |
<%= f.label :number %> |
7 |
<%= f.text_field :number %> |
8 |
|
9 |
<%= f.label :licence_to_kill %> |
10 |
<%= f.check_box :licence_to_kill %> |
11 |
|
12 |
<%= f.label :gambler %> |
13 |
<%= f.check_box :gambler %> |
14 |
|
15 |
<%= f.label :womanizer %> |
16 |
<%= f.check_box :womanizer %> |
17 |
|
18 |
<%= f.submit %> |
19 |
|
20 |
<% end %>
|
Muchas cosas que escribir para crear un nuevo objeto @agent
, ¿no? Slim te permite manejar esto mucho más sucintamente. Simplemente mantenemos el signo igual y nos deshacemos de la mayoría de las otras cosas. Tadaa!
Slim
1 |
= form_for @agent do |f| |
2 |
|
3 |
= f.label :name |
4 |
= f.text_field :name |
5 |
|
6 |
= f.label :number |
7 |
= f.text_field :number |
8 |
|
9 |
= f.label :licence_to_kill |
10 |
= f.check_box :licence_to_kill |
11 |
|
12 |
= f.label :gambler |
13 |
= f.check_box :gambler |
14 |
|
15 |
= f.label :womanizer |
16 |
= f.check_box :womanizer |
17 |
|
18 |
= f.submit |
Puedes ver claramente por qué este proyecto se llama Slim. Todo el exceso de grasa se ha ido. No me digas que no te gusta lo que ves, ¡sé que lo estás cavando! Solo un signo =
y puedes rellenar tu marcado con el código Ruby, en este caso de Rails, por supuesto. Y cuando lo comparas con el HTML representado en la página final, es difícil ignorar qué tan compacto es Slim.
Salida de HTML
1 |
<form action="/" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓" /> |
2 |
|
3 |
<input type="hidden" name="authenticity_token" value="+P2I801EkEVBlsMgDo9g9/XgwwQfCBd1eoOBkFmgAHE4bxYi9HGUjEjsNwNMnEadV2tbDtYvQhFb4s/SNMXYtw==" /> |
4 |
|
5 |
<label for="agent_name">Name</label> |
6 |
<input type="text" name="agent[name]" id="agent_name" /> |
7 |
|
8 |
<label for="agent_number">Number</label> |
9 |
<input type="text" name="agent[number]" id="agent_number" /> |
10 |
|
11 |
<label for="agent_licence_to_kill">Licence to kill</label> |
12 |
<input name="agent[licence_to_kill]" type="hidden" value="0" /> |
13 |
<input type="checkbox" value="1" name="agent[licence_to_kill]" id="agent_licence_to_kill" /> |
14 |
|
15 |
<label for="agent_gambler">Gambler</label> |
16 |
<input name="agent[gambler]" type="hidden" value="0" /> |
17 |
<input type="checkbox" value="1" name="agent[gambler]" id="agent_gambler" /> |
18 |
|
19 |
<label for="agent_womanizer">Womanizer</label> |
20 |
<input name="agent[womanizer]" type="hidden" value="0" /> |
21 |
<input type="checkbox" value="1" name="agent[womanizer]" id="agent_womanizer" /> |
22 |
|
23 |
<input type="submit" name="commit" value="Save Agent" /> |
24 |
|
25 |
</form>
|
Recuerda la pregunta inicial por la cual el equipo central de Slim se guía: "¿Cuál es el mínimo requerido para hacer que esto funcione?" Cuando observas la salida HTML final, creo que es justo decir que Slim ha respondido esa pregunta con bastante éxito, sin quejas por mi parte. Quiero agregar un par de pequeños ejemplos para darte más oportunidad de acostumbrarte a cómo se ve esto en Slim.
Este fragmento de código ERB ...
1 |
<%= render "shared/agents", collection: @agents %> |
... se convierte en esto en Slim:
1 |
= render "shared/agents", collection: @agents |
ERB
1 |
<h2>Agents</h2> |
2 |
|
3 |
<ul>
|
4 |
<% @agents.each do |agent| %>
|
5 |
<li class='agent'>
|
6 |
<div>Name: <%= agent.name %></div> |
7 |
<div>Number: <%= agent.number %></div> |
8 |
<div>Licence to kill: <%= agent.licence_to_kill %></div> |
9 |
</li> |
10 |
<% end %>
|
11 |
</ul> |
Slim
1 |
h2 Agents |
2 |
ul
|
3 |
- @agents.each do |agent| |
4 |
li.agent |
5 |
div
|
6 |
| Name: |
7 |
= agent.name |
8 |
div
|
9 |
| Number: |
10 |
= agent.number |
11 |
div
|
12 |
| Licence to kill: |
13 |
= agent.licence_to_kill |
También puedes escribir esto de una manera más ágil a través de la interpolación. Sin embargo, no quieres volverte demasiado loco con eso. Esto se vería así entonces:
Slim
1 |
h2 Agents |
2 |
ul
|
3 |
- @agents.each do |agent| |
4 |
li.agent |
5 |
div Name: #{agent.name} |
6 |
div Number: #{agent.number} |
7 |
div Licence to kill: #{agent.licence_to_kill} |
Interpolacion de texto
Mencioné esto antes brevemente, pero como es una forma de generar código Ruby, también pertenece a esta sección. Por supuesto, también puedes utilizar la interpolación de texto estándar de Ruby en tus plantillas Slim.
Slim
1 |
h2 Welcome Mr. #{misix_agent.surname}! I expect you to die! |
2 |
|
3 |
h2 Welcome Mr. \#{misix_agent.surname}! I expect you to die! |
HTML
1 |
<h2>
|
2 |
Welcome Mr. Bond! I expect you to die! |
3 |
</h2>
|
4 |
|
5 |
<h2>
|
6 |
Welcome Mr. \#{misix_agent.surname}! I expect you to die! |
7 |
</h2>
|
Como se vio anteriormente, una barra invertida \
inicial simple se escapa de la interpolación.
Código de control
Una más por el camino. Supongamos que deseas utilizar un par de condicionales en tu vista. Al igual que Haml, significa que el código Ruby no se debe enviar a la página con un simple guión -
. Has visto esto en el ejemplo anterior, donde lo usamos para iterar sobre @agents
sin mostrar esa parte particular del código.
Aunque deberías tratar de mantenerte alejado de todo tipo de condicionales en tus vistas donde sea posible y tratar de encontrar mejores soluciones OOP para tales casos, que es una historia para otro momento, se verían así:
Slim
1 |
- if current_user.role == "admin" |
2 |
p#admintxt | Welcome back my master! |
3 |
= link_to "Edit Profile", edit_user_path(:current) |
4 |
= link_to "Logout", logout_path |
5 |
- elsif current_user |
6 |
= link_to "Edit Profile", edit_user_path(:current) |
7 |
= link_to "Logout", logout_path |
8 |
- else |
9 |
= link_to "Register", new_user_path |
10 |
= link_to "Login", login_path |
ERB
1 |
<% if current_user.role == "admin" %> |
2 |
<p id="admintxt">Welcome back my master!</p> |
3 |
<%= link_to "Edit Profile", edit_user_path(:current) %>
|
4 |
<%= link_to "Logout", logout_path %>
|
5 |
<% elsif current_user %>
|
6 |
<%= link_to "Edit Profile", edit_user_path(:current) %>
|
7 |
<%= link_to "Logout", logout_path %>
|
8 |
<% else %>
|
9 |
<%= link_to "Register", new_user_path %>
|
10 |
<%= link_to "Login", login_path %>
|
11 |
<% end %>
|
Si deseas generar código sin que el HTML se escape en su lugar, simplemente usa dos signos iguales ==
. ¡Eso es!
Antes de continuar, definitivamente debería tomarme el tiempo para mencionar esto: como sabrás, muchas toneladas de código en las vistas, también conocido como toneladas de código Ruby en nuestro contexto, son un olor grave y deben minimizarse en todo momento. Solo porque Slim lo hace incluso más atractivo para enlucir tus plantillas con toneladas de lógica, no significa que debas hacerlo. ¡Practica la restricción en ese departamento! Por otro lado, Slim lo hace realmente elegante para inyectar Ruby donde sea necesario.
HTML en línea
Si sientes la necesidad de escribir HTML en tus plantillas Slim, tienes la opción de hacerlo. No he usado esa función, ni me importaría usarla, pero tal vez durante una fase de transición esto podría ser útil para los recién llegados. Vamos a echar un vistazo súper rápido.
Slim
1 |
doctype html |
2 |
<html> |
3 |
head
|
4 |
title = full_title(yield(:title)) |
5 |
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true |
6 |
= javascript_include_tag 'application', 'data-turbolinks-track' => true |
7 |
= csrf_meta_tags |
8 |
<body> |
9 |
header.navbar |
10 |
.logo |
11 |
= link_to "sample app", 'root_path', id: "logo" |
12 |
<nav> |
13 |
ul.navbar-right |
14 |
li
|
15 |
= link_to "Home", 'root_path' |
16 |
li
|
17 |
= link_to "Help", 'help_path' |
18 |
li
|
19 |
= link_to "Log in", 'login_path' |
20 |
</nav> |
21 |
.main
|
22 |
= yield
|
23 |
</body> |
24 |
</html> |
Cuando Slim encuentra el corchete angular izquierdo <
, sabe que deseas mezclar algo de HTML.
Texto verbatim (palabra por palabra)
El símbolo de la pipa |
señala a Slim que deseas tener texto sin formato (palabra por palabra) y simplemente copia la línea. En efecto, esto te permite evitar cualquier tipo de procesamiento. La documentación dice que si deseas escribir texto literal en varias líneas, debes darle sangría al texto con cada salto de línea.
Slim
1 |
body
|
2 |
p
|
3 |
|
|
4 |
Slim is my new best friend. Slim is my new best friend. |
Salida HTML
1 |
<body>
|
2 |
<p>
|
3 |
Slim is my new best friend. Slim is my new best friend. |
4 |
</p>
|
5 |
</body>
|
Captura de pantalla



Si colocas el texto en la misma línea que el símbolo pipe |, puedes establecer el margen izquierdo después del pipe más un solo espacio. Por curiosidad, jugué un poco con esto y encontré los siguientes resultados. Solo la última variación de ejemplo tiene un pequeño hipo obvio del que deberías estar consciente: se traga la primera palabra de la oración.
Slim
1 |
body
|
2 |
p
|
3 |
|
|
4 |
This line is on the left margin. |
5 |
This line will have one space in front of it. |
6 |
This line will have two spaces in front of it. |
7 |
And so on... |
8 |
|
9 |
p
|
10 |
| This line is on the left margin. |
11 |
This line will have one space in front of it. |
12 |
This line will have two spaces in front of it. |
13 |
And so on... |
14 |
|
15 |
p This line is on the left margin. |
16 |
This line will have one space in front of it. |
17 |
This line will have two spaces in front of it. |
18 |
And so on... |
19 |
|
20 |
p This line is on the left margin. |
21 |
This line will have one space in front of it. |
22 |
This line will have two spaces in front of it. |
23 |
And so on... |
24 |
|
25 |
p
|
26 |
This line is on the left margin. |
27 |
This line will have one space in front of it. |
28 |
This line will have two spaces in front of it. |
29 |
And so on... |
Captura de pantalla



La forma en que la salida se representa en tu marcado HTML difiere un poco.
1 |
<body>
|
2 |
<p>
|
3 |
This line is on the left margin. |
4 |
This line will have one space in front of it. |
5 |
This line will have two spaces in front of it. |
6 |
And so on... |
7 |
</p>
|
8 |
|
9 |
<p>
|
10 |
This line is on the left margin. |
11 |
This line will have one space in front of it. |
12 |
This line will have two spaces in front of it. |
13 |
And so on... |
14 |
</p>
|
15 |
|
16 |
<p>
|
17 |
This line is on the left margin. |
18 |
This line will have one space in front of it. |
19 |
This line will have two spaces in front of it. |
20 |
And so on... |
21 |
</p>
|
22 |
|
23 |
<p>
|
24 |
This line is on the left margin. |
25 |
This line will have one space in front of it. |
26 |
This line will have two spaces in front of it. |
27 |
And so on... |
28 |
</p>
|
29 |
|
30 |
<p>
|
31 |
<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> |
32 |
</p>
|
33 |
</body>
|
Comentarios
Por supuesto, es necesario comentar tu código de vez en cuando. No olvides, sin embargo, que demasiados comentarios son también un olor. ¡Intenta mantenerlo al mínimo!
Una barra diagonal hacia adelante /
es todo lo que necesitas para comentar cualquier código.
Slim
1 |
body
|
2 |
/p
|
3 |
| This line is on the left margin.
|
4 |
This line will have one space in front of it.
|
5 |
This line will have two spaces in front of it.
|
6 |
And so on...
|
¡Boom! Y ahora este párrafo se ha ido de la página. Este comentario no deja rastro en el marcado HTML final. Solo necesitas aplicarlo al selector padre y todos sus hijos también serán comentados. Por lo tanto, incluso los comentarios son escasos y mínimos.
Si, por otro lado, deseas algún comentario HTML <!-- -->
que aparezca en la salida final renderizada, solo necesitas agregar un signo de exclamación !
después de la barra.
Slim
1 |
body
|
2 |
/!p
|
3 |
| This line is on the left margin.
|
4 |
This line will have one space in front of it.
|
5 |
This line will have two spaces in front of it.
|
6 |
And so on...
|
Salida HTML
1 |
<body>
|
2 |
<!--p
|
3 |
| This line is on the left margin.
|
4 |
This line will have one space in front of it.
|
5 |
This line will have two spaces in front of it.
|
6 |
And so on...-->
|
¡Ordenado!
Atajos personalizados
Hemos estado usando atajos todo el tiempo. Cuando escribes un punto .
o un símbolo hash #
le dices a Slim que quieres usar accesos directos predefinidos para clases e identificaciones. Eso es ciertamente un muy buen valor por defecto, pero ¿qué puedes hacer para expandir eso y crear tus propios pequeños fragmentos? Podemos hacer esto para etiquetas y atributos por igual. ¡Bienvenido a la genialidad de Slim!
En Rails, solo necesitamos configurar un inicializador con el siguiente patrón:
config/initializers/slim.rb
1 |
Slim::Engine.set_options shortcut: {'c' => {tag: 'container'}, '#' => {attr: 'id'}, '.' => {attr: 'class'} } |
En las aplicaciones de Sinatra, simplemente agrega la misma configuración en cualquier lugar debajo de la línea donde requieres Slim con require 'slim'
.
your_sinatra_app.rb
1 |
require 'sinatra' |
2 |
require 'slim' |
3 |
|
4 |
Slim::Engine.set_options shortcut: {'c' => {tag: 'container'}, '#' => {attr: 'id'}, '.' => {attr: 'class'} } |
5 |
|
6 |
get('/') { slim :index } |
7 |
|
8 |
__END__
|
9 |
|
10 |
@@ index
|
11 |
doctype html
|
12 |
html
|
13 |
head
|
14 |
title Slim Templates
|
15 |
body
|
16 |
h1 Boss Level Templates With Slim
|
Puedes configurar opciones en el Slim::Engine proporcionando un hash con el acceso directo que necesitas. En el ejemplo anterior, le indicamos a Slim que usara c
como acceso directo para una etiqueta container
. Lo utilizarías así en tus archivos Slim:
Slim
1 |
c.content Now you have a container tag with a .content class. |
Y el HTML renderizado se vería así, por supuesto:
HTML
1 |
<container class="content"> |
2 |
Now you have a container tag with a .content class. |
3 |
</container>
|
Muy bonito, ¿eh? Pero no pensaste que ahí es donde se detiene la música, ¿verdad? Podemos llevarlo más allá de eso. Déjame darte un ejemplo que es un poco más complicado:
config/initializers/slim.rb
1 |
Slim::Engine.set_options shortcut: { |
2 |
'#' => {attr: 'id'}, |
3 |
'.' => {attr: 'class'}, |
4 |
'c' => {tag: 'container'}, |
5 |
'&' => {tag: 'input', attr: 'type'}, |
6 |
'@' => {attr: 'role'}, |
7 |
'^' => {attr: %w(data-role role)} |
8 |
}
|
En este ejemplo, no solo creé etiquetas personalizadas sino que también proporcioné atributos personalizados. Vamos a analizar este paso a paso. Por cierto, rompí el hash de opciones en varias líneas para mantenerlo legible y para evitar tener una larga línea de código con la que a nadie le gusta tropezar. Se lee mucho mejor, ¿no te parece?
A través del símbolo &
, ahora podemos crear una etiqueta de entrada, y solo necesitamos darle un tipo, que sigue inmediatamente al símbolo. Podemos usar cualquier símbolo que tenga sentido usar; no hay necesidad de usar el mismo que yo hice. Sin embargo, ten cuidado y trata de tomar decisiones inflexibles en ese departamento.
Slim
1 |
&text name="user" |
2 |
&password name="pw" |
3 |
&submit |
Salida HTML
1 |
<input name="user" type="text"> |
2 |
<input name="pw" type="password"> |
3 |
<input type="submit"> |
Cuando realices cambios en este inicializador con tus accesos directos personalizados, no debes olvidar reiniciar tu servidor local. Sin eso, tus cambios no se reflejarán durante el preprocesamiento.
A continuación, si necesito un atributo role
, ahora puedo prefijarlo con un símbolo @
.
Slim
1 |
.person@admin Daniel Mendler |
Salida HTML
1 |
<div class="person" role="admin"> |
2 |
Daniel Mendler |
3 |
</div> |
Actualización: el atributo role es un enfoque semántico para describir el rol del elemento en cuestión, si necesitas determinar el propósito del elemento.
Mira, a través del punto obtenemos una clase class="person"
y @admin
nos dio un role="admin"
. Muy útil, pero podemos ir un paso más allá y usar una matriz para especificar múltiples atributos que deberían crearse a través de un solo acceso directo.
Slim
1 |
.nifty^hacker CrackDoctor |
Salida HTML
1 |
<div class="nifty" data-role="hacker" role="hacker"> |
2 |
CrackDoctor |
3 |
</div>
|
Debido a que asociamos una serie de atributos para nuestro acceso directo ^
, Slim crea atributos data-role
y role
simultáneamente mediante un solo símbolo. Eso puede ser bastante útil. Imagínate si deseas generar un elemento similar al siguiente y puedes hacerlo de manera concisa con un atajo y algún código Ruby.
HTML
1 |
<source src="track1.mp3" type="audio/mpeg" data-duration="1min5secs" data-tempo="125bpm" data-artist="The Beatles" /> |
Escribir todo esto a mano no parece ser el mejor uso de tu tiempo, tenemos un código para hacer ese trabajo por nosotros. Bueno, ahí lo tienen, eso es todo lo que necesitas saber para crear tu propio conjunto de atajos increíbles, o para crear un gran lío cuando no practicas un poco de restricción. Recomendaría no exagerar con esto, especialmente trata de evitar definir accesos directos que usen símbolos a los que Slim ya está conectado.
Actualización: los data- attributes se utilizan para tener algunos datos privados en tu página o aplicación. Cosas que te ayudan a filtrar contenido, por ejemplo. Son atributos personalizados que se pueden utilizar en todos los elementos HTML. Usarlos para propósitos de JavaScript es otra práctica común. También es muy útil para probar elementos en una página si quieres asegurarte de que se muestren elementos particulares y evitar que los diseñadores se metan con tus estilos.
Configurando Slim
Antes de que te vayas, quería mostrarte un pequeño vistazo a las vastas opciones de configuración y cómo aplicarlas. Para Rails, debes crear un archivo de entorno como config/environments/development.rb
y especificar las opciones que necesitas. Simplemente coloca tu configuración en algún lugar dentro del bloque Rails.application.configur
e.
1 |
Rails.application.configure do |
2 |
Slim::Engine.set_options default_tag: 'p', |
3 |
tabsize: 2, |
4 |
attr_list_delims: {'(' => ')', |
5 |
'[' => ']', |
6 |
'{' => '}', |
7 |
'«' => '»', |
8 |
'‹' => '›' |
9 |
}
|
10 |
end
|
En esta configuración, me aseguré de que la etiqueta predeterminada que se crea si se omite un nombre de etiqueta es una etiqueta <p>
, no una etiqueta div
, que es la configuración estándar. Además, ajusté el tamaño de las pestañas para usar dos espacios en blanco y finalmente agregué dos delimitadores más para envolver los atributos de las etiquetas. Ahora puedo usar ‹›
y «»
también para eso. No es terriblemente útil pero es bueno para propósitos de demostración.
En el siguiente ejemplo, puedes ver que todos los delimitadores para atributos wrappers crean el mismo resultado, también que .some-class
o #some-id
crea etiquetas <p>
por defecto.
Slim
1 |
body
|
2 |
#zeroth
|
3 |
a{href="https://slim-lang.com" title='Home page'} Goto the home page |
4 |
|
5 |
.first |
6 |
a[href="http://slim-lang.com" title='Home page'] Goto the home page |
7 |
|
8 |
.second |
9 |
a(href="http://slim-lang.com" title='Home page') Goto the home page |
10 |
|
11 |
.third |
12 |
a‹href="http://slim-lang.com" title='Home page'› Goto the home page |
13 |
|
14 |
.fourth |
15 |
a«href="http://slim-lang.com" title='Home page'» Goto the home page |
Salida HTML
1 |
<body>
|
2 |
<p id="zeroth"></p> |
3 |
<a href="http://slim-lang.com" title="Home page">Goto the home page</a> |
4 |
|
5 |
<p class="first"></p> |
6 |
<a href="http://slim-lang.com" title="Home page">Goto the home page</a> |
7 |
|
8 |
<p class="second"></p> |
9 |
<a href="http://slim-lang.com" title="Home page">Goto the home page</a> |
10 |
|
11 |
<p class="third"></p> |
12 |
<a href="http://slim-lang.com" title="Home page">Goto the home page</a> |
13 |
|
14 |
<p class="fourth"></p> |
15 |
<a href="http://slim-lang.com" title="Home page">Goto the home page</a> |
16 |
</body>
|
Alternativamente, también puedes configurar esto en config/initializers/slim.rb
como te mostré en la sección sobre accesos directos personalizados.
Para Sinatra, es el mismo ejercicio descrito en la sección de accesos directos. Simplemente establece tus opciones en algún lugar por debajo de tu declaración require 'slim'
y estarás listo.
Echa un vistazo a la documentación en "Opciones disponibles" para obtener más información acerca de lo que está disponible para la configuración. Slim te da muchas opciones para jugar.
Consideraciones finales
Eso es básicamente todo. Hay uno o dos temas más avanzados en los que deberías profundizar si es necesario, pero pensé que en su mayoría no son para principiantes ni se usan mucho en el día a día. Quería mantener las cosas simples y mostrarte todo lo que necesitas para cambiar rápidamente a este increíble motor de plantillas. ¡Diviértete y espero que Slim sea ahora uno de tus nuevos juguetes favoritos!