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
インターフェース設計のコツとツボ
togishima
2
490
Feature Flag 自動お掃除のための TypeScript プログラム変換
azrsh
PRO
4
630
從零到一:搭建你的第一個 Observability 平台
blueswen
0
220
Proxmoxをまとめて管理できるコンソール作ってみました
karugamo
1
410
ワンバイナリWebサービスのススメ
mackee
10
7.5k
コンポーネントライブラリで実現する、アクセシビリティの正しい実装パターン
schktjm
1
670
Cloudflare Realtime と Workers でつくるサーバーレス WebRTC
nekoya3
0
230
『Python → TypeScript』オンボーディング奮闘記
takumi_tatsuno
1
140
漸進。
ssssota
0
1.1k
ソフトウェア品質特性、意識してますか?AIの真の力を引き出す活用事例 / ai-and-software-quality
minodriven
19
6.7k
RubyKaigi Hack Space in Tokyo & 函館最速 "予習" 会 / RubyKaigi Hack Space in Tokyo & The Fastest Briefing of RubyKaigi 2026 in Hakodate
moznion
1
120
iOSアプリ開発もLLMで自動運転する
hiragram
6
2.1k
Featured
See All Featured
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Become a Pro
speakerdeck
PRO
28
5.4k
Why Our Code Smells
bkeepers
PRO
336
57k
Reflections from 52 weeks, 52 projects
jeffersonlam
349
20k
Documentation Writing (for coders)
carmenintech
71
4.8k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.2k
Designing Experiences People Love
moore
142
24k
The Cost Of JavaScript in 2023
addyosmani
49
8.1k
Six Lessons from altMBA
skipperchong
28
3.8k
Visualization
eitanlees
146
16k
Docker and Python
trallard
44
3.4k
The Pragmatic Product Professional
lauravandoore
35
6.7k
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?