Crystal Slang
Crystal Slang is a lightweight, terse, templating language for Crystal.
Since there's some thing about slang that I haven't been able to find example for in the wild I figured I'd document what I've learned in an organized fashion so I (as well as others) can refer to this when working on Amber projects.
Syntax
The syntax is similar to other templating languages like jade/pug or slim.
doctype html
html
head
meta name="viewport" content="width=device-width,initial-scale=1.0"
title This is a title
css:
h1 {color: red;}
p {color: green;}
style h2 {color: blue;}
body
/! Visible multi-line comment
span this is wrapped in a comment
/[if IE]
p Dat browser is old.
/ Invisible multi-line comment
span this is wrapped in a comment
h1 This is a slang file
h2 This is blue
input type="checkbox" checked=false
input type="checkbox" checked=true
input type="checkbox" checked="checked"
span#some-id.classname
#hello.world.world2
- some_var = "hello world haha"
span
span data-some-var=some_var two-attr="fun" and a #{p("hello")}
span
span.deep_nested
p
| text inside of <p>
= Process.pid
| text node
' other text node
span.alongside pid=Process.pid
custom-tag#with-id pid="#{Process.pid}"
- ["ah", "oh"].each do |s|
span = s
/ This is an invisible comment
#amazing-div some-attr="hello"
/! This is a visible comment
script var num1 = 8*4;
javascript:
var num2 = 8*3;
alert("8 * 3 + 8 * 4 = " + (num1 + num2));
Given the context:
some_var = "hello" strings = ["ah", "oh"]
Compiles to HTML:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>This is a title</title> <style> h1 {color: red;} p {color: green;} </style> <style>h2 {color: blue;}</style> </head> <body> <!--Visible multi-line comment <span>this is wrapped in a comment</span> --> <!--[if IE]> <p>Dat browser is old.</p> <![endif]--> <h1>This is a slang file</h1> <h2>This is blue</h2> <input type="checkbox"/> <input type="checkbox" checked/> <input type="checkbox" checked="checked"/> <span id="some-id" class="classname"> <div id="hello" class="world world2"> <span> <span data-some-var="hello world haha" two-attr="fun">and a hello</span> <span> <span class="deep_nested"> <p> text inside of <p> </p> #{Process.pid} text node other text node </span> </span> </span> <span class="alongside" pid="#{Process.pid}"> <custom-tag id="with-id" pid="#{Process.pid}"> <span>ah</span> <span>oh</span> </custom-tag> </span> </div> </span> <div id="amazing-div" some-attr="hello"></div> <!--This is a visible comment--> <script>var num1 = 8*4;</script> <script> var num2 = 8*3; alert("8 * 3 + 8 * 4 = " + (num1 + num2)); </script> </body> </html>
If/Else
If and else's are denoted with the -
and content between what would be curly brackets go on the next line following either |
or html tag such as span
div
- if(some_var == 12)
| It's twelve
- else
| It's not twelve
Given the context:
some_var = 12
Compiles to HTML:
<div>It's twelve</div>
Case/When
div
- case(some_var)
- when 12
| It's twelve
- when 15
| It's fifteen
- default
| Don't know
Given the context:
some_var = 12
Compiles to HTML:
<div>It's twelve!</div>
With Variables
With variables you have to denote =
so it knows you're passing a variable.
div
p This user's name is:
span = user.name
Given the context:
user = User.new user.name = "jimbo212"
Compiles to HTML:
<div>jimbo212</div>
Shortcodes
For shortcodes it's very similar to how variables are passed, excecpt it's with ==
.
There's more info about these in the Amber Docs
p
== link_to("Back", "/books", class: "btn btn-light btn-sm")
== link_to("Edit", "/books/#{book.id}/edit", class: "btn btn-success btn-sm")
Compiles to HTML:
<div>jimbo212</div>