amberframework / liquid.cr Goto Github PK
View Code? Open in Web Editor NEWLiquid template engine for Crystal
License: MIT License
Liquid template engine for Crystal
License: MIT License
We're now using liquid.cr
as dependency on amberframework 🎉
although, We're having some issues with the liquid.cr
tags:
5.07s$ shards install
Fetching https://github.com/amberframework/router.git
Fetching https://github.com/amberframework/cli.git
Fetching https://github.com/mosop/optarg.git
Fetching https://github.com/mosop/callback.git
Fetching https://github.com/mosop/string_inflection.git
Fetching https://github.com/elorest/compiled_license.git
Fetching https://github.com/jeromegn/kilt.git
Fetching https://github.com/TechMagister/liquid.cr.git
Failed git ls-tree -r --full-tree --name-only v0.2.4 -- shard.yml (). Maybe a commit, branch or file doesn't exist?
^ https://travis-ci.org/amberframework/amber/jobs/364128731#L551
I had a similar issue here: ChangJoo-Park/gravatarcr#1
I've benchmarked this project versus Shopify/liquid on Ruby 2.5
And got very strange results:
Ruby
tpl = Liquid::Template.parse(template)
ctx = Liquid::Context.new
ctx["order"] = order
Benchmark.ips do |x|
x.report("parse & render") {
ctx = Liquid::Context.new
ctx["order"] = order
Liquid::Template.parse(template).render(ctx)
}
x.report("render") {
tpl.render(ctx)
}
end
Crystal
tpl = Liquid::Template.parse(template)
ctx = Liquid::Context.new
ctx.set("order", order)
Benchmark.ips do |x|
x.report("parse & render") {
ctx = Liquid::Context.new
ctx.set("order", order)
Liquid::Template.parse(template).render(ctx)
}
x.report("render") { tpl.render(ctx) }
end
Ruby (template without filters)
parse & render 2.698k (± 3.8%) i/s - 13.585k in 5.042274s
render 10.020k (± 2.6%) i/s - 50.085k in 5.002127s
Crystal (template without filters)
parse & render 1.56k (639.72µs) (± 2.02%) 171kB/op 2.52× slower
render 3.94k (253.49µs) (± 1.97%) 73.9kB/op fastest
Ruby (template with one strip_newlines filter)
parse & render 2.547k (± 3.3%) i/s - 12.760k in 5.014887s
render 8.649k (± 4.6%) i/s - 43.962k in 5.094069s
Crystal (template with one strip_newlines filter)
parse & render 1.50k (667.40µs) (± 1.20%) 179kB/op fastest
render 1.29k (776.84µs) (±57.11%) 235kB/op 1.16× slower
Crystal version was built with --release
flag, but it didn't help. As you can see, Liquid on Crystal renders in 2.5 slower than on Ruby in the best case (without any filters). Using Liquid-filters kills performance of rendering on Crystal completely. And surprisingly just render
starts to take more time than parse + render
.
P.S. Here is the test data
{% assign params_name = "{{ name | underscore }}_params" %}
{% assign hash_name = "{{ name| underscore }}_hash" %}
{% assign create_model_method = "create_{{ name | underscore }}" %}
require "./spec_helper"
{% assign params_name = "{{ name | underscore }}_params" %}
{% assign hash_name = "{{ name| underscore }}_hash" %}
{% assign create_model_method = "create_{{ name | underscore }}" %}
require "./spec_helper"
multiple spaces between tokens
Can you create a new release?
While attempting to update Amber today, I happened to notice that this repo is active again. Any interest in merging some (or all?) of the changes I made in my fork?
https://github.com/anamba/liquid.cr/blob/master/CHANGELOG.md
At this point, I am not using Crystal daily like I used to, so I am probably not going to find the time to break up the changes into individual PRs, but it would be nice not to have to maintain my own fork.
Especially now that Amber requires liquid 0.3.3, which means I now have to fork that, too (because my liquid fork is up to 0.6.0). Another case where crystal-lang/shards#299 would be really helpful.
contains
keyword ( http://shopify.github.io/liquid/basics/operators/ )I just realize you released v0.3.0 to fix crystal v0.25.0 compat issues, Thank you! 🎉
However, tag v0.2.6 (patch version) is still available, so any dev using ~> 0.2.0
with crystal v0.24.2 will get compat issues 😅
Liquid.cr need some updates to fix breaking-changes on crystal v0.25.0
in lib/liquid/src/liquid/filters/first.cr:9: no overload matches 'JSON::Any.new' with type JSON::Any
Overloads are:
- JSON::Any.new(raw : Type)
- JSON::Any.new(pull : JSON::PullParser)
- JSON::Any.new(raw : Int32)
- JSON::Any.new(raw : Float32)
- JSON::Any.new(raw : Time)
Any.new d.first
^^ We're getting this on amber specs
Ref: https://shopify.github.io/liquid/tags/raw/
{% raw %}
In Handlebars, {{ this }} will be HTML-escaped, but
{{{ that }}} will not.
{% endraw %}
On liquid.cr
Unhandled exception: Missing hash key: "raw" (KeyError)
from /usr/lib/crystal/hash.cr:0:9 in 'fetch'
from /usr/lib/crystal/hash.cr:62:5 in '[]'
from lib/liquid/src/liquid/block_register.cr:10:5 in 'for_name'
from lib/liquid/src/liquid/parser.cr:127:23 in 'consume_statement'
from lib/liquid/src/liquid/parser.cr:55:11 in 'parse'
from lib/liquid/src/liquid/parser.cr:22:7 in 'parse'
from lib/liquid/src/liquid/template.cr:15:7 in 'parse'
from src/testliquid.cr:17:1 in '__crystal_main'
from /usr/lib/crystal/crystal/main.cr:104:5 in 'main_user_code'
from /usr/lib/crystal/crystal/main.cr:93:7 in 'main'
from /usr/lib/crystal/crystal/main.cr:133:3 in 'main'
from __libc_start_main
from _start
from ???
It seems the whitespace control is removing whitespace from within the template statements (unexpected behaviour) rather than removing the whitespace created by the flow control (expected behaviour).
Given this data
fields = [ {type: "reference", name: "user"}, {type: "reference", name: "post"} ]
with this template
{%- for field in fields -%}
{%- if field.type == "reference" -%}
belongs_to :{{field.name}}
{%- endif -%}
{%- endfor -%}
I would expect the output to be
belongs_to :user
belongs_to :post
but the actual output is
belongs_to :userbelongs_to :post
When there's an iterator in the liquid template, the parser introduces a carriage return at the beginning of each iteration, and another one at the end, leaving a blank line between each iteration.
This does appear to be known, since it's accounted for in template_spec.cr:
it "should render for loop with loop variable" do
tpl = Parser.parse("{% for x in 0..2 %}
Iteration n°{{ forloop.index }}
{% endfor %}")
tpl.render(Context.new(:strict)).should eq "\n Iteration n°1\n \n Iteration n°2\n \n Iteration n°3\n "
end
However, this isn't desirable behaviour to me, and I'm wondering if anyone else agrees that we should change this, or if it's preferred to leave it as is.
Currently the whitespace feature of shopify liquid {%- -%} seems like it is not supported in liquid.cr so generated artifacts have a lot of whitespace and many empty lines if IF expressions are used within loops.
Related to #7
template = Liquid.embed("path/to/template.liquid")
Choose which action is the best when bad arguments are given to a filter:
Liquid does have a syntax for this, but I don't see it within this library. It is a very useful part of Liquid.
This code fails do compile, commenting out the class Node declaration solves the issue.
class Node
end
require "liquid"
txt = "
{% if kenny.sick %}
Kenny is sick.
{% elsif kenny.dead %}
You killed Kenny! You ***!!!
{% else %}
Kenny looks okay --- so far
{% endif %}
"
ctx = Liquid::Context.new
ctx.set "kenny", { "sick" => false, "dead" => true}
tpl = Liquid::Template.parse txt # tpl can be cached and reused
result = tpl.render ctx
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.