Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Liquid Markup
Search
Jon Daniel
October 04, 2012
Programming
1
180
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
57
Smart Software Design (SOA Edition)
binarycleric
0
140
Ethical and Sustainable On-Call
binarycleric
6
2.4k
Other Decks in Programming
See All in Programming
プロダクトの品質に コミットする / Commit to Product Quality
pekepek
1
610
Figma Dev Modeで変わる!Flutterの開発体験
watanave
0
3.7k
型のインスタンス化は非常に深く、無限である可能性があります。
kimitashoichi
0
120
Functional Event Sourcing using Sekiban
tomohisa
0
130
競技プログラミングで 基礎体力を身につけよう / You can get basic skills through competitive programming
mdstoy
0
150
Remix on Hono on Cloudflare Workers
yusukebe
2
400
Gestaltung digitaler Lösungen – Produktions- oder Designprozess?
techstories
0
130
.NET Conf 2024の振り返り
tomokusaba
0
190
React + Tauriでデスクトップアプリ開発に入門してみた
ynishimura0922
0
140
Reckoner における Datadog Browser Test の活用事例 / Datadog Browser Test at Reckoner
nomadblacky
0
190
Thoughts and experiences on Rust and TypeScript
unvalley
2
210
HTTP compression in PHP and Symfony apps
dunglas
2
1.3k
Featured
See All Featured
Practical Orchestrator
shlominoach
186
10k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
31
2.7k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
45
2.2k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.3k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
Building Your Own Lightsaber
phodgson
103
6.1k
Designing for Performance
lara
604
68k
YesSQL, Process and Tooling at Scale
rocio
169
14k
Statistics for Hackers
jakevdp
796
220k
Navigating Team Friction
lara
183
15k
Into the Great Unknown - MozCon
thekraken
33
1.5k
Typedesign – Prime Four
hannesfritz
40
2.4k
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?