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
69
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
Java on Azure で LangGraph!
kohei3110
0
170
#kanrk08 / 公開版 PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実
bash0c7
1
450
GraphRAGの仕組みまるわかり
tosuri13
8
480
なんとなくわかった気になるブロックテーマ入門/contents.nagoya 2025 6.28
chiilog
1
220
A2A プロトコルを試してみる
azukiazusa1
2
1.2k
Blazing Fast UI Development with Compose Hot Reload (droidcon New York 2025)
zsmb
1
220
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
440
プロダクト志向なエンジニアがもう一歩先の価値を目指すために意識したこと
nealle
0
110
5つのアンチパターンから学ぶLT設計
narihara
1
110
Azure AI Foundryではじめてのマルチエージェントワークフロー
seosoft
0
130
ASP.NETアプリケーションのモダナイズ インフラ編
tomokusaba
1
410
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
510
Featured
See All Featured
Speed Design
sergeychernyshev
32
1k
Thoughts on Productivity
jonyablonski
69
4.7k
How to train your dragon (web standard)
notwaldorf
93
6.1k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
657
60k
Scaling GitHub
holman
459
140k
Optimizing for Happiness
mojombo
379
70k
Documentation Writing (for coders)
carmenintech
72
4.9k
Building an army of robots
kneath
306
45k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
A Modern Web Designer's Workflow
chriscoyier
694
190k
Raft: Consensus for Rubyists
vanstee
140
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?