Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Liquid Markup
Search
Jon Daniel
October 04, 2012
Programming
1
190
Liquid Markup
Talk I gave October 4, 2012 at Pittsburgh Ruby Brigade.
Jon Daniel
October 04, 2012
Tweet
Share
More Decks by Jon Daniel
See All by Jon Daniel
Growth and Mentorship: Working with Junior Developers
binarycleric
0
63
Smart Software Design (SOA Edition)
binarycleric
0
140
Ethical and Sustainable On-Call
binarycleric
6
2.5k
Other Decks in Programming
See All in Programming
Use Perl as Better Shell Script
karupanerura
0
690
単体テストの始め方/作り方
toms74209200
0
440
LINEヤフー データグループ紹介
lycorp_recruit_jp
0
460
Java on Azure で LangGraph!
kohei3110
0
120
C++20 射影変換
faithandbrave
0
450
GoのWebAssembly活用パターン紹介
syumai
3
10k
業務自動化をJavaとSeleniumとAWS Lambdaで実現した方法
greenflagproject
1
110
赤裸々に公開。 TSKaigiのオフシーズン
takezoux2
0
130
統一感のある Go コードを生成 AI の力で手にいれる
otakakot
0
3k
F#で自在につくる静的ブログサイト - 関数型まつり2025
pizzacat83
0
290
try-catchを使わないエラーハンドリング!? PHPでResult型の考え方を取り入れてみよう
kajitack
3
510
Rails産でないDBを Railsに引っ越すHACK - Omotesando.rb #110
lnit
1
160
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1370
200k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Producing Creativity
orderedlist
PRO
346
40k
Why You Should Never Use an ORM
jnunemaker
PRO
56
9.4k
4 Signs Your Business is Dying
shpigford
184
22k
Writing Fast Ruby
sferik
628
61k
Adopting Sorbet at Scale
ufuk
77
9.4k
BBQ
matthewcrist
89
9.7k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
For a Future-Friendly Web
brad_frost
179
9.8k
How STYLIGHT went responsive
nonsquared
100
5.6k
Transcript
Liquid Markup
Jon Daniel @binarycleric github.com/binarycleric
Obligatory Promotion We’re Hiring Smart People. Ruby experience NOT required.
What Is Liquid?
None
github.com/Shopify/liquid
lets clients design their own sites...
safely and securely
logic and variable manipulation
None
yay!
None
$ gem install liquid require 'liquid'
markup = "Hello, {{ thing }}!" t = Liquid::Template.parse(markup) t.render("thing"
=> "world")
Hello, world!
markup = "Welcome, {{ user.name }}" user = User.find(1337) t
= Liquid::Template.parse(markup) t.render('user' => user)
Welcome, !
Liquid Has Trust Issues
Deny By Default
class Person < ActiveRecord::Base end # denied! "{{ person.name }}"
=> "" class Person < ActiveRecord::Base liquid_methods :name end # okay! "{{ person.name }}" => "Cmdr Shepard"
markup = "Welcome, {{ user.name }}" user = User.find(1337) t
= Liquid::Template.parse(markup) t.render('user' => user)
Welcome, Jon ‘maddog’ Hall! * If you don’t know who
he is, check Wikipedia.
Live Free Or Die.
Actually Rendering Templates
# load the user from somewhere. t = Liquid::Template.parse(markup) t.render("user"
=> user)
t = Liquid::Template.parse(markup) context = Liquid::Context.new(*args) t.render(context)
The Magic Context
Liquid::Context.new local_assigns, global_assigns, registers
Liquid::Context.new local_assigns, global_assigns, registers
registers[:domain] = domain registers[:whatever] = whatever registers[:your] = your registers[:app]
= app registers[:needs] = needs registers[:file_system] = FileSystem.new
registers[:domain] = domain registers[:whatever] = whatever registers[:your] = your registers[:app]
= app registers[:needs] = needs registers[:file_system] = FileSystem.new
Some Liquid Syntax
class FileSystem def initialize(*args) # whatever end def read_template_file(name, context)
# fetches partials from wherever end end {% include 'some-partial' %}
# a block {% if liquid == 'awesome' %} You
should try Liquid! {% endif %} # a tag {% assign liquid = 'awesome' %}
class ExampleTag < Liquid::Tag def initialize(name, markup, tokens) # setup
the tag, parse stuff, ya know... # expensive stuff. end def render(context) # drop in the assigns and go! # should be cheap. end end
class ExampleTag < Liquid::Tag def initialize(name, markup, tokens) # setup
the tag, parse stuff, ya know... # expensive stuff. end def render(context) # drop in the assigns and go! # should be cheap. end end
class PersonDrop < Liquid::Drop def addresses # stupid slow operation
Address::find_by_person(@person) end end {{ user.addresses }}
{{ “hello world” | capitalize }} # shamelessly stolen from
# liquid's source. use your # imagination people! def capitalize(input) input.to_s.capitalize end
Liquid Philosophies
•assume hostile environment •white list what you need •deny everything
else
•can edit markup •is probably non-technical Assume the client
•ignore errors by default •don’t let the client break too
much
It May Not Be For You
•partial branding •full white-label •per-install customization
Views As Data
Contribute!
Questions?