vapor / leaf-kit

🍃 An expressive, performant, and extensible templating language built for Swift.
https://docs.vapor.codes/4.0/leaf/getting-started
MIT License
49 stars 38 forks source link

Improved #export/#import Behavior #58

Closed tdotclare closed 4 years ago

tdotclare commented 4 years ago

This update provides significantly improved resolution of #export/#import.

API Changes

The unbodied usage of #export("exportkey", value) now supports any acceptable single parameter as the exported value. Example uses:

// Exports context variable
#export("isAdmin", admin)
// Exports an expression
#export("specialKey", username == "tdotclare")
// Exports a custom tag call
#export("baseURL", baseURL()) 

#import can now be used inside parameters, allowing behavior like:

#if(import("showSidebar")): <div id="sidebar"><div>  #endif

Observable Behavior Changes/Fixes

Internal Changes

tdotclare commented 4 years ago

A future PR could/should enable Swift-style optional tests as well to allow providing defaults where no value is exported - EG:

#import("baseURL" ?? "www.default.com")
ffried commented 4 years ago

@tdotclare A quick thought, that came to me today: Where are the exported expessions evaluated? At import-time or at export-time?

Given the following:

#export("test", import("somethingElse"))
#export("somethingElse", "abc")

And then:

<div>#import("test")</div>

Will this try to import "somethingElse" inside the context where "test" is exported? Or will it (recursively) import it when "test" is imported, resulting in <div>abc</div>?

The latter would make sense to me, allowing for quite flexible patterns. The former is probably easier to implement, I guess... 🤔

tdotclare commented 4 years ago

It depends; if the export value is a single resolvable value during AST handling (eg, #export("key", "value") - with value being a string literal, a numeric constant, or a keyword, then a top-level #import syntax will automatically resolve to raw data, so yes, the AST would automatically become a single raw data. If the value is an actual expression like #export("key", variable == true) then the imported expression won't be resolved until render time when the variable exists.

ffried commented 4 years ago

It depends; if the export value is a single resolvable value during AST handling (eg, #export("key", "value") - with value being a string literal, a numeric constant, or a keyword, then a top-level #import syntax will automatically resolve to raw data, so yes, the AST would automatically become a single raw data. If the value is an actual expression like #export("key", variable == true) then the imported expression won't be resolved until render time when the variable exists.

  • Note - in the case where the expression is not resolvable at parsing time (like variable == true) - the import is still fully resolved during parsing, removing the import statement - it is replaced by the actual expression. EG; if written out, #import("key") would become #(variable == true) in the AST.

Wow, cool. That sounds like what I had hoped for! Thanks again for this!