rejectedsoftware / diet-ng

Compile-time indentation based, XML structured template system
MIT License
45 stars 24 forks source link

Live mode -- allows one to change non-code parts of diet templates and render at runtime #70

Closed schveiguy closed 4 years ago

schveiguy commented 5 years ago

This is a big commit, and lots of stuff to discuss. This is my attempt at satisfying #53.

The idea is simple -- it's very expensive to recompile an entire website based on diet templates when you just want to move around or alter some HTML in your diet code. Let's say you simply want to add a class to an element. This doesn't change anything but a string literal output by the mixin.

Live mode, instead of outputting a string literal, outputs data from a passed in array. This array is generated by parsing the file at runtime. In order to keep everything sane, the code is ALSO parsed again, and if it doesn't match (save for the line number directives), then an exception is thrown. This is stored behind a cache which checks for file modification dates and only does the expensive parsing if any file or dependency is modified.

The code is a bit overzealous when putting in string outputs, which causes problems in some cases (see hacky issues below). But the nice thing about this is that you can add in html ANYWHERE and it just works. For instance:

- if(x)
  - foo(bar);

can be modified and properly updated like:

-if(x)
  p.someclass Hi diet live!
  - foo(bar);
  1. I had to add a LOT of @safe stuff. Mostly because a lot of things in vibe require @safe but CTFE does not! Most of the files that were changed were simply to add safe tags where appropriate.
  2. The deployed executable REQUIRES access to the views directory. At this time, I look at this as a development feature, so I'm not sure it needs to be "clean" in that respect. It's certainly possible to store the parsed strings that happened at compile time and serve those up if the files aren't there.
  3. There are a couple of "hacky" solutions to problems. First is an else statement, which cannot have a string output between the prior curly brace and the else. Therefore, I suppress the string output in that case (I'm just doing matching, but it should be pretty effective). The second case is a return statement. In this case, the compiler complains about the added string output because the statement is unreachable! So I have a slight hack to skip it on the closing curly brace. I hate the way this is done, but again, this is a development tool, so maybe it's ok to require certain leeway here?
  4. This will not work for type definitions in the template (as you cannot output string table data inside the definition).
  5. This will not work for static functions, as the output range would not be available.

There may be more issues, but this is what came up when I ran it against my pretty decent sized code base (31 diet templates with lots of imports and extends).

Please give a cursory look and let me know your thoughts.

schveiguy commented 5 years ago

ping @s-ludwig this is what I was talking about yesterday. To test, just define a version for DietUseLive in your vibe program, and then you should be able to change non-code portions of your views and it should just work.

schveiguy commented 4 years ago

OK, I think this is ready to be considered for inclusion. Let me know if you need me to squash.

schveiguy commented 4 years ago

ping @s-ludwig any thoughts on this?

schveiguy commented 4 years ago

Another ping @s-ludwig just want to make sure this squeaky wheel gets some grease ;) If there's another direction this needs to go, I'd like to work on it. I'm already using this full-time in my dev cycle and the improvements are huge when doing front-end development.

schveiguy commented 4 years ago

FYI, I found a case where the live mode isn't happy when you change HTML -- attributes with interpolations. If you change the attribute name, the code changes because of how the code is generated. I think I can fix this, but I need to think about it some more. I can also add it later after this is merged.

s-ludwig commented 4 years ago

Okay, sounds fine to fix in a separate commit!

schveiguy commented 4 years ago

Thanks for merging! I'll take a look at the attributes thing today. And work on releasing the diet precompiler. No joke it reduces my build time for my project by something like 75%, and the live editing of stuff like javascript/css classes is a game changer.