w3c-ccg / vc-render-method

Rendering methods for Verifiable Credentials
https://w3c-ccg.github.io/vc-render-method/
Other
2 stars 1 forks source link

Template engine #10

Open BigBlueHat opened 1 month ago

BigBlueHat commented 1 month ago

This question sits pretty close to the core of Render Method as a concept (for me at least). Especially if we imagine a more general approach like what's proposed in #9, the the template engine used on the template or url response is the "only" thing fully defined by that method and what the output format is becomes the responsibility of the mediaType property.

Consequently, I'd like to start the discussion around options.

The current specification draft (951c7ef) uses JSON Pointer (RFC6901) wrapped in {{ and }} as the means to populate areas of a template. There are, however, no conditional capabilities (or "sections") nor the ability to loop. Additionally, I've not yet found a template engine built that does this style of processing--which means greater overhead for implementers (until libraries are written).

Another option that seems common (both mentioned in other issues/threads and which I've used personally is Mustache. Mustache's "logic-less" templates do provide "sections" which output (or don't) areas of template code based on truthy values of certain keys which are also used to handle loops. However (as with JSON Pointer), it does not provide for value based conditions which prevent accessing data in arrays-of-objects (for example).

Liquid (and others), provide that flexibility (and more), but I wonder where we should draw the line. The more advanced the template engine becomes, the more risks may be created. That said, limiting the credential formats to accommodate the template engine used by Render Method seems like altering the language rather than revising the dictionary.

I'd love to hear more thoughts and experiences (and concerns!) from others.

Cheers! 🎩

brianorwhatever commented 1 month ago

My vote would be to target mustache I think it lands in a very good place as far as complexity and simplicity.

Can you explain this caveat a little more?

it does not provide for value based conditions which prevent accessing data in arrays-of-objects (for example).

BigBlueHat commented 1 month ago

@brianorwhatever if an array of objects was used to store somethings to be passed to Mustache, the only way to retrieve a specific item would be via it's location in the array...not via any of it's keys/values.

This is possible:

{{ products.0.type }}

But if you wanted to find an object with a specific type...you'd need Liquid (or similar):

{% assign kitchen_products = products | where: "type", "kitchen" %}

If you needed to do a type specific lookup and only had Mustache on hand, you have to modify the data being sent to the template engine to be Mustache compatible/ready.

So, kitchen_products above might be added directly to the JSON headed to the template engine prior to rendering--meaning you end up with a "modified for viewing" credential data object.

Something like:

{
  "products": [ /* all the products */ ],
  "kitchen_products": [ /* only products with type=kitchen */ ]
}

I'm not sure which is worse/better: a smarter template engine or the requirement for data to be pre-manipulated (or stored...) to meet the demands of the template engine...

msporny commented 1 month ago

We could add a feature that allows you to specify the template language in the render method, with a default of Mustache?