liquid-derive
The liquid templating language for Rust
0.26.10
7.4M downloads/mo
#3675 most downloaded on crates.io
cobalt-org/liquid-rust
What this package is like to depend on
Last release 2 years ago
no release in 18 months
Release timing varies
gaps range from 2 weeks to 12 months
Nearly every release is documented
notes for 20 of 22 stable releases
Nothing withdrawn
no release was ever pulled
7 years old
29 releases · first in 2019
0 releases in the last 12 months
see the full history below
Release timeline
29 releases · Jul 2019 to Feb 2025Releases
latest 29-
0.26.1004 Feb 2025 -
0.26.924 Jan 2025 -
0.26.801 Aug 2024Nothing published for this version
-
0.26.725 Jul 2024Nothing published for this version
-
0.26.625 Jul 2024 -
0.26.503 Jun 2024Release notes
Open source →Compatibility
Bump MSRV to 1.70
Documentation
- Provided an example of
liquid::partials
- Provided an example of
-
0.26.409 Jun 2023 -
0.26.302 Jun 2023 -
0.26.228 May 2023Release notes
Open source →Compatibility
Bump MSRV to 1.65
Fix
- Serialization leaves off subseconds when not needed
- Deserialiation supports with and without subseconds
-
0.26.123 Feb 2023Release notes
Open source →Compatibility
Bump MSRV to 1.60
Fixes
- Don't lose millisecond precision on datetimes
-
0.26.001 Apr 2022 -
0.25.101 Apr 2022 -
0.25.029 Mar 2022 -
0.24.009 Mar 2022 -
0.23.123 Dec 2021 -
0.23.025 Aug 2021Release notes
Open source →Breaking Changes
- Upgraded from
anymaptoanymap2which is slightly better maintained (and removed it from the API)
- Upgraded from
-
0.22.027 Feb 2021Release notes
Open source →Breaking Changes
For the most part, only plugin authors should be impacted by these changes.
core::runtimewent through significant changesRenderable::render_tonow takes&dyn Runtimeinstead of&Runtime<'_>- Adding a new stack frame is now a
StackFrame::newinstead ofRuntime.run_in_scope- This opens up taking references to layers lower in the stack.
runtime.to access stack functions instead ofruntime.stack_mut()
InterruptStateis nowInterruptRegisterand accessed viaruntime.registers()- Functions were renamed while at it.
core::modelhas been flattenedderive(ValueView)now requires being used withimpl ObjectViewliquid-coreusers now need to opt-in to thederivefeature for derive macros
Features
API
- Allow
#[derive(liquid_core::ObjectView, liquid_core::ValueView)](previously only worked fromliquid, making it unusable for thelibcrate)
Fixes
- Remove
serderequirement forderive(ValueView), making it work with more types (likefield: &dyn ValueView).
Performance
- Reduce allocations for for-loop variables
- Reduce overhead from
derive(ValueView)generatingto_value
Benchmarks:
- Baseline was Liquid 0.21.5
- Variability tended to be high when in the low
usrange - For the most part, this release brings us in line with Tera's performance (when we weren't already faster).
- This is with correcting for a bug in Tera's benchmarks
- Something is off about
bench_big_loop_big_object/render, it was hardly impacted by the changes and yet that should have been case that greatly improved. Further investigation is needed.
handlebars_bench_template/parse/handlebars time: [24.068 us 24.265 us 24.561 us] change: [-19.750% -17.343% -14.831%] (p = 0.00 < 0.05) Performance has improved. handlebars_bench_template/parse/liquid time: [19.382 us 19.438 us 19.503 us] change: [-1.7723% -0.6484% +0.3359%] (p = 0.25 > 0.05) No change in performance detected. handlebars_bench_template/render/handlebars time: [17.542 us 17.644 us 17.768 us] change: [+0.2705% +0.9005% +1.5616%] (p = 0.01 < 0.05) Change within noise threshold. handlebars_bench_template/render/liquid time: [9.0979 us 9.1362 us 9.1840 us] change: [-29.397% -28.804% -28.079%] (p = 0.00 < 0.05) Performance has improved. handlebars_bench_large_loop/render/handlebars time: [2.1674 ms 2.1748 ms 2.1828 ms] change: [-1.6970% -0.9970% -0.3973%] (p = 0.00 < 0.05) Change within noise threshold. handlebars_bench_large_loop/render/liquid time: [971.57 us 1.0048 ms 1.0330 ms] change: [-25.328% -22.623% -20.133%] (p = 0.00 < 0.05) Performance has improved. liquid_bench_fixtures/parse/Hello World time: [1.5103 us 1.5228 us 1.5364 us] change: [+0.9648% +2.0790% +3.2025%] (p = 0.00 < 0.05) Change within noise threshold. liquid_bench_fixtures/render/Hello World time: [325.45 ns 327.42 ns 329.17 ns] change: [+66.006% +66.928% +67.840%] (p = 0.00 < 0.05) Performance has regressed. bench_big_loop_big_object/render/tera time: [9.7588 us 10.082 us 10.483 us] change: [+16.670% +19.302% +22.469%] (p = 0.00 < 0.05) Performance has regressed. bench_big_loop_big_object/render/liquid time: [243.01 us 244.43 us 245.82 us] change: [-3.1405% -2.6344% -2.1172%] (p = 0.00 < 0.05) Performance has improved. bench_big_table/render/tera time: [3.6955 ms 3.7093 ms 3.7226 ms] change: [-14.427% -12.151% -9.8055%] (p = 0.00 < 0.05) Performance has improved. bench_big_table/render/liquid time: [5.4149 ms 5.4978 ms 5.5944 ms] change: [-56.570% -55.904% -55.143%] (p = 0.00 < 0.05) Performance has improved. bench_teams/render/tera time: [8.9949 us 9.0961 us 9.2245 us] change: [+11.039% +14.026% +16.983%] (p = 0.00 < 0.05) Performance has regressed. bench_teams/render/liquid time: [9.0989 us 9.1398 us 9.1854 us] change: [-30.075% -29.750% -29.403%] (p = 0.00 < 0.05) Performance has improved. bench_parsing_basic_template/render/tera time: [29.527 us 29.732 us 29.979 us] change: [-0.2179% +0.8213% +2.0881%] (p = 0.16 > 0.05) No change in performance detected. bench_parsing_basic_template/render/liquid time: [16.676 us 16.724 us 16.772 us] change: [-1.2453% -0.7338% -0.3215%] (p = 0.00 < 0.05) Change within noise threshold. bench_rendering_only_variable/render/tera time: [1.4250 us 1.4302 us 1.4351 us] change: [-14.768% -12.240% -9.6021%] (p = 0.00 < 0.05) Performance has improved. bench_rendering_only_variable/render/liquid time: [851.04 ns 859.36 ns 867.64 ns] change: [+26.841% +28.148% +29.436%] (p = 0.00 < 0.05) Performance has regressed. bench_rendering_basic_templates/render/tera time: [7.9776 us 8.2825 us 8.5379 us] change: [+8.1702% +11.263% +14.601%] (p = 0.00 < 0.05) Performance has regressed. bench_rendering_basic_templates/render/liquid time: [3.9680 us 3.9832 us 3.9992 us] change: [+15.551% +16.062% +16.660%] (p = 0.00 < 0.05) Performance has regressed. bench_huge_loop/render/tera time: [850.76 us 857.75 us 865.69 us] change: [+0.4801% +0.9708% +1.5712%] (p = 0.00 < 0.05) Change within noise threshold. bench_huge_loop/render/liquid time: [803.23 us 808.50 us 814.27 us] change: [-32.892% -32.340% -31.777%] (p = 0.00 < 0.05) Performance has improved. bench_access_deep_object/render/tera time: [5.5409 us 5.5652 us 5.5925 us] change: [-3.5414% -2.1804% -1.0822%] (p = 0.00 < 0.05) Performance has improved. bench_access_deep_object/render/liquid time: [4.2440 us 4.2770 us 4.3158 us] change: [-43.376% -42.898% -42.391%] (p = 0.00 < 0.05) Performance has improved. bench_access_deep_object_with_literal/render/tera time: [7.7474 us 7.7802 us 7.8141 us] change: [+0.9487% +1.4115% +1.9242%] (p = 0.00 < 0.05) Change within noise threshold. bench_access_deep_object_with_literal/render/liquid time: [6.2592 us 6.2853 us 6.3135 us] change: [-48.596% -47.174% -45.635%] (p = 0.00 < 0.05) Performance has improved. -
0.21.104 Feb 2021 -
0.21.009 Jul 2020Release notes
Open source →Breaking Changes
- Switched from
ScalarCowusingi32toi64.
Highlights
API
- Switched from
ScalarCowusingi32toi64. - Added
from_value(&dyn ValueView)to complementto_value(...) -> Value ValueViewsupport was added to all integer types
- Switched from
-
0.20.108 Jun 2020Release notes
Open source →Highlights
Conformance improvements
- Support
splitonnil(see #403)
Bug fixes
- Fix overflow in truncate (see #402)
- Don't panic on divide-by-zero (see #404)
- Support
-
0.20.020 Mar 2020Release notes
Open source →This release resolves several planned breaking changes we've been holding off on. This doesn't make us ready for 1.0 yet but this closes the gap significantly.
Highlights
Conformance improvements
We're striving to match the liquid-ruby's behavior and this release gets us closer:
wherefilter implemented by or17191- Improvements to
sort,sort_natural,compact, and other filters by or17191 - Improvements to
includes conformance. Before, it was a weird hybrid of jekyll and stdlib styles. - Support for
{{ var.size }} - Improved equality of values
In addition, we've made it more clear what filters, tags, and blocks are a part of core liquid, Jekyll's extensions, Shopify's extensions, or our own extensions.
Improved API stability for
liquidThe
liquidcrate has been stripped down to what is needed for parsing and rendering a template.liquid_corewas created as a convenience for plugin authors.liquid_libhas all plugins soliquidcan focus on providing thestdlibwhile non-stdlibplugins can more easily evolve.
rendercan accept Rust-native typesPreviously, you had to construct a
liquid::value::Object(a newtype for aHashMap) to pass torender. Now, you can create astructthat implementsObjectViewandValueViewinstead and pass it in:#[derive(liquid::ObjectView, liquid::ValueView, serde::Serialize, serde::Deserialize, Debug)] struct Data { foo: i32, bar: String, } let data = Data::default(); let template = todo!(); let s = template.render(&data)?;In addition to the ergonomic improvements, this can help squeeze out the most performance:
- Can reuse borrowed data rather than having to switch everything to an owned type.
- Avoid allocating for the
HashMapentries.
These improvements will be in the caller of
liquidand don't show up in our benchmarks.Other
renderergonomic improvementsThere multiple convenient ways to construct your
data, depending on your application:let template = todo!(); // `Object` is a newtype for `HashMap` and has a similar interface. let object = liquid::Object::new(); let s = template.render(&object)?; let object = liquid::object!({ "foo" => 0, "bar" => "Hello World", }); let s = template.render(&object)?; // Requires your struct implements `serde::Serialize` let data = todo!(); let object = liquid::to_object(&data)?; let s = template.render(&object)?; // Using the aforementioned derive. let data = Data::default(); let s = template.render(&data)?;String Optimizations
A core data type in liquid is an
Object, a mapping of strings toValues. Strings used as keys within a template engine are:- Immutable, not needing separate
sizeandcapacityfields of aString.Box<str>is more appropriate. - Generally short, gaining a lot from small-string optimizations
- Depending on the application,
'static. Something like aCow<'static, str>. Even better if it can preserve'staticgetting a reference and going back to an owned value.
Combining these together gives us the new
kstringcrate. Some quick benchmarking suggests- Equality is faster than
String(as a gauge of access time). - Cloning takes 1/5 the time when using
'staticor small string optimization.
Details
Breaking Changes
- String types have been switched to
kstringtypes for small string and'staticoptimizations. - Plugins (tags, filters, and blocks)
- Reflection traits are no longer a super trait but instead a getter is used.
- Filter API changed to accept a
&dyn ValueView liquidis stripped down to being about to parse and render. For tag, filter, and block plugins,liquid_corewill have everything you need.
- Value:
- Functionality has moved from
ValuetoValueView,ArrayView, andObjectView. Datewas renamed toDateTime.DateTimeis now a newtype.
- Functionality has moved from
- Library:
liquidno longer exposes filters, tags, or blocks. Depend onliquid_liband enable the relevant features to get them.ParserBuildersextra_filtersandjekyll_filtersare no more. Instead depend onliquid_lib, enable theextras,shopify, orjekyllfeatures and manually add them.ParserBuilderswith_liquidandliquidhave been renamed towith_stdlibandstdlib.includetag was a hybrid of jekyll and liquid styles. Now there are separate jekyll and luquid plugins.
Features
- Value
- Scalar extended with a date-only type (#253 fixed in #363).
- Support structs being
ObjectView(#379). to_scalarandto_objectfunctions along with existingto_value(#381).scalar,array, andobjectmacros along with existingvalue(#381).- derive macros for
ObjectView/ValueView(#385). - Support
.size(#136 fixed in #390).
- Parser:
- Initial reflection support (#357).
- Render:
- Make accessing variables faster (#386).
- Filters:
- Support the
wherefilter (#291 fixed in #349) sort,sort_natural,compactnow acceptpropertyparameter (#333, #334, #335 fixed in #352).
- Support the
Fixes
- Reflection
'staticlifetimes were relaxed (#367).
- Filters:
sortorder ofnilwas incorrect (#262 fixed in #352).sortshould work on scalars (#250 fixed in #352).
-
0.20.0-alpha.819 Mar 2020 pre-releaseNothing published for this version
-
0.20.0-alpha.719 Mar 2020 pre-releaseNothing published for this version
-
0.20.0-alpha.617 Mar 2020 pre-releaseNothing published for this version
-
0.20.0-alpha.517 Mar 2020 pre-releaseNothing published for this version
-
0.20.0-alpha.417 Mar 2020 pre-releaseNothing published for this version
-
0.20.0-alpha.316 Mar 2020 pre-releaseNothing published for this version
-
0.20.0-alpha.216 Mar 2020 pre-releaseNothing published for this version
-
0.19.005 Jul 2019Release notes
Open source →Features
Breaking Changes