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
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
58
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
Amazon ECS とマイクロサービスから考えるシステム構成
hiyanger
2
560
Domain-Driven Transformation
hschwentner
2
1.9k
WebDriver BiDiとは何なのか
yotahada3
1
140
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
11
3.8k
時計仕掛けのCompose
mkeeda
1
300
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
1k
Conform を推す - Advocating for Conform
mizoguchicoji
3
690
CI改善もDatadogとともに
taumu
0
120
Amazon S3 TablesとAmazon S3 Metadataを触ってみた / 20250201-jawsug-tochigi-s3tables-s3metadata
kasacchiful
0
170
データの整合性を保つ非同期処理アーキテクチャパターン / Async Architecture Patterns
mokuo
47
17k
Kubernetes History Inspector(KHI)を触ってみた
bells17
0
230
社内フレームワークとその依存性解決 / in-house framework and its dependency management
vvakame
1
560
Featured
See All Featured
Visualization
eitanlees
146
15k
Fontdeck: Realign not Redesign
paulrobertlloyd
83
5.4k
The Language of Interfaces
destraynor
156
24k
GitHub's CSS Performance
jonrohan
1030
460k
What's in a price? How to price your products and services
michaelherold
244
12k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
6
550
Automating Front-end Workflow
addyosmani
1368
200k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
The Pragmatic Product Professional
lauravandoore
32
6.4k
Six Lessons from altMBA
skipperchong
27
3.6k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
9
440
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?