Tigerlily
Tigerlily édite une plateforme à destination des grands comptes, qui leur permet de gérer de façon simple et efficace leurs actions de social marketing
z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
d | toggle debug mode |
## <ret> | go to slide # |
c, t | table of contents (vi) |
f | toggle footer |
r | reload slides |
n | toggle notes |
p | run preshow |
Tigerlily édite une plateforme à destination des grands comptes, qui leur permet de gérer de façon simple et efficace leurs actions de social marketing
<p><% User.delete_all %> Pwned !</p>
{% for story in story_list %}
<h2>
<a href="{% url_to story %}">
{{ story.headline }}
</a>
</h2>
<p>{{ story.tease|escape }}</p>
{% endfor %}
template = Liquid::Template.parse('Hello {{ person }}')
puts template.render('person' => 'Homer')
class ShopDrop < Liquid::Drop
def top_sales
Shop.current.products.find(:all, :order => 'sales', :limit => 10 )
end
def before_method(method_name)
Shop.current.send(method_name) if Shop.column_names.include?(method_name)
end
end
class Shop
liquid_methods :top_sales
def top_sales
Shop.current.products.find(:all, :order => 'sales', :limit => 10 )
end
end
class Shop
def to_liquid
self
end
def top_sales
Shop.current.products.find(:all, :order => 'sales', :limit => 10 )
end
end
<p>{{ shop.class.delete_all }} Pwned !</p>
<p>{{ my_list|join:", " }}</p>
module MyFilters
def join(input, glue=' ')
input.join(glue)
end
end
Liquid::Template.register_filter(MyFilters)
<p>{% random 5 %}</p>
<!-- produce -->
<p>3</p>
class Random < Liquid::Tag
def initialize(tag_name, max, tokens)
super
@max = max.to_i
end
def render(context)
rand(@max).to_s
end
end
Liquid::Template.register_tag('random', Random)
{% random 5 %}
<p>Wanna hear a joke?<p>
{% endrandom %}
<!-- In 20% of the cases, produce: -->
<p>Wanna hear a joke?</p>
class Random < Liquid::Block
def initialize(tag_name, markup, tokens)
super
@rand = markup.to_i
end
def render(context)
if rand(@rand) == 0
super
else
''
end
end
end
Liquid::Template.register_tag('random', Random)
<p>
{% if_already_voted_on post %}
Remove my vote
{% else %}
Vote
{% endif_already_voted_on %}
</p>
class IfAlreadyVotedOn < Liquid::Block
def initialize(tag_name, variable, tokens)
@variable = variable
@blocks = []
push_block!
super
end
def render(context)
context.stack do
current_user = context['current_user']
post = context[@variable]
block = current_user.already_voted_on?(post) ? @blocks.first : @blocks.last
return render_all(block, context)
end
end
## snip ....
def unknown_tag(tag, markup, tokens)
if tag == 'else'
push_block!
else
super
end
end
private
def push_block!
block = []
@blocks.push(block)
@nodelist = block
end
end
Template.register_tag('if_already_voted_on', IfAlreadyVotedOn)
GC.disable
Benchmark.bm{ |x|
x.report('~25 tags') { Liquid::Template.parse(template25) }
x.report('~250 tags') { Liquid::Template.parse(template250) }
x.report('~2500 tags') { Liquid::Template.parse(template2500) }
x.report('~25000 tags') { Liquid::Template.parse(template25000) }
}
GC.enable
~25 tags 0.000000 0.000000 0.000000 ( 0.001449)
~250 tags 0.010000 0.000000 0.010000 ( 0.009970)
~2500 tags 0.100000 0.000000 0.100000 ( 0.098813)
~25000 tags 1.020000 0.010000 1.030000 ( 1.028419)
Une bibliothèque qui aide à créer des tags liquid plus cohérents et plus facilement.
class TypeOfTag < Solid::Tag
tag_name :typeof
def display(*values)
values.map{ |value| "<p>Type of #{value.inspect} is #{value.class.name}</p>" }.join("\n")
end
end
{% capture myvar %}eggspam{% endcapture %}
{% typeof "foo", 42, 4.2, myvar, /bb|[^b]{2}/, myoption:"bar", otheroption:myvar %}
<!-- produce -->
<p>Type of "foo" is String</p>
<p>Type of 42 is Fixnum</p>
<p>Type of 4.2 is Float</p>
<p>Type of "eggspam" is String</p>
<p>Type of /bb|[^b]{2}/ is Regexp</p>
<p>Type of {:myoption=>"bar", :otheroption=>"eggspam"} is Hash</p>
class HelloTag < Solid::Tag
tag_name :hello
context_attribute :current_user
def display
"Hello #{current_user.name} !"
end
end
class PBlock < Solid::Block
tag_name :p
def display(options)
"<p class='#{options[:class]}'>#{yield}</p>"
end
end
{% p class:"content" %}
It works !
{% endp %}
<!-- produce -->
<p class="content">It works !</p>
class IfAlreadyVotedOn < Solid::ConditionalBlock
tag_name :if_already_voted_on
context_attribute :current_user
def display(post)
yield(current_user.already_voted_on?(post))
end
end
<p>
{% if_already_voted_on post %}
Remove my vote
{% else %}
Vote
{% endif_already_voted_on %}
</p>
class Post < ActiveRecord::Base
scope :published, where(:published => true)
scope :with_comments, where('comments_count > 0')
class << self
liquid_methods :published, :with_comments
end
end
SyntaxError: (eval):1: syntax error, unexpected $end
...Class < Liquid::Drop; self; end
class PostDrop < Solid::ModelDrop
allow_scopes :published, :with_comments
respond :to => /sorted_by_(\w+)/, :with => :sort_by
protected
def sort_by(ordering)
@scope = scope.sorted_by(ordering)
end
immutable_method :sort_by
end
{% for post in Post.published.with_comments.sorted_by_comments_count %}
<p>{{ post.title }}</p>
{% endfor %}
Coloration syntaxique pour Ace
//= require ace/mode-solid