-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Qute enhancements #7733
Qute enhancements #7733
Conversation
Forgot @gavinking :) |
83274d2
to
c7d1056
Compare
Now with 100% more correct formatting. |
@FroMage I'll take a look later this week. Anyway, I don't like the fact that the template itself will not declare the type info... |
As I grok this, the declaration of type info in templates are still optional as it is today thus I see this as just a java compatible way of declaring the typeinfo and if you also have typeinfo in the template and they are incompatible I would expect a failure. also this feels like something that would fit nicely with java 14 records. @FroMage remind me again why we use "extend CheckedTemplateInstance" and not a annotation ? |
Because we need to be able to return an instance of this type that can later be checked by the renderer filter to see if it can render it. Although I could inject the supertype based on an annotation. So yeah, I could do this with an annotation too, I'm just too used to RAILS working with subtyping. Do you think it'd be better? |
Oh come on, to be fair, you don't like the type info at all ;) |
I got used to it ;-). I have few questions...
I'll take a look at the implementation and will try to play with the API. It could be that my concerns are just unfounded... |
I like ducktyping from rails too :) so at least having annotation as an option would let me put it on something that is not necessarily a CheckedTemplateInstance but simply just any bean with a proper constructor and bean/field accessors. |
Why would you need to do that? Those constructors and accessors would never be used. The class is just a placeholder, the only kind we could think of to declare a list of template parameters in Java. |
+1
The value is that once you open a template the presence of a type info is a hint that tells you whether you need to care about about types or not.
I have none ;-).
Well, that's a matter of taste and users can choose their own convention. BTW I also think we don't need annotation for this. |
Litteraly the ONLY thing that makes Convention-Over-Configuration work is that users don't choose their own conventions ;) |
@FroMage Yeah, sorry "convention" was a poor choice. It should be "style" or something like that... ;-). I know that you'd like to avoid any name transformations so that it's 1:1 but this would only work for simple template names like |
Sure, we can support that. But I'm not sure we need to. I'd rather tell people to name their files |
Fair enough. From what I see the |
We could make it work outside a jax-rs resource, indeed. |
we use kebab case everywhere else (except java class names); why are we suddenly wanting users to use camel case in file names ? |
The IDE can be enhanced to give content assist and verification when its in the template - just saying. |
Just throwing this out there, but another approach you could use is annotated interfaces. For a templates in
You can then just inject this template controller anywhere you want, and use it in a type safe manner. |
This does replace one injection point per method with one per class, but I like the idea, and it's led me to come up with another idea that does away with injection altogether. I'm pretty sure we can use the @Path("hello")
public class HelloResource {
private native TemplateInstance renderHello(String name);
private native TemplateInstance renderGoodbye(String name);
@GET
public TemplateInstance hello(@QueryParam String name) {
return renderHello(name); // this is type-safe
}
@Path("bye")
@GET
public TemplateInstance goodbye(@QueryParam String name) {
return renderGoodbye(name); // this is type-safe
}
} It's shorter than my constructors proposal and doesn't require injection. I think they can even be |
How does this
I like Stuart's proposal. The "controller" could be used for all templates in your app. We should at least explore this possibility. @FroMage BTW the methods in your |
It works by us replacing the bytecode of the method with a normal method. It's pretty much the only way to declare a method without a body unless it's an abstract class or interface. I think @gunnarmorling showed it to me, IIRC.
Well, the entire Panache APIs are based on using any trick necessary to make UX better, so I disagree :)
Ah yes. |
I disagree. I don't think that Panache users are not encouraged to use |
I wish I could claim ownership, but it wasn't my idea :) Might be an interesting effort though to make it a small JEP to have an official keyword for body-less methods in non-abstract classes? |
It was @gavinking or I that proposed |
New:
Now in theory I've only got documentation to write before this is ready. |
I've added docs. I'm not quite sure on which feet to dance about it, because we have conflicting opinions as to what should be the default style, the one we should start with. ATM, I've updated the docs in this manner:
As a result, I've moved the template extension docs to their own section, and added some text about the convention of grouping them in a single class, or by target. I've also updated the mailer docs to mention the type-safe declaration first @cescoffier. Please @mkouba @stuartwdouglas @emmanuelbernard @cescoffier can you take a look at the docs and let me know if I can improve it: I'm really not sure how to organise it so it's not overly verbose (there's a lot of overlap between the alternative approaches)? |
4cb2354
to
32618a7
Compare
32618a7
to
99e180c
Compare
Rebased due to the |
99e180c
to
4daf855
Compare
4daf855
to
618fc07
Compare
Rebased yet again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added few comments. It looks good (although I'm still against using the native
modifier in the API ;-). I still need to checkout the code and play with the API a little.
extensions/qute/runtime/src/main/java/io/quarkus/qute/api/CheckedTemplate.java
Show resolved
Hide resolved
...s/resteasy-qute/runtime/src/main/java/io/quarkus/resteasy/qute/runtime/ResteasyTemplate.java
Outdated
Show resolved
Hide resolved
618fc07
to
3cfecf3
Compare
All updated and rebased. Let's see what CI says. |
Windows failure doesn't seem related:
@mkouba can you rereview and we get this PR behind us? |
@FroMage could you pls squash the commits? It's not possible to do "squash and merge" in the quarkus repo. |
3cfecf3
to
7917f25
Compare
Done. |
Awesome, thanks! |
@mkouba does this one break something for the users? |
@gsmet AFAIK it should not. Also for qute we don't care that much about compatibility because it's still an experimental feature. |
Finally found the time to follow up on the discussions we had at the last f2f, here's my proposal for improving UX for templating.
ATM, in order to do a non-type-safe template you need this template in
templates/hello.txt
:And this controller:
My proposal for non-type-safe templates is to move the template to
templates/HelloResource/hello.txt
and write the following code:This will default to using a template under
{className}/{methodName}
, and will (this is still missing) take an optional template name as parameter if you want to override it.Type-safe templates
On the other hand (and orthogonally), ATM if you want type-safe templates you need to write this template:
While the invocation (in any style: old or new) is not ever type-safe, letting you do this:
I propose the following variant, guaranteeing type-safety as discussed at the f2f:
The template doesn't have types in there:
And the template declares a constructor for the template instance:
This is implemented in this branch and a little bit tested.
Opinions @mkouba @maxandersen @emmanuelbernard @cescoffier @nicmarti ?