Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 8 commits into from
Mar 23, 2020

Conversation

schveiguy
Copy link
Contributor

@schveiguy schveiguy commented Oct 10, 2019

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
Copy link
Contributor Author

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.

have them parsed and served at runtime. This also makes just about
everything @safe since it's needed at runtime instead of compile time.
barely-changing character array with the new index. Saves a bit of
memory on compile-time.
live mode (and cache mode) on example. Slight tweaks to html string
generator.
@schveiguy schveiguy changed the title DO NOT MERGE Live mode -- allows one to change non-code parts of diet templates and render at runtime Live mode -- allows one to change non-code parts of diet templates and render at runtime Mar 6, 2020
@schveiguy
Copy link
Contributor Author

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

@schveiguy
Copy link
Contributor Author

ping @s-ludwig any thoughts on this?

@schveiguy
Copy link
Contributor Author

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.

source/diet/parser.d Outdated Show resolved Hide resolved
/**
This returns only the NON-code portions of the diet template. The return value is a concatenated string with each string of HTML code separated by a null character. To extract the strings to send into the live renderer, split the string based on a null character.
*/
string getHTMLRawTextOnly(in Document doc, string range_name = dietOutputRangeName, HTMLOutputStyle style = HTMLOutputStyle.compact) @safe
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this and getHTMLLiveMixin should really be public. Is there a use case for using them directly instead of going through DietLiveMode plus the regular API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need them public (including getHTMLMixin which is already public) because I call them in my diet pre-compiler project (I'm going to finalize and release that as soon as this is merged). See here: https://github.com/schveiguy/dietpc/blob/97d0812ddbf03139fcca1f1ede6107093148c2e6/source/app.d#L71-L78

@schveiguy
Copy link
Contributor Author

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
Copy link
Member

Okay, sounds fine to fix in a separate commit!

@s-ludwig s-ludwig merged commit c9697bf into rejectedsoftware:master Mar 23, 2020
@schveiguy
Copy link
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants