php-mustache icon indicating copy to clipboard operation
php-mustache copied to clipboard

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

Open renoirb opened this issue 7 years ago • 7 comments

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.

renoirb avatar Aug 10 '17 23:08 renoirb

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

jbboehr avatar Aug 10 '17 23:08 jbboehr

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.

jbboehr avatar Aug 11 '17 00:08 jbboehr

(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 avatar Aug 11 '17 01:08 renoirb

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.

renoirb avatar Aug 11 '17 01:08 renoirb

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.

jbboehr avatar Aug 11 '17 02:08 jbboehr

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.

renoirb avatar Aug 11 '17 03:08 renoirb

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

jbboehr avatar Aug 11 '17 21:08 jbboehr