jbboehr / php-mustache

Mustache PHP Extension
MIT License
56 stars 22 forks source link

Question: Is it possible to extract or access comment data? #45

Open renoirb opened 7 years ago

renoirb commented 7 years ago

Hi John,

I'm digging into the code and am currently working on a BFF system and picked Mustache as the templating engine.

That said, I'd like to describe in some way associated assets to a template partial. Imagine a Mustache template with a "front matter". Think like we can do with Markdown document where what's on top until a line with ---.

I have 3 choices in front of me:

  1. Have a file on filesystem just beside the mustache template
  2. Have a "front matter" in the same file, import in PHP Mustache object only what's after the first line with ---
  3. Use Mustache comments.

Looking at coments related tests in libmustache and mustache-spec, I see tests where you deal with getting content OUTSIDE the comments.

Is there a way to get what's inside too?

Maybe I'm stretching too much of what Mustache can do and I should just implement a "front matter".

$string = 'File contents AFTER first line with three dashes';
$tpl = new Mustache($string);

(Pretty much like you're doing with tests/*.phpt, while thinking about it)

Thank you for your advice.

jbboehr commented 7 years ago

Well, you can inspect the AST. See Mustache::parse and MustacheAST::toArray.

jbboehr commented 7 years ago

Or do you mean accessible from the template itself? In that case, you could use a lambda which receives the content of it's block unexecuted. Just note that lambdas are not supported using compile, only render. They're about the same speed anyway IIRC, so nbd.

renoirb commented 7 years ago

(Writing quickly from a phone, I will miss exact references, hopefully this'll be still expand my point)

I'm asking because I did not see --nor have enough experience reading C-- to have a mental model of other possiblilties outside of the tests.

I see that MustacheAST has a method that returns an array, where each members has a type property with an i teger.

I assume that means one integer means comment and I could get that string payload. I guess I could walk the array recursively from the top of the AST, and if I se (and follow) the convention of having a comment first, i'd be able to get that string, pass it to a yaml parser, and so on.

That being said, writing this use-case makes me realize that i'd better leverage opcache (and/and APCu) once I've done the work of mangling with the templates files.

Which leads me to think that if I just walk a folder tree, manipulate files in some way, dfigure out metadata, "hydrate" the mustache template string into a mustache class, serialize all this work for next request.

Using exclusively mustache may be stretching this a bit too far. And would't get benefits because i'll have a "cache warmer" system to have in-memory mustache templates (you classes do have __sleep and looks serializable :+1:

So, maybe I could contribute to tests here and see if I could use comments and MustacheAST as a data source for template metadata.

Or do it as a Service in my BFF microservice layer.

I'll see what I can assemble and publish publicly once I have something more concrete.

Since this is an unofficial PHP extension that isn't documented lfficially, I rely on tests. Anyway, reading tests is always useful along the code to see what's possible.

renoirb commented 7 years ago

For more context, I'm building a PHP microservice that'll serve over HTTP (with appropriate Cache-Control, and so on) representation of a folder of templates.

The template input, would ideally be a directory tree of Mustache files with self contained description.

The container sill have a in-memory (e.g. tmpfs, and/or in RAM) of the metadata I wanna build from the files in that folder.

In the end, it should do things similar to

https://github.com/zalando/tailor/blob/master/examples/fragment-performance/fragment.js

Where I'll have Node.js (and Tailor, or BigPipe, or Fractal, or ...) do HTtP/2 streaming layout assembly from a normalized data source.

jbboehr commented 7 years ago

Since this is an unofficial PHP extension that isn't documented lfficially, I rely on tests. Anyway, reading tests is always useful along the code to see what's possible.

There is some basic documentation in the php stub: https://github.com/jbboehr/php-mustache/blob/master/mustache.php

(you classes do have __sleep and looks serializable

You might want to benchmark serialization vs reparsing the template. Mustache has very simple syntax, it may not be slower to just reparse.

If you need to extract the data separate from execution, I would go with either comments and walking the AST or preprocessing the template.

If you only need to extract the data after execution, then lambdas might be a good choice.

renoirb commented 7 years ago

To double-check, is the ::tokenize() array outcome, for each type property comes from enum Type { ...} in jbboehr/libmustache.

Could it be possible to export to PHP’s MustacheAST class as a constant. For instance, MustacheAST::NODE_COMMENT using same int value as libmustache's Note::TypeComment’s.

And all other Node constant integers to the PHP class?

That would be nice if we could

// Pseudo code, I haven't worked with this, yet.
foreach($tokenized as $node) {
  if ($node['type'] === \MustacheAST::NODE_COMMENT) {
    /* $node['data'] should be Node’s comment contents  */
  }
}

Because, so far, when I look at this data structure shown from the tests, I have no idea what flags, and type should be, and in what context.

jbboehr commented 7 years ago

Yes, it does, and flags comes from the enum below it.